Matlab 找出所有等于数字阶乘和的数
如何找到所有数字(例如145=1!+4!+5!=1+24+120=145) 哪个等于它们的数字的阶乘之和 我想切掉数字,把这些数字的阶乘加在一起,并将其与原始数字进行比较。若阶乘和等于原始数,则该数为解的上界,必须保持不变。我无法将我的想法编码,我如何才能将其编码?这是真的吗?Matlab 找出所有等于数字阶乘和的数,matlab,Matlab,如何找到所有数字(例如145=1!+4!+5!=1+24+120=145) 哪个等于它们的数字的阶乘之和 我想切掉数字,把这些数字的阶乘加在一起,并将其与原始数字进行比较。若阶乘和等于原始数,则该数为解的上界,必须保持不变。我无法将我的想法编码,我如何才能将其编码?这是真的吗? 感谢下面的代码片段找到了满足此条件的最多1000个数字 numbers = []; for i=1:1000 number_char = int2str(i); sum = 0; for j=1:length
感谢下面的代码片段找到了满足此条件的最多1000个数字
numbers = [];
for i=1:1000
number_char = int2str(i);
sum = 0;
for j=1:length(number_char)
sum = sum+ factorial(eval(number_char(j)));
end
if (sum == i)
numbers(end+1) = i;
end
end
disp(numbers)
这将产生:
1 2 145
注意如果(log10(n)+1)*9!小于n,则没有任何数值满足大于n的条件。我发布此答案的主要原因是,如果没有合适的替代方案,我不能将eval
的使用保留在中
下面是一个小函数,用于检查任何给定(整数)n
:
isFact = @(n) n==sum(factorial(int2str(n)-'0'));
说明:
int2str(n)-“0”
:“切掉数字”求和(阶乘(…)
:“将数字的阶乘相加”n==…
:“将其与原始数字进行比较”maxInt
之间的所有数字:
maxInt = 100000; % just for the example
solution = false(1,maxInt); % preallocating memory
for k = 1:maxInt
solution(k) = isFact(k);
end
find(solution) % find all the TRUE indices
结果是:
ans =
1 2 145 40585
上面的循环写得很简单。如果您希望进一步提高效率和灵活性(如不检查1到
maxInt之间的所有数字,以及检查任何形状的数组),可以将其更改为:
% generating a set of random numbers with no repetitions:
Vec2Check = unique(randi(1000,1,1000)); % you can change that to any array
for k = 1:numel(Vec2Check)
if isFact(Vec2Check(k))
Vec2Check(k) = Vec2Check(k)+0.1;
end
end
solution = Vec2Check(Vec2Check>round(Vec2Check))-0.1
添加0.1作为一个“标志”,用于标记isFact
为其返回true
的数字。然后我们通过比较向量和它的四舍五入顶点来提取它们
您甚至可以使用单线解决方案:
solution = nonzeros(arrayfun(@(n) n.*(n==sum(factorial(int2str(n)-'0'))),Vec2Check))
你说你不能编码是什么意思?这是真的吗?不,这是假的。您可以编写代码为不太熟悉的读者解释:eval函数确实不能总是预编译,因此速度很慢,通常不推荐使用。字符差异技巧简洁高效。我编写这段代码是为了简单,例如避免了函数句柄(@)。同样,如果您关心效率,也应该避免使用[number,i],尽管在这种情况下很少执行该操作。但是,请注意,在另一个答案中为布尔型分配一个向量并不是最优的,因为对于所有的数字,都应该预先分配一个长度约为10000000的向量。我主要关心的不是它的性能,而是它的性能。我同意这里的预分配并不是真正必要的,尽管知道这需要一些关于代码的启发,我更喜欢在简单的使用示例中避免。