我想要实现的目标:
我有一个函数,我想循环遍历可打印的ascii字符的所有可能组合,从单个字符开始,然后是两个字符,然后是三个等。
让我感到困难的部分是,我希望这能够为尽可能多的角色工作(留在一夜之间)。
对于记录:我知道abc
确实是97 98 99
,因此如果更容易,数字表示就可以了。
这适用于少数字符:
我可以创建n
个字符的所有可能组合的列表,然后循环遍历它,但是在n = 4
时需要大量内存。 n > 5
(至少在普通台式计算机上)这种方法实际上是不可能的。
在下面的脚本中,我所做的就是为每个组合增加一个计数器。我真正的功能做了更高级的东西。
如果我有无限的记忆力,我可以做(感谢Luis Mendo):
counter = 0;
some_function = @(x) 1;
number_of_characters = 1;
max_time = 60;
max_number_of_characters = 8;
tic;
while toc < max_time && number_of_characters < max_number_of_characters
number_of_characters = number_of_characters + 1;
vectors = [repmat({' ':'~'}, 1, number_of_characters)];
n = numel(vectors);
combs = cell(1,n);
[combs{end:-1:1}] = ndgrid(vectors{end:-1:1});
combs = cat(n+1, combs{:});
combs = reshape(combs, [], n);
for ii = 1:size(combs, 1)
counter = counter + some_function(combs(ii, :));
end
end
现在,我希望在一定的时间内,5秒,10秒,2分钟,30分钟内尽可能多地循环组合,所以我希望创建一个功能“s”仅限于可用时间,并且仅使用一些合理的内存量。
尝试为更多角色做出(并失败):
我考虑使用上述方法之一预先计算两个或三个字母的组合,并仅对最后一个字符使用循环。这不需要太多内存,因为它只有一个(相对较小的)数组,加上一个或多个循环的附加字符。
我设法将其扩展到最多4个字符,但除此之外,我开始遇到麻烦。
我试图使用一个向上计数的迭代器。每当我点击any(mod(number_of_ascii .^ 1:n, iterator) == 0)
时,我都会将第m个字符加1。因此,最后一个字符只重复周期!"# ... ~
,每次点击波形时,第二个字符递增。每当第二个字符出现波形时,第三个字符会递增等。
您对我如何解决这个问题有什么建议吗?
答案 0 :(得分:0)
看起来你基本上试图计算基数为26(或者如果你需要CAPS则为52)。该基数中的每个数字都将考虑特定的字符串。例如,
0,1,2,3,4,5,6,7,8,9,A,B,C,d,E,F,G,H,I,J,K,L,M,N ,O,p,10,11,12,...
这里,上限A到P只是用于表示base-26系统的数字符号的符号。以上只是代表这一串字符。
A,B,C,d,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X ,Y,Z,BA,BB,BC,...
然后,你可以这样做:
symbols = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E',...
'F','G','H','I','J','K','L','M','N','O','P']
characters = ['a','b','c','d','e','f','g','h','i','j','k','l',...
'm','n','o','p','q','r','s','t','u','v','w','x','y','z']
count=0;
while(true)
str_base26 = dec2base(count,26)
actual_str = % char-by-char-lookup-of-str26 to chracter string
count=count+1;
end
当然,它不代表以0结尾开头的字符。但那应该很简单。
答案 1 :(得分:0)
你对于只是获得一个向上计数的迭代器的想法并不是很远。
这个想法需要的是从整数到ASCII字符的映射。正如StewieGriffin建议的那样,你只需要在基数95(94个字符加空格)中工作。
为什么是空白:您需要将某些内容映射到0并与之等效。空白是完美的候选人。然后,您只需跳过包含任何空格的字符串。如果您不这样做并直接从!
开始,则您将无法代表!!
或!ab
等字符串。
首先让我们定义一个将(1:1)整数映射到字符串的函数:
function [outstring,toskip]=dec2ASCII(m)
out=[];
while m~=0
out=[mod(m,95) out];
m=(m-out(1))/95;
end
if any(out==0)
toskip=1;
else
toskip=0;
end
outstring=char(out+32);
end
然后在您的主脚本中
counter=1;
some_function = @(x) 1;
max_time = 60;
max_number_of_characters = 8;
currString='';
tic;
while numel(currString)<=max_number_of_characters&&toc<max_time
[currString,toskip]=dec2ASCII(counter);
if ~toskip
some_function(currString);
end
counter=counter+1;
end
dec2ASCII
函数的一些随机输出:
dec2ASCII(47)
ans =
O
dec2ASCII(145273)
ans =
0)2
就性能而言,我无法详细阐述,因为我不知道你想对你的some_function
做些什么。我唯一可以说的是dec2ASCII
的运行时间大约为2*10^(-5) s
旁注:这样的迭代在速度方面会非常有限。如果函数some_function
什么都不做,你就可以在大约40分钟内循环显示4个字符,而5个字符最多需要64个小时。也许你想减少想要通过你迭代的函数传递的东西数量。
但是,此代码很容易并行化,因此如果您想检查更多组合,我建议您尝试以并行方式执行此操作。