最近老婆工作上需要用到根据一堆数据,再根据一个已知的和,找到这个和由哪几个数凑得。
看着老婆花时间慢慢随机选数算,这太低效了。网上搜了下,的确有一个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个,需要更大的童鞋可以拿源码自己改。
最初还设想,有一堆的数,有多个和待凑数,每个数只会用一次,找到合适的组合的,最后因为老婆说用不到,自己偷懒就没写,界面上还保存着,也许哪天会更新呢~