Cody Challenge-MathWorks官网面向新手的通关类题库及解答(三)

MATLAB Cody是MathWorks官方的通关形式题库,问题丰富,涉及面广,学习matlab不同阶段的人都可以在其中找到适合自己的题库。其中,Cody Challenge是面向新手的题库,由易到难,帮助大家掌握基础,并感受matlab矩阵化运算的特点。
Cody Challenge-MathWorks官网面向新手的通关类题库及解答(三)

学习matlab两个月,感觉自己并没有用到太多matlab矩阵化运算,偶然发现这个题库,感觉还不错,在此记录分享,若有人看且能指出某题有更好的解法,不胜感激。

以下是部分题目:

您将获得一个包含字符串的单元格数组和一个字符串定界符。 您需要产生一个字符串,该字符串由单元格数组中由定界符分隔的每个字符串组成。

例如,此输入

 in_cell = {'Lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur'};
 delim = ' ';

应该产生以下输出:

 out_str = 'Lorem ipsum dolor sit amet consectetur';

解决

function out_str = cellstr_joiner(in_cell, delim)  
out_str = in_cell{1};  
for k = 2:length(in_cell)  
out_str = [out_str, delim, in_cell{k}];  
end  

如果输入字符串s是类似“ hello”的词,则输出词乘积p是基于对应关系a = 1,b = 2,… z = 26的数字。 尽管输入可能是大小写混合的,但假设输入将是单个单词。 注意,A = a = 1并且B = b = 2。

所以

 s = 'hello'

意味着

 p = 8 * 5 * 12 * 12 * 15 = 86400

解决

function p = word_product(s)  
s = upper(s);  
p = 1;  
for k = 1:length(s)  
p = p*(s(k) - 'A' + 1);  
end 
% upper(' a ') 可以将小写字母转换为大写字母

更优解

p = prod(upper(s) - 'A' + 1);  %prod( )可以实现矩阵元素累乘

给定整数向量v和整数n,返回v的索引(作为升序的行向量),求和为n。如果v中没有求和为n的子集,则返回空矩阵[]。 您可以假设答案总是唯一的。

例子

v = [2, 3, 5];
n = 8;
subset_sum(v, n)
ans =
2 3
%即,以升序返回v中元素之和为n的子集的元素的索引。

解决

