Q&A

  • 경우의 수 출력...
각문자열에서 한 문자씩만 선택해서 새로운 문자열을 만들어 출력하려합니다.



문자열1="a,s,d,f,g"

문자열2="e,t,g,h,j,i,o"

문자열3="l,h,q"



새로운 문자열 => "a,e,l" 부터 "g,o,q"

전체 경우의 수를 계산해보니 5*7*3=105가지이네요.



단순하게 for문3개를 써서 돌리면 나오겠지만

문자열의 갯수가 유동적(문자열4,5,6...)이고 또 각 문자열의 문자의 갯수가 유동적이라면

for문으로만은 해결할수가 없네요.

다른 방법이 없을까요?



고수님들의 한수 부탁드립니다...

2  COMMENTS
  • Profile
    최용일 2006.02.22 11:08
    안녕하세요. 최용일입니다.

    걍 for문 몇번이면 해결됩니다. 실질적으로 경우의수 만드는데 쓰이는 for문은 딱 2번이네요...

    <!--CodeS-->
    function GetNumberOfCaseCount(const Source: array of string): Integer;
    var
      Index: Integer;
    begin
      Result := Length(Source[0]);
      for Index := 1 to High(Source) do
        Result := Result * Length(Source[Index]);
    end;

    procedure GetNumberOfCaseList(const Source: array of string;
      var List: array of string);
    var
      Index, Count: Integer;
      PermutationCount, PermutationSize: Integer;
      RepeatCount, SourceLength, SourceIndex: Integer;
    begin
      PermutationSize := Length(Source);
      PermutationCount := Length(List);
      for Index := 0 to High(List) do
        SetLength(List[Index], PermutationSize); // for Better Performance...

      RepeatCount := PermutationCount;
      for Index := 0 to High(Source) do
      begin
        SourceLength := Length(Source[Index]);
        RepeatCount := RepeatCount div SourceLength;
        for Count := 0 to PermutationCount - 1 do
        begin
          SourceIndex := ((Count div RepeatCount) mod SourceLength);
          List[Count][Index+1] := Source[Index][SourceIndex+1];
          // Low Performance...
          // List[Count] := List[Count] + Source[Index][SourceIndex+1];
        end;
      end;
    end;


    // Call...
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Index: Integer;
      Str1, Str2, Str3: string;
      StaticArray: array[0..1] of string;
      DynamicArray: array of string;
      PermutationCount: Integer;
      PermutationList: array of string;
    begin
      Memo1.Lines.Clear;

      // Ex 1
      NumberOfCaseCount := GetNumberOfCaseCount(['abc', '123', 'XYZ', '45678']);
      SetLength(NumberOfCaseList, NumberOfCaseCount);
      GetNumberOfCaseList(['abc', '123', 'XYZ', '45678'], NumberOfCaseList);

      for Index := 0 to High(NumberOfCaseList) do
        Memo1.Lines.Add(NumberOfCaseList[Index]);

      // Ex 2
      Str1 := 'abc';
      Str2 := '123';
      Str3 := 'XYZ';
      NumberOfCaseCount := GetNumberOfCaseCount([Str1, Str2, Str3]);
      SetLength(NumberOfCaseList, NumberOfCaseCount);
      GetNumberOfCaseList([Str1, Str2, Str3], NumberOfCaseList);

      for Index := 0 to High(NumberOfCaseList) do
        Memo1.Lines.Add(NumberOfCaseList[Index]);

      // Ex 3
      StaticArray[0] := 'abc';
      StaticArray[1] := '123';
      NumberOfCaseCount := GetNumberOfCaseCount(StaticArray);
      SetLength(NumberOfCaseList, NumberOfCaseCount);
      GetNumberOfCaseList(StaticArray, NumberOfCaseList);

      for Index := 0 to High(NumberOfCaseList) do
        Memo1.Lines.Add(NumberOfCaseList[Index]);

      // Ex 4
      SetLength(DynamicArray, 3);
      DynamicArray[0] := 'abc';
      DynamicArray[1] := '123';
      DynamicArray[2] := 'XYZ';
      NumberOfCaseCount := GetNumberOfCaseCount(DynamicArray);
      SetLength(NumberOfCaseList, NumberOfCaseCount);
      GetNumberOfCaseList(DynamicArray, NumberOfCaseList);

      for Index := 0 to High(NumberOfCaseList) do
        Memo1.Lines.Add(NumberOfCaseList[Index]);
    end;
    <!--CodeE-->

    에러처리나 쉼표처리하는 것은 소스보시고 수정해서 쓰세요...

    ^^ 항상 즐코하세요...

  • Profile
    joint 2006.02.22 22:46
    감사합니다.