定义:
  类型1 2的0次方 = 1
  类型2 2的1次方 = 2
  类型3 2的2次方 = 4
  类型4 2的3次方 = 8
  ……定义一个变量n,当n=1时,该数据类型为:类型1;
          当n=2时,该数据类型为:类型2;
          当n=3时,该数据类型为:类型1和类型2;3=2的0次方+2的1次方
          当n=4时,该数据类型为:类型4;
          当n=5时,该数据类型为:类型1和类型4;5=2的1次方+2的2次方
          ……求一种算法:当给你一个变量值11,通过这个算法得到该数据的类型?
  (11=2的0次方+2的1次方+2的3次方,
  也就是该数据为:类型1和类型2和类型4)
谢谢!

解决方案 »

  1.   


    function GetDataType(Data: DWORD): String;
    var
      i : Integer;
    begin
      Result := '';
      i := 1;
      while Data > 0 do
      begin
        if Data mod 2 = 1 then
        begin
          if Result <> '' then Result := Result + '和';
          Result := Result + '类型' + IntToStr(i);
        end;
        Data := Data div 2;
        inc(i);
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      ShowMessage (GetDataType(11));
    end;
      

  2.   

    不太明白你要干嘛,这完全不需要什么算法啊,两种从数的角度理解是完全一样的。如果是位操作的话,有些经典的算法,推荐Addison Wesley的《Hacker's Delight》一书
    这里可以根据你的问题给你一些演示:type
      TPower2Of = (
        p2o_0,  p2o_1,  p2o_2,  p2o_3,
        p2o_4,  p2o_5,  p2o_6,  p2o_7,
        p2o_8,  p2o_9,  p2o_10, p2o_11,
        p2o_12, p2o_13, p2o_14, p2o_15,
        p2o_16, p2o_17, p2o_18, p2o_19,
        p2o_20, p2o_21, p2o_22, p2o_23,
        p2o_24, p2o_25, p2o_26, p2o_27,
        p2o_28, p2o_29, p2o_30, p2o_31);
      TPower2Sets = set of TPower2Of; { 该set有32个元素,与32-bits的数据对应 }const
      CSTypeSets  : array[TPower2Of]of string = (
        'type 0',  'type 1',  'type 2',  'type 3',
        'type 4',  'type 5',  'type 6',  'type 7',
        'type 8',  'type 9',  'type 10', 'type 11',
        'type 12', 'type 13', 'type 14', 'type 15',
        'type 16', 'type 17', 'type 18', 'type 19',
        'type 20', 'type 21', 'type 22', 'type 23',
        'type 24', 'type 25', 'type 26', 'type 27',
        'type 28', 'type 29', 'type 30', 'type 31'
          );function getFirstBit_Right1(X: Integer): Integer;
    asm { 求从最低位的1所在位 }
      test  eax, not 0  // if(X=0)then Exit;
      jz    @ret
      bsf   eax, eax
      inc   eax
    @ret:
    end;function CountBits_Eq1(X: Integer): Integer;
    begin { 求值为1的位的总数 }
      X := (X and $55555555) + ((X shr 1)and $55555555);
      X := (X and $33333333) + ((X shr 2)and $33333333);
      X := (X and $0f0f0f0f) + ((X shr 4)and $0f0f0f0f);
      X := (X and $00ff00ff) + ((X shr 8)and $00ff00ff);
      Result  := (X and $ffff) + (X shr 16);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      p : TPower2Of;
      p2set : TPower2Sets;
      s : string;
      value, count, it  : Integer;
    begin
      Memo1.Clear;
      value := 65;  // 方式1
      p2set := TPower2Sets(value);  { 将整数转为set,实际上什么都不需要做 }
      for p:=Low(p)to High(p)do
      if(p in p2set)then
        s := Format('%s %s', [s, CSTypeSets[p]]);
      Memo1.Lines.Add(s);  s := '';
      Memo1.Lines.Add(#13#10'-------------'#13#10);  // 方式2
      count := CountBits_Eq1(value);
      Memo1.Lines.Add(Format('Type Count of %d: %d'#13#10, [value, count]));
      while(count>0)do
      begin
        it  := getFirstBit_Right1(value)-1;
        Memo1.Lines.Add(Format('%d: %s', [it, CSTypeSets[TPower2Of(it)]]));
        value := value and (not (1 shl it));  { 将刚得到的bit置0 }
        Dec(count);
      end;  
    end;
      

  3.   

    非常感谢jadeluo,Seamour的帮助。