问题描述
- c#中快速从3个DataTable中分别提取一个数据进行相加,获得我想要的值
-
【背景】:有三个DataTable,每个DataTable大约1.5万条数据。【我的需求描述】:封装一个方法,参数1是我需要的值,参数2是偏差值,参数3、4、5分别是3个DataTable,参数6是一个允许的匹配次数(当然,有好的办法的话,这个参数可以不要),我的意思必须要很快的从3个DataTable中各抽出一行中的一列(也就是分别从3个DataTable中提取一个数),进行相加,3个数加得的总和应该在参数1的值减去偏差值到参数1的值加上偏差值这个范围内,并且我需要快速得到数据,比如2秒内,求最好的解决办法......(提醒:我要的是很快可以得到结果的办法,不是1分钟才能得到结果)
【再次累赘的说一下想完成的功能】:就是说:用户输入一个想得到的值(比如2500),然后用户输入一个允许的偏差值(比如500,正负偏差都可以就是说高于500以内或低于500以内都可以,当然,偏差值是0也可以),3个容器(DataTable或数组或集合都行,这里是由系统提供的固定数据),最终需要使用大家的方法而得到的索引分别代入3个容器中,以便从3个容器中分别取一个值出来,进行相加,使得加数属于该用户想得到的值(此时应在2000-3000范围内,含临界值)即可。
【我的其他要求】:必须是匹配速度非常快(最慢1-2秒)、准确、代码合理。如果用户每次都输入2500的需求值和500的偏差值,最终你们提供的方法所获得的索引不应该每次都一样,当然如果有特殊情况下只能匹配出一个的话是列外的,因为以现有的值来看,一般偏差值不是0的话,按道理是可以匹配出很多条的,但是,只要找到一个匹配,即可以直接返回了。方式不需要有多大的通用性,只要能满足该需求即可.
点击这里下载测试项目,写好了的,有数据直接可以测试 <-----■■■■■■■■■
【一些提示】:有人反映说我的数据有重复,其实告诉你们,里面有45041条,是没有重复的,只是weight有重复而已,我给你们的数据库删除了很多列,其他列是没有重复的。
【想封装的方法如下】:
/// <summary> /// 获取自动匹配 /// </summary> /// <param name="needValue">需要的值</param> /// <param name="deviationValue">允许的偏差值(正负)</param> /// <param name="dtFirst">第一个数据容器:DataTable</param> /// <param name="dtSecond">第二个数据容器:DataTable</param> /// <param name="dtThird">第三个数据容器:DataTable</param> /// <param name="reMatchCount">允许的匹配次数,如果有更好的办法,该参数可以取消掉</param> /// <returns>获得的结果,比如:三个DataTable的索引</returns> public object GetAutoMatch(double needValue, double deviationValue, DataTable dtFirst, DataTable dtSecond, DataTable dtThird, int reMatchCount) { //我们假设此时传来的参数值是: needValue=2500; deviationValue=500; dtFirst=第1个DataTable;//(是固定数据,当然,这里你理解成一个数组也行) dtSecond=第2个DataTable;//(是固定数据,当然,这里你理解成一个数组也行) dtThird=第3个DataTable;//(是固定数据,当然,这里你理解成一个数组也行) reMatchCount=99999;//暂时没用上,如果采用循环方式,可以考虑用上此参数 //只要大家在三个DataTable中分别抽出一个数(也就是说任意三个索引) //加起来的值是我想要的,就匹配成功了 int firstIndex = 0;//这里是关键,就是让大家帮我得到一个firstIndex int secondIndex = 0;//这里是关键,就是让大家帮我得到一个secondIndex int thirdIndex = 0;//这里是关键,就是让大家帮我得到一个thirdIndex //问题就在这里,我需要大家想个办法出来,能在1秒钟内得到3个索引值,最重要的是,把索引值代入后面的if判断必须要满足条件,因为我事先分别知道3个DataTable的最大值和最小值,而且我限制了needValue、deviationValue了,按照我的限制规则加上你们得到的3个索引,匹配的结果是绝对能匹配成功的,如果匹配不出,那么代表你们帮我获取的3个索引值根本不正确。 //按照以上传参的值,如果sum在2000-3000范围,就算匹配成功 double sum = Convert.ToDouble(dtFirst.Rows[firstIndex]["Weight"]) + Convert.ToDouble(dtSecond.Rows[secondIndex]["Weight"]) + Convert.ToDouble(dtThird.Rows[thirdIndex]["Weight"]); //如果找到任意一组匹配的项,就可以return了。 if (sum == needValue //|| sum == needValue - deviationValue//这个不需要,因为后面是<= //|| needValue == sum - deviationValue//这个不需要,因为后面是<= ||sum - needValue <= deviationValue || Math.Abs(needValue - sum) <= deviationValue) { return firstIndex+"|"+secondIndex+"|"+thirdIndex+"#"+sum; } return "-1|-1|-1#0"; //建议大家看完后,给点评论什么的,说下您的建议。 //感谢大家的帮助....................... //手写的代码,有点累,而且有些内容多处累赘了,不好意思... }
解决方案
折半查找三个DataTable的中间值,然后相加验证。前提当然是有序的。