Arrays 在所有字符组合中循环,元素数量不断增加
我想要实现的目标:Arrays 在所有字符组合中循环,元素数量不断增加,arrays,string,matlab,loops,Arrays,String,Matlab,Loops,我想要实现的目标: 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)
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(47)
ans =
O
dec2ASCII(145273)
ans =
0)2
我有一个函数,我想循环所有可能的可打印ascii字符组合,从一个字符开始,然后是两个字符,然后是三个字符,等等
这对我来说很困难的一点是,我希望它能为尽可能多的角色工作(让它过夜)
作为记录:我知道abc实际上是979899
,所以如果更简单的话,数字表示是可以的
这适用于少数字符:
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(47)
ans =
O
dec2ASCII(145273)
ans =
0)2
我可以为n
字符创建一个所有可能组合的列表,然后循环遍历,但当n=4
时,这将需要大量内存。这种方法对于n>5
(至少在普通的台式计算机上)是不可能的
在下面的脚本中,我所做的就是为每个组合增加一个计数器。我真正的功能是做更高级的东西
如果我有无限的记忆,我可以做(感谢):
计数器=0;
某些_函数=@(x)1;
字符数=1;
最长时间=60;
最大字符数=8;
抽搐;
而toc<最大时间和字符数<最大字符数
字符数=字符数+1;
向量=[repmat({'':'~'},1,字符数];
n=努美尔(向量);
梳=单元(1,n);
[combs{end:-1:1}]=ndgrid(向量{end:-1:1});
combs=cat(n+1,combs{:});
梳=重塑(梳,[],n);
对于ii=1:尺寸(梳,1)
计数器=计数器+一些函数(combs(ii,:);
结束
结束
现在,我想在一定的时间内循环使用尽可能多的组合,5秒、10秒、2分钟、30分钟,所以我希望创建一个只受可用时间限制的函数,并且只使用一些合理的内存量
我尝试了(但失败了)更多字符:
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(47)
ans =
O
dec2ASCII(145273)
ans =
0)2
我考虑过使用上述方法之一预先计算两个或三个字母的组合,并且只对最后的字符使用循环。这不需要太多内存,因为它只有一个(相对较小的)数组,加上一个或多个循环的附加字符
我成功地将其扩展到4个字符,但超出这个范围后,我开始陷入麻烦
我试着使用一个只向上计数的迭代器。每次我点击
any(mod(ascii的数字)^1:n,迭代器)==0)
我将第m个字符增加1。因此,最后一个字符只是重复循环!“#…”~
,并且每次它点击tilde,第二个字符递增。每次第二个字符点击tilde,第三个字符递增,以此类推
你对我如何解决这个问题有什么建议吗?看起来你基本上是在用base-26(或base-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 在这里,cap 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开头的字符。但这应该很简单。您的想法还不足以让迭代器向上计数 你需要的是一个从整数到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(47)
ans =
O
dec2ASCII(145273)
ans =
0)2
然后在主脚本中:
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(47)
ans =
O
dec2ASCII(145273)
ans =
0)2
就性能而言,我无法详细说明,因为我不知道您想用某些函数做什么。我唯一能说的是dec2ASCII
的运行时间大约是2*10^(-5)s
旁注:这样的迭代在速度上是非常有限的。有了函数的一些功能
什么都不做,你只需要在大约40分钟内循环4个字符,而5个字符就需要64个小时。也许你想减少你想要通过的东西的数量迭代的函数
不过,这段代码很容易并行化,因此如果您想检查更多的组合,我建议您尝试以并行方式执行此操作。输出字符串中的最大字符数是多少?我不确定我的计算机在几个小时内可以循环多少个组合,但它最好能适用于这么多组合。我想是这样的达到6或7左右的上限,但我不确定……正如下面预言提到的,这是在代币数量的基础上计算的,在你的例子中是95。95^5=7.7378e+09
。这需要一段时间。最多不应该超过几个小时?在我4岁的笔记本电脑上,我可以使用倍频程增加计数器1e7
t时间大约30秒。乘以7e2大约需要6个小时。我想我可以用Matlab和更快的计算机更快地完成这项工作……但我会选择任何可行的方法。=)所有组合,所以如果集合只有abc
,我只需要两个字符,那么我想要:aa、ab、ac、ba、bb、bc