在1至256内任意范围选n个进行不重复的组合,求列出所有的组合形式。e.g1-32   任意选出不重复的6个数字,列出所有的组合。

解决方案 »

  1.   

    procedure TForm1.Button2Click(Sender: TObject);var
    只能一个个列出不知道怎么全列出,聪明人想想吧。 
    x:real;
    begin
     x:=random(256);
     label2.caption:=floattostr(x);
    end;
      

  2.   

    var
      NumStr: String;
      i: Integer;  function GetNum(Str: String; n: integer): TStrings;
      var
        m: integer;
        nStr: String;    procedure Num(i: integer);
        var
          j: integer;
        begin
          Inc(m);
          for j := i + 1 to Length(Str) - n + m do
          begin
            nStr := nStr + Str[j];
            if m = n then
            begin
              Memo1.Lines.Add(nStr);
              nStr:=Copy(nStr, 1, m - 1);
            end
            else
            begin
              Num(j);
            end;
            if j = Length(Str) - n + m then
            begin
              Dec(m);
              nStr := Copy(nStr, 1, m-1);
            end;
            Application.ProcessMessages;
          end;
        end;  begin
        if Length(Str) < n then Exit;
        m := 0;
        Num(0);
      end;begin  for i := 1 to 32 do
        NumStr := NumStr + IntToStr(i);  GetNum(NumStr, 6);end;简单的递归程序,为了直接看到结果,用了TMemo输出结果!用数组不行,结果数量太过庞大,根据需要自己去理解吧不过...要有心理准备,一时半会可完成不了
      

  3.   

    应该不是很困难,算法如下:
    1. 1 ~ 255 随机选取 n 个数
    // 选择数据
    procedure SelectData(var AList: array of Byte; ACount: Integer);
    var
       intNo, intData: Integer;
       arrTable: array [1..255] of Boolean;
    begin
       if (ACount > 1) and (ACount < 256) then
       begin
          // 初始化
          Randomize;
          FillChar(arrTable, Sizeof(arrTable), 0);
          
          intNo := 0;
          while intNo < ACount do
          begin
             intData := Random(255) + 1;
             if not arrTable[intData] then
             begin
                arrTable[intData] := True;
                AList[intNo] := intData;
                Inc(intNo);
             end;
          end;
       end;
    end;
      2. 列出所有的组合type
       PArrayByte = ^TArrayByte;
       TArrayByte = array [0..255] of Byte;
       
    var
       tstrPrintResult: TStringList;
       
    // 初始化
    tstrPrintResult := TStringList.Create;
       
    // 列出项
    procedure ListPrint(AList: array of Byte; ACount: Integer);
    var
       intNo: Integer;
       strItem: String;
    begin
       strItem := IntToStr(AList[0]);
       for intNo := 1 to ACount - 1 do
          strItem := strItem + ', ' + IntToStr(AList[intNo]);
       
       // 加入列表中
       tstrPrintResult.Add(strItem);
    end;// 计算全排列
    procedure ListRank(A, B: array of Byte; ARest, ACount: Integer);
    var
       i: Integer;
       C, D: PArrayByte;
    begin
       if ARest = 0 then
          ListPrint(B, ACount)
       else if (ARest > 0) and (ARest <= ACount) then
       begin
          GetMem(C, ARest);
          GetMem(D, ACount - ARest + 1);
          
          for i := 0 to ARest - 1 do
          begin
             Move(A, C^, i);
             Move(@A[i + 1], @C^[i], ARest - i -1);
             Move(B, @D^[1], ACount - ARest);
             D^[0] := A[i];
             ListRank(C^, D^, ARest - 1, ACount);
          end;
         
          FreeMem(C, ARest);
          FreeMem(D, ACount - ARest + 1);
       end;
    end;// 根据指定项数生成全排列
    procedure BuildList(ACount: Integer);
    var
       A, B: array [0..255] of Byte;
    begin
       if (ACount > 0) and (ACount < 256) then
       begin
          tstrPrintResult.Clear;
          SelectData(A, ACount);
          ListRank(A, B, ACount, ACount);
          
          // 所有排列项都在 tstrPrintResult 中
          // ... ...
       end;
    end;
      

  4.   

    上面的程序我理解错了,你的要求其实就是如:4 选 2 的全组合为:12, 13, 14, 23, 24, 34。这样的算法其实很简单,我简单描述一下:
    procedure ListCombination(A, B: array of Byte; LenA, LenB, Count: Integer);
    begin
       if LenA > Count then
          exit
       else if LenA = Count then
          ListPrint(A, Count)
       else if LenA + LenB = Count then
       begin
          C := A + B;    // 只是为了描述方便, 其实是把A和B数组内容加到C中
          ListPrint(C, Count);
       end
       else if LenA + LenB > Count then
          for i := 1 to LenB do
          begin
             C := A + B[i - 1];
             D := Copy(B, i, LenB - i);
             ListCombination(C, D, LenA + 1, LenB - i, Count);
          end;
    end;
      

  5.   

    我这有一个C语言的算法,你可以拿过去看看,有点类似,它是求N个数的所有子集。
    #include<stdio.h>
    #define N 10
    int NUM=0;
    int find(char *a,int len,char ch)
    {
       int i;
       for(i=0;i<len;i++)
           if(ch==a[i]) return i;
       if(i==len) return 0;
    }
    void print(char *nul,int flag)
    {
      int i;
      printf("{");
      for(i=0;i<flag;i++)
        {
          printf("%c",nul[i]);
          if(i==flag-1) break;
          printf(",");
         }
      printf("}\n");
      NUM++;
    }
    void count(char *nul,char *rnd,int len,int flag)
    {
      int i,j;
      int t;
      if(flag<len)
      {
      if(flag>0) t=find(rnd,len,nul[flag-1]);
      else t=-1;
      for(i=t+1;i<len;i++)
         {
          nul[flag]=rnd[i];
          print(nul,flag+1);
          count(nul,rnd,len,flag+1);
    }
      }
    }
    void main()
    {
      char rnd[N]={'a','b','c','d','e','f','g','h','i','j'};
      char nul[N];
      count(nul,rnd,N,0);
      printf("%d\n",NUM);
      getch();
    }