Matlab 添加数字直到只剩下两个数字
如何编写要解决的函数: 例如,如果编号为4237,则解决方案Matlab 添加数字直到只剩下两个数字,matlab,Matlab,如何编写要解决的函数: 例如,如果编号为4237,则解决方案 yields 4+2 2+3 3+7 6 5 10 then 6+5 5+10 yields 11 15 1115是答案,而不是行向量[11,15] while或for不应使用 编辑。例2。若初始数字为21020,则最终答案应为77。应该是数字77,而不是向量[7,7]。根据您的评论,您的数字似乎已经是向量形式。所以你很接近。您只缺少了一个循环,例如: x = [4,2,3,7
yields 4+2 2+3 3+7
6 5 10
then 6+5 5+10 yields
11 15
1115
是答案,而不是行向量[11,15]
while
或for
不应使用
编辑。例2。若初始数字为21020,则最终答案应为77。应该是数字77,而不是向量[7,7]。根据您的评论,您的数字似乎已经是向量形式。所以你很接近。您只缺少了一个循环,例如:
x = [4,2,3,7];
while numel(x) > 2
x = x(1:end-1) + x(2:end);
end
结果是:
x =
11 15
无循环的解决方案:
%// input
a = 21020
%// convert number to array of digits
b = num2str(a)-48
%// or directly
b = [2 1 0 2 0]
%// get antidiagonal of pascal matrix
v = diag(fliplr(pascal(numel(b)-1))).'
%// calculation
c = sum([b(1:end-1).*v; b(2:end).*v],2)
%// convert array of digits to number inspired by Luis Mendo
result = str2double(sprintf('%i',c))
%// calculation
for ii = 1:numel(b)-2; b = filter(ones(1,2),1,b); end
%// convert array of digits to number inspired by Luis Mendo
result = str2double(sprintf('%i',b(end-1:end)))
带循环的解决方案:
%// input
a = 21020
%// convert number to array of digits
b = num2str(a)-48
%// or directly
b = [2 1 0 2 0]
%// get antidiagonal of pascal matrix
v = diag(fliplr(pascal(numel(b)-1))).'
%// calculation
c = sum([b(1:end-1).*v; b(2:end).*v],2)
%// convert array of digits to number inspired by Luis Mendo
result = str2double(sprintf('%i',c))
%// calculation
for ii = 1:numel(b)-2; b = filter(ones(1,2),1,b); end
%// convert array of digits to number inspired by Luis Mendo
result = str2double(sprintf('%i',b(end-1:end)))
我想这正是你想要的。它确实使用循环
x = 4237; %// input
x = dec2base(x,10)-'0';
for n = 1:numel(x)-2
x = conv(x,[1 1],'valid');
end
y = str2num(sprintf('%i',x)); %// output
无循环:您可以将[1]
与自身进行多次卷积,然后将其与数字进行一次卷积。[1]
与自身的N次卷积为正,可通过函数轻松计算:
x = 4237; %// input
x = dec2base(x,10)-'0';
N = numel(x)-2;
coeffs = round(exp(gammaln(N+1)-gammaln(1:N+1)-gammaln(N+1:-1:1)));
x = conv(x,coeffs,'valid');
y = str2num(sprintf('%i',x)); %// output
使用Luis Mendo和Marcin的答案,可以使用递归函数实现给定的解决方案,如下所示(不使用for或while):
仅出于学术目的,我们可以看看如何将递归与
conv
结合使用。这是受到路易斯·门多和埃米特方法的启发
换言之:
function [final] = convertNum(x)
function [out] = helper(in)
if numel(in) == 2
out = in;
else
out = helper(conv(in, [1 1], 'valid'));
end
end
digits = dec2base(x, 10) - '0';
final_digits = helper(digits);
final = str2num(sprintf('%i',final_digits));
end
convertNum
是我们用来输入一个数字的函数,输出将是一个两元素向量,它在每一步产生成对元素的总和,直到剩下两个元素为止
我们需要一个helper函数,该函数将接收一个系数数组,其中该数组包含从convertNum
中提取的输入数字的各个数字,该数字存储在x
中。我们首先要做的是把我们的数字x
转换成单独的数字(取自WayWewalk、Luis Mendo和Amit)。接下来,我们调用helper函数来计算成对和
helper函数的工作方式是,如果我们有一个长度不等于2的输入数,我们通过conv
执行成对求和,并使用它递归到helper函数中。一旦输入只包含两个元素,这就是我们从helper函数返回的内容,我们将这两个向量合并成一个数字。这就是我们最终返回给用户的内容
因此,使用x=21020
,我们得到:
final = convertNum(21020)
final =
77
同样地:
final = convertNum(4237)
final =
1115
你做了什么三分式?我试过sums=x(1:end-1)+x(2:end),但它只做初始和。我需要让它运行到剩下的两个数字。它给出了一个错误的答案。例如,如果x=21020,最终答案应该是1115而不是3122。这给出了正确的答案,但没有描述整个情况。唯一剩下的就是把
x
变回一个数字。考虑到x
是两个元素的向量,我们的工作就是将它们连接成一个数字。我们的想法是一样的:-)@LuisMendo是的,但仍然是:你和我的不是21020
的3122
,对不起,对于初始数字21020,最终答案应该是77。这是可行的,但答案应该是77而不是数组[7,7]。如何从数组转换为数字?@thewaywewalk起始输入应为数组。a=[2,1,0,2,0],而不是21020。答案应该是77。我更喜欢conv
而不是filter
,因为它会自动缩短向量+1纠正。我犯了一个错误。如果初始数字为21020,则最终答案应为77。您的conv
解决方案非常完美。为了避免使用循环,我在递归中使用了这个原则。递归在技术上不是一个循环,我写了一个答案。谢谢你允许我用递归来锻炼我的肌肉@rayryeng递归总是很难实现。至少我觉得这比我想象的要困难得多loops@ray顺便说一句,你想试试你的运气吗?:-)