有一个浮点数字序列,例如下:
344
46
567
35.5
4564
456
3457
98
898
878.89
78
978
问题:有一个数值入2345,求上面的数列中选哪几个相加的值最近于该值?
太难了
我想了半天想不通,请高手指点!!

解决方案 »

  1.   

    var
      Form1: TForm1;
      myarr:array[1..12] of double=(344,
    46,
    567,
    35.5,
    4564,
    456,
    3457,
    98,
    898,
    878.89,
    78,
    978);
    implementation{$R *.dfm}
    function Cha(x,y:double):double;
    begin
    if x>=y then result:=x-y else result:=y-x;
    end;function GetNearNum(n:double):double;
    var i:integer;d:double;
    begin
    d:=cha(n,myarr[1]);
    for i:=1 to 12 do
      if cha(n,myarr[i])<d then
         begin
         d:=cha(n,myarr[i]);
         result:=myarr[i];
         end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
    showmessage('最接近值为:'+floattostr(GetNearNum(2345)));
    end;
      

  2.   

    没楼上的那么简单.
    讲个大概的算法:;
    1.从n个数里取m个数组合,m=n直到m=1(要用到递归).
    2.得出组合后,对每个组合相加和目标数求差,对该差值和该组合建立关系
    3.对差值排序得到最小值,通过该最小值找到组合
    重点和难点是得到组合序列.
    可以采用便宜算法,规定差值在某个范围即表示找到.然后每取到一个组合就比较,只要符合就返回退出,这样不用把所有的组合都枚举出来.
    取数组合的算法,可以从m=1...n开始也可以从m=n...1开始.
      

  3.   

    没理解对,我是要在数列里面任意挑,然后加起来,最后那几个数的和最接近(或者说最接近并小于)这个值。“数列”随机,“和”输入,答案是一个加法式,如:数1+数4+数5+数35=sum 最接近 和 and 小于和
      

  4.   

    没楼上的那么简单. 
    讲个大概的算法:; 
    1.从n个数里取m个数组合,m=n直到m=1(要用到递归). 
    2.得出组合后,对每个组合相加和目标数求差,对该差值和该组合建立关系 
    3.对差值排序得到最小值,通过该最小值找到组合 
    重点和难点是得到组合序列. 
    可以采用便宜算法,规定差值在某个范围即表示找到.然后每取到一个组合就比较,只要符合就返回退出,这样不用把所有的组合都枚举出来. 
    取数组合的算法,可以从m=1...n开始也可以从m=n...1开始.不要划一个范围吧,每次记录计算过的差值最小的就可以了。
      

  5.   

      myarr: array[0..11] of double = (
        344,
        46,
        567,
        35.5,
        4564,    456,
        3457,
        98,
        898,
        878.89,
        78,
        978);
    procedure TForm1.btn1Click(Sender: TObject);
    begin
      Combination(myarr, 2345, 10000);//2345是相加逼近值,10000是给出一个最初的相差
    end;function Combination(mArry: array of double; mCon: double; mCha: double): Boolean; //mArry初始数组,
    var
      nilArray: array of double;  procedure fCombination(mLeft, mRight: array of double);
      var
        i, j, k, l: Integer;
        sRight: array of double;
        sLeft: array of double;
        sumTemp: double;
        temStr: string;
      begin
        if Length(mLeft) >= 1 then
        begin
          sumTemp := 0;
          for i := 0 to Length(mLeft) - 1 do
          begin        temStr := temStr + FloatToStr(mLeft[i]) + ',';
            sumTemp := sumTemp + mLeft[i];
          end;
          if Abs(mCon - sumTemp) < mCha then
          begin
            mCha := Abs(mCon - sumTemp);
            Form1.mmo1.Lines.Add(temStr);
            Form1.mmo1.Lines.Add(FloatToStr(mCha));
            Form1.mmo1.Lines.Add(#13);
          end;
        end;    for i := 0 to Length(mRight) - 1 do
        begin
          j := Length(mLeft);
          setlength(sLeft, j + 1);
          for j := 0 to Length(mLeft) - 1 do
            sLeft[j] := mLeft[j];      sLeft[Length(sLeft) - 1] := mRight[i];      setlength(sRight, Length(mRight) - i - 1);      for k := 0 to Length(mRight) - i - 2 do
            sRight[k] := mRight[k + 1];      fCombination(sLeft, sRight);    end;
      end;begin
      result := False;
      try
        fCombination(nilArray, myarr);
      finally  end;
      result := True;
    end;这个递归有点问题,会出现重复值,大家看着帮忙修正吧。
      

  6.   

    procedure TForm1.btn1Click(Sender: TObject);
    begin
      Combination(myarr, 12345, 100000);
    end;function Combination(mArry: array of single; mCon: single; mCha: single): Boolean; {   组合   }
    var
      nilArray: array of single;  procedure fCombination(mLeft, mRight: array of single);
      var
        i, j, k, l: Integer;
        sRight: array of single;
        sLeft: array of single;
        sumTemp: single;
        temStr: string;
      begin
        if Length(mLeft) >= 1 then
        begin
          sumTemp := 0;
          for i := 0 to Length(mLeft) - 1 do
          begin
            temStr := temStr + FloatToStr(mLeft[i]) + ',';
            sumTemp := sumTemp + mLeft[i];
          end;
          if Abs(mCon - sumTemp) < mCha then
          begin
            mCha := Abs(mCon - sumTemp);
            Form1.mmo1.Lines.Add(temStr);
            Form1.mmo1.Lines.Add(FloatToStr(mCha));
            Form1.mmo1.Lines.Add(#13);
          end;
        end;    for i := 0 to Length(mRight) - 1 do
        begin
          j := Length(mLeft);
          setlength(sLeft, j + 1);
          for j := 0 to Length(mLeft) - 1 do
            sLeft[j] := mLeft[j];      sLeft[Length(sLeft) - 1] := mRight[i];      setlength(sRight, Length(mRight) - i - 1);      for k := i to Length(mRight) - 2 do
            sRight[k - i] := mRight[k + 1];      fCombination(sLeft, sRight);    end;
      end;begin
      result := False;
      try
        fCombination(nilArray, myarr);
      finally  end;
      result := True;
    end;
    貌似这样就好了。你们仔细看看吧
      

  7.   


    344,46,98,878.890014648438,978, 
    0.10986328125 小数点位数问题是因为double和single数据类型的问题。real应该就没有这个问题了。878.890014648438就是878.89