DataTable列上多值运算
1、从网上找了个中缀算法(也不知道什么前缀后缀,抱歉),可以对字符串表达式进行运算
2、有些时候还是会用到ASCII码表的
char c = expression[k];//expression为一字符串
int intAsciiCode = (int)c;
3、里面用到了解决多种字符串日期显示格式,转换为日期类型的办法
DateTime time = DateTime.Now;
DateTimeFormatInfo dtfi = new CultureInfo("zh-CN", true).DateTimeFormat;
DateTime.TryParseExact(strTime, new string[] { "yyyyMMdd", "yyyy.M.d", "d-M-yyyy", "d-M月-yyyy", "yyyy-M-d", "yyyy_M_d" }, dtfi, DateTimeStyles.None, out time);//strTime为字符串类型日期
public class DataTableCompute
{
/// <summary>
/// 对DataTabella行上的列根据运算式计算
/// </summary>
/// <param name="dicDecimal">数值类型表达式键值对</param>
/// <param name="dicTime">时间类型表达式键值对</param>
/// <param name="row">DataTable表上的行</param>
public static void ComputeColumns(Dictionary<string, string> dicDecimal, Dictionary<string, string> dicTime, DataRow row)
{
if (dicDecimal != null && dicDecimal.Count > )
{
foreach (KeyValuePair<string, string> kvp in dicDecimal)
{
GetExpressionByType(row, kvp, "decimal");
}
}
if (dicTime != null && dicTime.Count > )
{
foreach (KeyValuePair<string, string> kvp in dicTime)
{
GetExpressionByType(row, kvp, "time");
}
} } private static void GetExpressionByType(DataRow row, KeyValuePair<string, string> kvp, string type)
{
string result = kvp.Key;
string expression = kvp.Value;
string[] cols = expression.Split(new char[] { '(', ')', '+', '-', '*', '/', '\\' },StringSplitOptions.RemoveEmptyEntries);
for (int m = ; m < cols.Length; m++)
{
if (type == "time")
{
DateTime time = DateTime.Now;
if (cols[m].ToLower() != "now")
{
DateTimeFormatInfo dtfi = new CultureInfo("zh-CN", true).DateTimeFormat;
if (!DateTime.TryParseExact(row[cols[m]].ToString(), new string[] { "yyyyMMdd", "yyyy.M.d", "d-M-yyyy", "d-M月-yyyy", "yyyy-M-d", "yyyy_M_d" }, dtfi, DateTimeStyles.None, out time))
{
time = DateTime.Now;
}
}
cols[m] = (time.Year * + time.Month).ToString();
}
else
{
double d = ;
if (double.TryParse(row[cols[m]].ToString(), out d))
{
d = Math.Round(d, );
}
cols[m] = d.ToString();
}
}
StringBuilder newExpression = new StringBuilder();
int n = ;
for (int k = ; k < expression.Length; k++)
{
char c = expression[k];
int intAsciiCode = (int)c;
if (intAsciiCode >= && intAsciiCode <= )
{
newExpression.Append(c.ToString() + " ");
continue;
}
if (c == 'F' || c == 'n')
{
newExpression.Append(cols[n] + " ");
n++;
}
}
string str = newExpression.ToString();
row[result] = CalculateResult(str);
}
private static double CalculateResult(string expre)
{
List<string> temp = getColuExpression(expre);
try
{
while (temp.Count > )
{
for (int i = ; i < temp.Count; i++)
{
double resultTemp = ;
if (temp[i] == "+")
resultTemp = Convert.ToDouble(temp[i - ]) + Convert.ToDouble(temp[i - ]);
else if (temp[i] == "-")
resultTemp = Convert.ToDouble(temp[i - ]) - Convert.ToDouble(temp[i - ]);
else if (temp[i] == "*")
resultTemp = Convert.ToDouble(temp[i - ]) * Convert.ToDouble(temp[i - ]);
else if (temp[i] == "/")
resultTemp = Convert.ToDouble(temp[i - ]) / Convert.ToDouble(temp[i - ]);
else
continue;
temp[i - ] = resultTemp.ToString();
temp.RemoveAt(i);
temp.RemoveAt(i - );
break;
}
}
}
catch (Exception ex)//计算表达式的值错误,导致无法运算
{
temp.Clear();
temp.Add("");
}
return Convert.ToDouble(temp[]);
}
private static List<string> getColuExpression(string exp)
{
System.Text.ASCIIEncoding asc = new System.Text.ASCIIEncoding();
Stack st = new Stack();
string[] temp = exp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
List<string> value = new List<string>(); for (int i = ; i < temp.Length; i++)
{
int num = (int)asc.GetBytes(temp[i])[];
if (num < && num > )
{
if (st.Count > )
{
string operatorStr = st.Peek().ToString();
if (temp[i] == "*" || temp[i] == "/")
{
if (temp[i + ] == "(")
{
st.Push(temp[i]); continue;
}
else
{
if (operatorStr == "(")
{
st.Push(temp[i]);
continue;
}
else if (operatorStr == "*" || operatorStr == "/")
{
value.Add(st.Pop().ToString());
st.Push(temp[i]);
continue;
}
else
{
st.Push(temp[i]);
continue;
}
}
}
else if (temp[i] == "+" || temp[i] == "-")
{
if (operatorStr == "(")
{
st.Push(temp[i]);
continue;
}
else
{
value.Add(st.Pop().ToString());
if (st.Count > && st.Peek().ToString() != "(")
{
value.Add(st.Pop().ToString());
}
st.Push(temp[i]);
continue;
}
}
else if (temp[i] == "(")
{
st.Push(temp[i]);
continue;
}
else
{
if (i + == temp.Length)
{
value.Add(st.Pop().ToString());
st.Pop();
while (st.Count > )
value.Add(st.Pop().ToString());
break;
}
else
{
value.Add(st.Pop().ToString());
st.Pop();
continue;
}
}
}
else
{
st.Push(temp[i]);
continue;
}
}
else if (i + == temp.Length)
{
value.Add(temp[i]);
value.Add(st.Pop().ToString());
while (st.Count > )
value.Add(st.Pop().ToString());
break;
}
else
{
value.Add(temp[i]);
continue;
}
}
return value;
}
}
DataTable列计算类
DataTable列上多值运算的更多相关文章
- 【Excel】SUMIF 或用 筛选器 实现挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加
Background: 挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加.比如挑选下表中,所有带有“MX104”这个字段的值,然后把它的后面total那一列的值相加. Solution: ...
- 获取DataTable某一列的所有值
/// <summary> /// 获取某一列的所有值 /// </summary> /// <typeparam name="T">列数据类型 ...
- VARCHAR列上的索引
一年前,我写了在索引的导航结构里,SQL Server如何存储VARCHAR列.我们都知道,在SQL Server里索引(聚集索引,非聚集索引)的键列有最大900byte的大小限制. 假设现在你想捉弄 ...
- SQL Server如何在变长列上存储索引
这篇文章我想谈下SQL Server如何在变长列上存储索引.首先我们创建一个包含变长列的表,在上面定义主键,即在上面定义了聚集索引,然后往里面插入80000条记录: -- Create a new t ...
- 深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算
布尔代数上的位运算 布尔代数是一个数学知识体系,它在0和1的二进制值上演化而来的. 我们不需要去彻底的了解这个知识体系,但是里面定义了几种二进制的运算,却是我们在平时的编程过程当中也会遇到的.这四种运 ...
- UNIQUEIDENTIFIER列上的统计信息
UNIQUEIDENTIFIER列上的统计信息非常有意思,在它上面有一些很令人讨厌的行为.我们来看下. 问题重现(The repro) 为了向你展示我们刚抱怨的行为,我用下列简单的表定义创建了一个数据 ...
- Oracle中Clob类型处理解析:ORA-01461:仅可以插入LONG列的LONG值赋值
感谢原作者:破剑冰-Oracle中Clob类型处理解析 上一篇分析:ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值 最近为Clob字段在插入数据时发现当字符的字节数(一个半角字符一 ...
- 索引列上的统计 <第一篇>
一.索引在查询优化中的角色 SQL Server的查询优化器是基于开销的优化器.它通过确认选择性.数据的唯一性以及过滤数据(通过WHERE或JOIN子句)所使用的列来决定最佳的数据访问机制.统计与索引 ...
- 关于 Oracle外键列上是否需要索引问题?
外键列上缺少索引会带来两个问题,限制并发性.影响性能.而这两个问题中的任意一个都可能会造成严重性能问题. 无论是Oracle的官方文档,还是在Tom的书中都说明了两种情况下可以忽略外键上的索引.其 ...
随机推荐
- Redmine 项目管理工具----完全攻略
摘要: 此篇博客涉及 安装,插件修改,插件安装,代码显示,中文乱码,SVN配置等内容,几乎覆盖所有redmine基本功能. 本机环境: Redmine 版本: 3.2.0 本机环境: win7 64位 ...
- 基于jsp的文件上传和下载
参考: 一.JavaWeb学习总结(五十)--文件上传和下载 此文极好,不过有几点要注意: 1.直接按照作者的代码极有可能listfile.jsp文件中 <%@taglib prefix=&qu ...
- 获取元素的xpath, 转换xpath为csspath进行jQuery元素获取
获取元素的xpath, 转换xpath为csspath进行jQuery元素获取 博客分类: 编程心得 jQueryCSSHTML var $shadow = new Object(); /** 获取 ...
- Activiti系列:为什么Activiti 5.18 的REST的api总是返回404错误
REST api可以访问了,如下 1.修改db.properties配置文件,让他访问sql server 2.在浏览器中输入如下地址,注意中间有一个service,这点和之前的不一样,在<Ac ...
- 通过数据库方式访问excel 2007及其以后(xlsx)文件的连接字符串
sqlconn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\test3.xls;Extended Properties=&q ...
- [CareerCup] 9.6 Generate Parentheses 生成括号
9.6 Implement an algorithm to print all valid (e.g., properly opened and closed) combinations of n-p ...
- [CareerCup] 13.1 Print Last K Lines 打印最后K行
13.1 Write a method to print the last K lines of an input file using C++. 这道题让我们用C++来打印一个输入文本的最后K行,最 ...
- 《信息安全系统设计基础》第一次实验报告--Linux 基础入门
北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全设计基础 班级:1352 姓名:何伟钦 学号:20135223 成绩: 指导教师:娄嘉鹏 ...
- 细说C#多线程那些事-线程基础
我第一次接触“线程”的概念时,觉得它深奥难懂,看了好多本书,花了很长时间才领悟到它的真谛.现在我就以一个初学者的心态,把我所理解的“多线程”描述给大家.这一次是系列文章,比较完整的展示与线程相关的基本 ...
- Linux 常用工具贴
1. nmon for Linux 用于监控Linux CPU.IO.网络等,可以生产excel格式的报表 http://nmon.sourceforge.net/pmwiki.php?n=Sit ...