例如: 从0-9 a-z(共36个字符)中取出五个,然后把每种组合显示或存为文件
00000    
00001
..
..
..
00009
0000a
0000b
..
..
0000z
-------------------------
00010
00011
..
..
00019
0001a
..
..
0001z

解决方案 »

  1.   


    var
    SourceList: TStringList;      ->把目标字符都加到StringList里
    DestStr: string;
    RandIdx: Integer;
    for Idx:= 0 to 4 do
    begin
      RandIdx:= Random(SourceList.Count - 1);
      DestStr:= DestStr + SourceList(RandIdx);
    end;ShowMessage(DestStr);
    1.可以把目标字符串都写到一个文件里,一个字符一行,然后用StringList.LoadFromFile,以后要加目标字符的话,只要在文件里加就行了;
    2.控制长度的话,只要把4改成5、6等等就行了;
      

  2.   

    dropme:
       你好,谢谢你的解答,但这样的话有二个问题:
       第一:用这个随机取stringList的行,有可能会不完整
       第二:会有重复现象
      

  3.   

    用递归。基本思想就是,从一个集合里取一个出来,然后从集合删除这个元素,再次递归调用,在剩余的函数里再取一个出来. 下面的程序不完全符合楼主的要求,我当初写的用来给公司取名的,排列所有组合。edit1里输入需要的几个字母,然后会把根据这些字母的所有排列组合都列出来
    function plstr(str:string):Tstringlist;
    var
       i,j:integer;
       len:integer;
       cchar:string;
       tempstr:string;
       templist:Tstringlist;
    begin
    result:=Tstringlist.create;len:=length(str);
    if len=1 then
       begin
       result.add(str);
       exit;
       end;for i:=1 to len do
       begin
       cchar:=str[i];   tempstr:=str;
       delete(tempstr,i,1);
       templist:=plstr(tempstr);
       for j:=1 to templist.Count do
          begin
          result.Add(cchar+templist[j-1]);
          end;
       templist.Free;
       end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
       str:string;
       i:integer;
       len:integer;
       strs:Tstringlist;
    begin
    memo1.Clear;str:=edit1.Text;strs:=plstr(str);
    memo1.Lines.Add('=========================');
    memo1.Lines.Add(inttostr(strs.Count));
    memo1.Lines.Add('=========================');for i:=1 to strs.Count do
       begin
       memo1.Lines.Add(strs[i-1]);
       end;strs.Free; 
    end;
      

  4.   

    procedure TForm1.GetStr(bitnum :Integer; Var backList :TStringList);
    const
      allnum :Integer = 36;
      data :Array [0..35] of String = ('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','q','r','s','t',
      'u','v','w','x','y','z');
    var
      tmpList :TStringList;
      i, j :Integer;
    begin
      tmpList := TStringList.Create;
      try
        if (bitnum < 1) then
        begin
        end
        else
        begin
          if (backList.Count = 0) then
          begin
            for i := 0 to allnum-1 do
              tmpList.Add(data[i]);
          end
          else
          begin
            for i := 0 to allnum-1 do
              for j := 0 to backList.Count-1 do
                if (Pos(data[i], backList.Strings[j]) = 0) then
                  tmpList.Add(data[i]+backList.Strings[j]);
          end;
          GetStr(bitnum-1, tmpList);
        end;
        if tmpList.Count > 0 then
        begin
          backList.Clear;
          backList.Text := tmpList.Text;
        end;
        
      finally
        tmpList.Free;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      st:TStringList;
    begin
      st := TStringList.Create;
      GetStr(5, st);
      showmessage(inttostr(st.Count));
      st.SaveToFile('d:\aa.txt');
    end;//排列组合很多,位数多的话要内存足够大
    可以用少量的位数试验
    GetStr(2, st);
      

  5.   

    yqdragon:
      你好,你这个基本是我要的效果,但是GetStr(2, st)的时候,00 11 22..这样二个一样的不会列进去.烦请帮忙再看下
      

  6.   

      procedure GetStr(ANum: Integer; AResultList: TStrings);
      const
        TABLE: array[0..35] of Char = ('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','q','r','s','t',
          'u','v','w','x','y','z');    procedure DoIt(AIndex: Integer; const ALeftStr: string);
        var
          I: Integer;
        begin
          for I := 0 to High(TABLE) do
            if AIndex = ANum - 1 then
              AResultList.Append(ALeftStr + TABLE[I])
            else
              DoIt(AIndex + 1, ALeftStr + TABLE[I])
        end;  begin
        DoIt(0, '')
      end;
      

  7.   

    楼上很多兄弟的答案都不错,这里提供一个不同的思路,楼主的这个想法,让我想起进制的原理
    就用36进制来实现这个,:)//整数转36进制字符,结果放在P-4中,未判断n>=36^5的情况
    procedure IntTo36H(n : integer; P : Pointer);
    asm
      PUSH EDX;
      MOV  ECX , 36
      XOR  EDX , EDX
      DIV  ECX;
      POP  ECX;
      ADD  DL , $30
      CMP  DL , $39
      JNA  @@Number
      ADD  DL , $60-$39
      @@Number:
      MOV  [ECX] , DL;
      CMP  EAX , 0
      JZ   @@Exit;
      MOV  EDX , ECX;
      DEC  EDX;
      CALL IntTo36H;
      @@Exit:
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      i , Len : integer;
      S : AnsiString;
      P : PAnsiChar;
    begin
      Len := 100;
      SetLength(S , 5);
      P := Pointer(S);
      for i:=0 to Len-1 do begin
        PByte(P)^ := $30;
        PDWORD(P+1)^ := $30303030;
        IntTo36H(i , P+4);
        Memo1.Lines.Add(S);
      end;
    end;