问题描述
客户有如此需求,不知道是懒,还是正常。感觉有难度。哈哈请大家帮忙分析一下。先谢谢。需求:财务部经常收到某客户几个合同的汇款,所以他们要人工去一个个找,可能正好等于,或某几个合同的款项。或最接近的某几个合同(有预付款的情况)比如某客户A共有6个合同A001123.4元A002200元A003300元A004350元A005450元A006500元情况一(某数相等)、客户汇款为:200元那么对应合同号:A002情况二(某几个数相加相等)、客户汇款为:423.4元那么对应合同号:A001、A003情况三(某个数或某几个数之和最接近)、找出最接近的参考合同。请大家帮忙分析一下。
解决方案
解决方案二:
帮忙顶,我想到的就是把所有情况列出来了,呵呵
解决方案三:
还是不明白你的需求。
解决方案四:
穷举法,一个一个试
解决方案五:
慢慢分析,这是基础
解决方案六:
引用1楼g_beginner的回复:
帮忙顶,我想到的就是把所有情况列出来了,呵呵
举个列子,可能不恰当。我借了你五次钱,分别是100、200、300、400、500(1)现在我还了你100结果:你拿出借条一看,是第一张(2)现在我还了你1500结果:你拿出借条一看,五次钱全还了(3)我还了你150结果:有可能是100、200(这两个数最接近还款)
解决方案七:
引用2楼hzzduoduo的回复:
还是不明白你的需求。
举个列子,可能不恰当。我借了你五次钱,分别是100、200、300、400、500(1)现在我还了你100结果:你拿出借条一看,是第一张(2)现在我还了你1500结果:你拿出借条一看,五次钱全还了(3)我还了你150结果:有可能是100、200(这两个数最接近还款)
解决方案八:
谢谢大家,帮帮忙啊
解决方案九:
要是只实现一个特例可以,全部实现有点不容易,不过可以分开来做
解决方案十:
可能误解了lz的原意.A:206B:{a:100b:150c:200d:300e:400f:600g:802}输入一个数A找出在指定数组里B中任意几个数值的和的下标.B排序;C取B中间的值:300下标:dA大于C往右进行折半查找,找到刚好等于的就输出下标比最后的值还大就.....组合查找,否则就取当前下标-1和当前下标+1小于一样;不知道是不是这样做o.
解决方案十一:
画个表列出来;就OK了;
解决方案十二:
我觉得,第一种情况循环比较下就行了,第二种情况声明2数组元素相加试试,第三种情况我也求解!!
解决方案十三:
情况一(某数相等)、客户汇款为:200元那么对应合同号:A002@lz:这个简单,直接查找情况二(某几个数相加相等)、客户汇款为:423.4元那么对应合同号:A001、A003情况三(某个数或某几个数之和最接近)、@lz:情况2与3实际上是一个问题,就是误差的设置而已:1.把数组从小到大排序2.找到与第一个数的和小于等于输入的元素下标end3.然后对从0到end取所有元素的组合求和4.找到和里面最接近的就可以了。因为这个组合的个数是不定的,所以必须要列举出所有的情况。但是因为求组合的性能问题,总共的个数每增加一个,计算都是爆炸式增加,所以对数据的组织要分类,查询的时候也要分类来查询。下面的代码是我使用的组合算法,作一点点修改就可以用了。packagetest;/***求N个元素的全排列算法:*1.创建一个大小为N个元素的数组.*2.利用N进制,满N加1的原则,对数组的第0个元素加1,满N了,则下一个元素值加1.*3.检查数组中的元素是否有重复的,如果没有,则是一个排列.*4.直到数组中的元素为0,1,2,...,N-1,则结束,否则继续第2步直到结束.*//***求N个元素中M个元素的组合算法:*1.创建一个大小为N个元素的数组,前M个元素为1,后面的N-M个元素为0*2.从左向右找到10的元素(前一个元素是1,下一个元素是0),交换这两个元素;*把此元素前面的所有1都移动到数组的最前面,此为一个组合,输出.*3.直到前N-M个元素都为0,则结束,否则继续第2步直到结束.*/publicclassCombinatory{publicstaticvoidproduceCombination(Stringstr,intsize){if(size>str.length()){thrownewIllegalArgumentException("Sizeistolarge.");}//创建一个数组,前size个元素全是1int[]digit=newint[str.length()];for(inti=0;i<size;++i){digit[i]=1;}//输出第一组printCombination(str,digit);while(!end(digit,digit.length-size)){for(inti=0;i<digit.length-1;++i){if(digit[i]==1&&digit[i+1]==0){//i上是1,i+1是0,交换inttemp=digit[i];digit[i]=digit[i+1];digit[i+1]=temp;//移动i前面的所有1到最左端intcount=countOf1(digit,i);for(intj=0;j<count;++j){digit[j]=1;}for(intj=count;j<i;++j){digit[j]=0;}printCombination(str,digit);break;}}}}//在下标end前1的个数privatestaticintcountOf1(int[]digit,intend){intcount=0;for(inti=0;i<end;++i){if(digit[i]==1){++count;}}returncount;}//数组中为1的下标对应的字符需要输出privatestaticvoidprintCombination(Stringstr,int[]digit){StringBuffersb=newStringBuffer();for(inti=0;i<digit.length;++i){if(digit[i]==1){sb.append(str.charAt(i));}}System.out.println(sb);}//结束条件:前size个元素都是0privatestaticbooleanend(int[]digit,intsize){intsum=0;for(inti=0;i<size;++i){sum+=digit[i];}returnsum==0?true:false;}publicstaticvoidmain(String[]args){System.out.println("Start");Stringstr="0123456789abcdef";longappStart=System.currentTimeMillis();longelapse=0;for(inti=1;i<=str.length();++i){longstart=System.currentTimeMillis();Combinatory.produceCombination(str,i);elapse=System.currentTimeMillis()-start;System.out.printf("Millis:%d,Seconds:%dn",elapse,elapse/1000);}elapse=System.currentTimeMillis()-appStart;System.out.printf("TotalMillis:%d,Seconds:%dn",elapse,elapse/1000);}}
解决方案十四:
这个问题是时间能够解决的问题,不解释
解决方案十五:
引用13楼linear56的回复:
这个问题是时间能够解决的问题,不解释
我在想一个问题:需求和实现是否是必须的?哈哈但是我作为程序员还是希望能给客户解决问题。
解决方案:
引用14楼koma_wind的回复:
引用13楼linear56的回复:这个问题是时间能够解决的问题,不解释我在想一个问题:需求和实现是否是必须的?哈哈但是我作为程序员还是希望能给客户解决问题。
给钱就有实现,不给钱,开什么玩笑,大家都很忙,*^o^*
解决方案:
这个有点麻烦至少复杂度是组合等级的