由和与加数进行凑数的遍历算法

最近老婆工作上需要用到根据一堆数据,再根据一个已知的和,找到这个和由哪几个数凑得。

看着老婆花时间慢慢随机选数算,这太低效了。网上搜了下,的确有一个execl的凑数插件,工具有使用次数限制。100次就需要花80大洋买。看着也不是多复杂的东西,C#稍微了解一点点,既然找不到免费的,干脆自己写个桌面版的吧(谁让github没搜到呢o(╥﹏╥)o)。

 

已经附上工具下载链接,源码github链接在文章末尾,需要的自取改代码,不想看实现说明的直接拖到最后。

 

自己对于C#的winform用的很少,只是写工具会用到一点,实现上其实就是遍历。.

例如1,2,11,3,5,41,22,31,54这9个数据,需要凑和为33的数,

(1)首先进行排序, 排完后为1,2,3,5,11,22,31,41,54

(2)进行遍历,遍历根据组合的个数来,首先假设是1个数就能得到33,那一共9个组合,假设和由两个加数构成,那组合就是1,2 /1,3/1,5/...1,54/2,3/2,5/...31,54/41,54   ,数据放到一个listsrc中,依次遍历数据。

(3)每次遍历时,最前面的数据是慢慢移位的例如1,2遍历过了,那2,1是不需要再遍历了。如何实现自己这块还是花了点时间想了下,自己的实现是新建一个list listindex,list的个数代表组合的加数个数。例如先假定2个数,那么listindex的个数是2,listindex[0]代表第一个加数在源数据的位置,   比如list[0] 是3,那么 listsrc[list[0]] = 11。  每次遍历时,listindex[最后一位]+1,如果加到了listsrc的尾数,那么listindex的倒数第二位+1,重置最后一位的值。  每次+1可以类比两个数加法的实现,会产生进位,进位后,不过不是固定的10进制加法,高位进位后,地位需要重新根据高位位置重设定一下低位的值。一直遍历,直到在这个加数个数的值以及遍历完,加数的个数再+1,再继续遍历。

        public bool ToaddIndex(ref List SrcDataindex, ref List srcData)
        {
            int c = 0;
            int lastestIndex = SrcDataindex.Count - 1;  //最后一位的数的index
            SrcDataindex[lastestIndex]++;
            for (int i = lastestIndex; i >= 0; i--)
            {
                if (c > 0)  //产生了进位
                {
                    SrcDataindex[i] += c;  //高位进行+1
                    for (int j = i; j + 1 <= lastestIndex; j ++)
                    {
                        // 低位根据高位的值重新设定
                        SrcDataindex[j+1] = SrcDataindex[j] + 1;  
                    }
                }
                
                // 判断是否最前面的数大于允许偏移的位置
                if(SrcDataindex[0] > srcData.Count - (lastestIndex) + 1)
                {
                    SrcDataindex[0] -= c;
                    Console.WriteLine("is 1 false");
                    return false;
                }
                if (SrcDataindex[i] > srcData.Count - (SrcDataindex.Count - i)) //该位偏移到了允许最大位
                {
                    c = 1;  //产生进位
                }
                else
                {
                    return true;  // 当前数目的加数没有遍历完
                }

            }
            return false;
        }

 实际上因为数据进行了排序,所以如果假设加数有3个数,如果和已经大于了我们想要的数,例如已经遍历到了5,11,22 那么剩下的5,11,31组合就不需要遍历了,因为肯定大于33的,所以直接跳到5,22,31 这样可以节省很多的组合数据,随着数据的变多,节省的时间也是很可观的。

 

源码 github地址  https://github.com/GoGoTryAgain/AutoGetSum

 

因为是基于.net4.0写的,运行需要电脑带有.netFramework 4.0。 

为了防止结果过多卡主,目前限定组合为50个,需要更大的童鞋可以拿源码自己改

最初还设想,有一堆的数,有多个和待凑数,每个数只会用一次,找到合适的组合的,最后因为老婆说用不到,自己偷懒就没写,界面上还保存着,也许哪天会更新呢~

你可能感兴趣的:(winform)