c#算法-c#中快速从3个DataTable中分别提取一个数据进行相加,获得我想要的值

问题描述

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的中间值,然后相加验证。前提当然是有序的。

时间: 2024-10-31 20:54:18

c#算法-c#中快速从3个DataTable中分别提取一个数据进行相加,获得我想要的值的相关文章

Excel中合并单元格中快速添加序号的方法

  Excel中合并单元格中快速添加序号的方法          如下图所示,需要在数据的A列加入序号: 如果我们利用传统的拖动填充方式添加序号,系统会弹出这样的提示:"此操作要求合并单元格都具有相同大小" 即不能对数据源格式进行修改,又不能用常规方法添加序号,怎么办呢? 要手工逐个的填写吗? 答案是否定的,如果数据量太大的话,我们不可能一个一个去手工添加吧. 这里给大家介绍一个简单的方法. 首先,选中要添加序号的单元格: 编辑栏输入公式: =MAX($A$1:A1)+1 注意关键的一

在Word 2007长文档中快速定位

在Word 2007长文档中快速定位 如果有一篇Word2007文档非常长,比如有几章.几十节甚至长达几十.几百页,要想查看或修改某页的内容时,如果拨动滚轮或使用翻页键一点点向后查找,实在需要相当的眼力和耐心.怎样才能在Word2007的长文档中快速定位呢? 其实有一个非常简单的方法.在Word2007界面的左下角,我们可以看到一个"页码标识"按钮,用X/Y的形式标明当前页面是总页数Y中的第X页.比如现在当前页面是5页中的第1页. 其实,只要点击这个"页码标识"按钮

二叉树深度遍历可视化-利用三种深度遍历算法一步步可视化出树的遍历过程,注意:每一步仅遍历一个节点

问题描述 利用三种深度遍历算法一步步可视化出树的遍历过程,注意:每一步仅遍历一个节点 从空树开始通过输入节点值来构造二叉树: 利用三种深度遍历算法一步步可视化出树的遍历过程,即用图示的方法给出遍历的过程.注意:每一步仅遍历一个节点 遍历的过程中实时打印出相应的遍历序列 补充说明: 可视化/图示的过程实质上就是逐步打印二叉树的过程,可参考"打印二叉树": 鼓励使用其他方法来可视化,例如MFC实现等

控件-在Delphi 7中 如何实现 A,B两台电脑间的数据判断传输

问题描述 在Delphi 7中 如何实现 A,B两台电脑间的数据判断传输 我现在想实现在电脑A中的程序 单击发送之后 电脑B中的程序弹出对话框 点击对话框的收到按钮,电脑A中也要弹出一个对话框 请问代码该怎么写?用哪些控件? 只需要写代码谢谢 解决方案 用indy控件,delphi示例项目文件夹下就有现成可用的程序,稍微改下界面就行了. 解决方案二: 网络通信 搜索 delphi TCP通信 或者 UDP通信 解决方案三: 用winsock来实现通讯 delphi7实现聊天室功能http://d

c++-请问在C++中,结构体数组类型能作为类的数据成员吗?

问题描述 请问在C++中,结构体数组类型能作为类的数据成员吗? 我想让自己构造一个结构体数组来存储记录,结构体数组类型能作为类的数据成员吗? 解决方案 just do it 解决方案二: 可以.实现的时候注意不要出错就可以. 解决方案三: 可以,c++中结构体和类除了默认访问控制符外没什么区别,一个类的对象可以作为另外一个类的成员数据,结构体当然可以 解决方案四: 可以啊,结构体不过是扩展了的int float等等 解决方案五: 当然可以不过我觉得你还不如重新写个class作为专门存储数据 解决

DataTable中的数据筛选

问题描述 DataTable先填充值到DataGridView中,条件是根据DataTable中的日期筛选出某一天的全部数据相加,算出平均值,日期不需要手动输入,日期在DataTable中取值意思就是得到DataGridView中某天数据的平均值,不需要重复查询数据库,数据库有很多日期,一个日期有很多数据 解决方案 解决方案二:linq吧,你可以百度一下,我也不是很清楚解决方案三:varsum=dt.Rows.Cast<DataRows>().Where(dr=>dr["日期&

算法的强大——快速计算一个正二进制整数中包含多少个1

原题:一个正整数,转成二进制后,这个二进制数包含多少个1? 这个问题在网上看过多次,几番思考,也没有什么好的办法.采用最基本的办法,逐位判断,是1的统计加1,最后将统计数返回. 以下是这个思路的VB2008代码,不失一般性,将正整数的范围控制在(1~231-1) Private Function GetCount1OfValue(ByVal Value As Integer) As Integer Dim i As Integer, Count As Integer = 0 For i = 0

在Word2016中快速编辑PDF格式文档

  在Word2016中快速编辑PDF格式文档           首先在资源管理器中找到想要编辑的PDF文件,右击它,从右键菜单中选择"打开方式→Word 2016". Word将自动启动,并弹出一个提示框,大意是转换后的文档与原PDF文档的格式会有些不同. 点击"确定",Word开始打开操作,如果PDF文档很大,这个过程会有些漫长.当PDF文档转换完成后,可能还会在上面出现安全提示,询问你是否确定要编辑. 如果需要编辑,可以点击"启用编辑"按

跨进程实现在Tree中快速定位节点

进程     前些日子写软件时,需要实现一个功能,就是在Tree中快速定位节点,比如注册表编辑器左边的Tree,只要给出Tree中的节点路径(以"\"分隔),就可以快速将树展开,并将当前节点定位到指定的节点.功能的实现并不难,但稍有些麻烦.原因在于,如果是本进程中的Tree,只要发消息就可以了,但如果是另外一个进程中的Tree,就要在那个进程中申请内存,将Tree节点的文字复制到这块内存,然后再把这块内存的数据复制到本进程的一块内存中,才能与指定的节点路径相比较.由于这个功能还有一些可