function ind = subset_sum(v,n)
b = zeros(2^length(v)-1 , length(v));
c = dec2bin(1:2^length(v)-1);
for i = 1 : 2^length(v)-1
    b(i , :) = str2num(c')';
end
mid = sum(b .* v , 2);
m = b(mid == n , :);
m_m = sort([find(m == 1)' , v(logical(m))'] , 1); 
if isempty(m_m)
    ind = [];
else
    ind = m_m(: , 1)';
end
end
%% 注意sort()函数要声明按列排列,虽然矩阵默认按列排列,但是当输入位行向量时就会按行排列

这题的思路是暴力求解,生成2length(v)-1行(不含全零)的有序二进制矩阵,然后求出2length(v)-1种组合的值,找到值为n的组合,然后排序就好了。

str2num(num2str( 10010 )’)'通过两次装置将数字各位变为矩阵元素是我偶然在论坛看到的,还挺好用的。

给定一个字符串,请删除所有前导和尾随空格(其中空格定义为ASCII 32)。

 Input  a = ' singular value decomposition  '
 Output b is 'singular value decomposition'

解决

function b = removeSpaces(a)
mid = find(a ~= 32);  
b = a(mid(1):mid(length(mid)));  
end

323之类的数是回文率。 其他数字不是124。 但是,当我们将这个数字添加到自己的反向副本中时,会发生什么情况。

124
+ 421
----
545

让我们再试一次。

150
+ 051
----
201

不,那没有用,但是如果我们继续下去怎么办?

201
+ 102
----
303

在那里,再次成为回文。 给定a,返回b = find_palindrome(a),使得b是最终由于重复的反向和相加而产生的回文数。

示例:

Input a = 150
Output b is 303

解决

function b = find_palindrome(a)  
now = a;  
nowstr = num2str(now);  
nowstr = [nowstr zeros(1, 3-length(nowstr))+'0'];  
while ~isempty(find((nowstr ~= nowstr(length(nowstr):-1:1)) == 1, 1))  
nowstr = num2str(str2num(nowstr) + str2num(nowstr(length(nowstr):-1:1)));  
nowstr = [nowstr zeros(1, 3-length(nowstr))+'0'];  
end 
b = str2num(nowstr); 

小巷里有n扇门。 最初它们都关闭了。 您受命要走过小巷n次,并以特定方式打开/关闭这些门:

切换您访问的每个门的状态。 即,如果门是关闭的,则将其打开,如果门是打开的,则将其关闭。

在第i条巷子里,从第i个门开始,参观第i个门。

给定n个门,返回打开的门的列表。

例:

假设n = 3。

第一次旅行时,您将从第一扇门开始,然后切换每扇门。 现在所有三个门都打开了。

在第二次旅行中,您从第二个门开始,然后切换其他每个门。 由于只有三扇门,这意味着您要关闭第二扇门。 现在,门1和3打开了。

在第三次旅行中,您从第三扇门开始,然后每隔三扇门切换一次。 现在只有门1打开。

所以:

 Input  n = 3
 Output y is 1

解决

function y = which_doors_open(n)  
y = zeros(1, n);  
for k = 1:n  
y(k:k:n) = bitxor(y(k:k:n), 1);  
end 
y = find(y == 1);  
end
% bitxor( )进行异或运算

本福德定律指出,前导数字的分布不是随机的。 这可能是因为许多事情都呈对数增长。 从这些向量中提取前导数字。

10 --> 1
13 --> 1
0.3 --> 3
-4 --> 4
-5 --> 5
-0.006 --> 6

输入一个变量

 x = [1 0.3 -2 0.001 -0.0006, 582398, 3020];

输出

 y = [1 3 2 1 6 5 3];
% 没看懂这个定律,不过题目就是要返回首个不为零的数字

给出两个解法

function y = leadingDigit(x)  
curly = @(x, varargin) x{varargin{:}};  
y = num2str(str2double(arrayfun(@(x) curly(regexp(num2str(x), '[1-9]', 'match'), 1), x))) - '0';  

function y = leadingDigit(x)  
y = zeros(1, length(x));  
for k = 1:length(x)  
now = num2str(x(k));  
now = regexp(now, '[1-9]', 'match');  
y(k) = str2num(now{1, 1});  
end 
end

给定货币量,返回以下形式的向量:

[100 50 20 10 5 2 1 0.5 0.25 0.1 0.05 0.01]
例子

 Input a = 257.68
 Output b is [2 1 0 0 1 1 0 1 0 1 1 3]

如果可能,请始终使用较大的钞票/硬币。

解决

function b = makingChange(a)  
table = [100 50 20 10 5 2 1 0.5 0.25 0.1 0.05 0.01];  
b = zeros(1, length(table));  
for k = 1:length(table)  
now = floor(a/table(k)+0.0001);  
b(k) = now  
4000  
; a = a - now*table(k);  
end 
end

将1到n之间的所有整数相加,其中不会出现数字m。 m始终是0到9之间的一位整数。

no_digit_sum(10,1) = 44

因为从总数中排除了1和10

sum(2:9) = 44
解决

function ans = no_digit_sum(n, m)  
y = 1:n;  
sum(y(arrayfun(@(x) all(num2str(x) ~= num2str(m)), y)));  
end

给定一个小写字母或数字作为输入,返回该字母在标准美国QWERTY键盘上出现的行,其位置从该行中最左边的数字或字母开始。

例子:

 Input  key = 'a'
 Output r = 3
        c = 1
 Input  key = '0'
 Output r = 1
        c = 10
 Input  key = 'y'
 Output r = 2
        c = 6

解决

function [r, c] = qwerty_coord(key)  
table = zeros(4, 10);  
table(1,:) = '1234567890';  
table(2,:) = 'qwertyuiop';  
table(3,1:9) = 'asdfghjkl';  
table(4,1:7) = 'zxcvbnm';  
[r , c] = find(table == key);
end
上一篇:MATLAB添加工具箱及无法连接到MathWorks问题


下一篇:matlab 2017b 支持的C编译器