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