捐赠 | 广告 | 注册 | 发布 | 上传 | 关于我们    
  沪ICP备05001939号 DELPHI盒子 | 盒子论坛 | 盒子文章 | 盒子问答悬赏 | 最新更新 | 论坛检索 | 下载中心 | 高级搜索    
  精品专区 | 繁體中文 | 奖励公告栏 | 直通车账号登陆 | 关闭GOOGLE广告 | 临时留言    
盒子资源分类
全部展开 - 全部合拢
拼凑组合发票的专用小程序
关键字:发票拼凑 凑票 源代码
来 自:原创
平 台:Win2k/XP/NT,Win2003 下载所需:0 火柴
深浅度:初级 完成时间:2009/3/3
发布者:lao1945 发布时间:2009/3/3
编辑器:D2007 语  种:简体中文
分 类:数学 下载浏览:2601/10215
加入到我的收藏
下载错误报错
登陆以后才能下载
 用户名:
 密 码:
自动登陆(30天有效)
图片如果打不开,说明流量不够了,请稍候下载……
人在江湖漂,哪能不凑票!
可手拿一大把,咋搭配才好?
贴多了,亏的慌;贴少了,人家财务不干啊!
所以造了这个工具,专门计算怎么贴浪费的最少。。。

核心算法:
架设有N张票,那么每张票都有用/不用两种可能,即0/1,共有2的N次方种。那么就可以从0到2^N-1,每个数字的2进制码分别就代表了每张票的用或者不用,把所有位分别取出来,乘以票面值,并最终相加,就是一个选择的总额,从中跳出最接近预期值的就ok了。

存在的问题:
1、longint型是32位的,所以最多只能算32张票。
2、运算量太大,所以超过20张以后就很慢了,除非有刚刚好的强行退出。所以还可以选择差额不超过1块钱(当然可以改成其他额度)就退出的模式,以加快速度。如果张数太多,会看起来跟死机一样。。。

哪位大大给改进一下算法啊!主要是解决运算速度的问题,或者有更好的挑选模式?
Google
 
本站原创作品,未经作者许可,严禁任何方式转载;转载作品,如果侵犯了您的权益,请联系我们
龙脉加密锁 15元起 Grid++Report 报表 申请支付@网
 相关文章
没有相关文章
相关评论
共有评论13条 当前显示最后6条评论
lao1945 2009/3/4 11:21:10
另外,改过的代码,在找最接近的时候,往往结果跟选项1是一样的,而不是最接近的值?
lao1945 2009/3/4 11:58:00
sophialung算法的bug确认:
刚重新确认了一下,发现bug是在只用某一张就能满足条件时出现的问题。
如:输入一张1000的,然后输入10、20、30,目标设定为70,就得不到结果(但最接近值可以得到结果)
huhuc 2009/3/5 17:52:37
我也来凑个热闹……
====分币凑整
function GetSumCB(sl:TStringList;target,error:Double):TStringlist;
var
  t: TStringlist;
  procedure GetAdd(tal:Double;R,Left:TStringlist);
  var
    i,cnt:Integer;
    value:Double;
    s,sA:string;
    nR,nLeft:TStringlist;
  begin
    value:=StrToFloat(Left.Names[Left.Count-1]);
    cnt:=StrToInt(Left.ValueFromIndex[Left.Count-1]);
    left.Delete(Left.Count-1);
    tal:=tal-value;
    for i:=0 to cnt do
    begin
      tal:=tal+value;
      if tal>target+error then exit;
      if i>0 then
      begin
        s:=FloatToStr(value)+'*'+IntToStr(i);
        R.Add(s);
        if Abs(tal-target)<=error then
        begin
          if tal=target then          
          sA:='[P]' else sA:='[Dlt='+Format('%.2f', [tal-target])+']';
          Result.Add('Method '+IntToStr(Result.Count+1)+sA+':'#13#10+R.Text);
        end;
      end;
      if left.Count>0 then
      begin
        nR:=TStringlist.Create;
        nLeft:=TStringlist.Create;
        nR.Assign(R);
        nLeft.Assign(Left);
        GetAdd(tal,nR,nLeft);
        nR.Free;
        nLeft.Free;
      end;
      if i>0 then R.Delete(R.Count-1);
    end;
  end;
begin
  Result:=TStringlist.Create;
  t:= TStringlist.Create;
  GetAdd(0,t,sl);
  t.Free;
  if Result.Count=0 then
    Result.Add('None') else Result.Add('Total '+IntToStr(Result.Count));
end;
procedure TForm1.btn1Click(Sender:TObject);
var
  s:TStringList;
begin
  s:=Tstringlist.Create;
  s.Add('3.1=9');
  s.Add('12.7=2');
  s.Add('5=5');
  MessageDlg(GetSumCB(s,68.3,1).Text,mtWarning, [mbOK],0);
end;
lao1945 2009/3/5 18:06:38
看了半天,终于发现了上边的几个小字,知道了您这段是干啥的了。。。
lao1945 2009/3/8 21:56:09
哪位介绍下咋更新上传的程序啊?我改了些bug,但不知道怎样能替换掉原来的?
abclikeabc 2009/3/10 18:19:46
  我记得以前做过一个排考场系统,要求与这个应该类似。因为这个算法可以这样:先采用与要凑的数字最接近的最大面额的票,然后将要凑的面额减去已凑好的数,于是要凑的值就会逐渐递减了。这个算法的好处是出结果非常快,缺点是有时人工可以凑整,计算出来的却可能+1了。可以试一下。
  临时想到哪写到哪了,语言可以不太可理解,望大家原谅。
我要发表评论 查看全部评论
 
  DELPHI盒子版权所有 1999-2023 V4.01 粤ICP备10103342号-1 更新RSS列表