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列上多值运算的更多相关文章

  1. 【Excel】SUMIF 或用 筛选器 实现挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加

    Background: 挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加.比如挑选下表中,所有带有“MX104”这个字段的值,然后把它的后面total那一列的值相加. Solution: ...

  2. 获取DataTable某一列的所有值

    /// <summary> /// 获取某一列的所有值 /// </summary> /// <typeparam name="T">列数据类型 ...

  3. VARCHAR列上的索引

    一年前,我写了在索引的导航结构里,SQL Server如何存储VARCHAR列.我们都知道,在SQL Server里索引(聚集索引,非聚集索引)的键列有最大900byte的大小限制. 假设现在你想捉弄 ...

  4. SQL Server如何在变长列上存储索引

    这篇文章我想谈下SQL Server如何在变长列上存储索引.首先我们创建一个包含变长列的表,在上面定义主键,即在上面定义了聚集索引,然后往里面插入80000条记录: -- Create a new t ...

  5. 深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算

    布尔代数上的位运算 布尔代数是一个数学知识体系,它在0和1的二进制值上演化而来的. 我们不需要去彻底的了解这个知识体系,但是里面定义了几种二进制的运算,却是我们在平时的编程过程当中也会遇到的.这四种运 ...

  6. UNIQUEIDENTIFIER列上的统计信息

    UNIQUEIDENTIFIER列上的统计信息非常有意思,在它上面有一些很令人讨厌的行为.我们来看下. 问题重现(The repro) 为了向你展示我们刚抱怨的行为,我用下列简单的表定义创建了一个数据 ...

  7. Oracle中Clob类型处理解析:ORA-01461:仅可以插入LONG列的LONG值赋值

    感谢原作者:破剑冰-Oracle中Clob类型处理解析 上一篇分析:ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值 最近为Clob字段在插入数据时发现当字符的字节数(一个半角字符一 ...

  8. 索引列上的统计 <第一篇>

    一.索引在查询优化中的角色 SQL Server的查询优化器是基于开销的优化器.它通过确认选择性.数据的唯一性以及过滤数据(通过WHERE或JOIN子句)所使用的列来决定最佳的数据访问机制.统计与索引 ...

  9. 关于 Oracle外键列上是否需要索引问题?

    外键列上缺少索引会带来两个问题,限制并发性.影响性能.而这两个问题中的任意一个都可能会造成严重性能问题.   无论是Oracle的官方文档,还是在Tom的书中都说明了两种情况下可以忽略外键上的索引.其 ...

随机推荐

  1. 【转】【Thread】ReaderWriterLock 读写锁

    ReaderWriterLock类 通常来讲,一个类型的实例对于并行的读操作是线程安全的,但是并行地更新操作则不是(并行地读和更新也不是). 这对于资源也是一样的,比如一个文件.当保护类型的实例安全时 ...

  2. 【C#】【邮件】C#发送邮件出现 "指定字符串与主题所要求的形式不符"

    用C#发送邮件的时候有时会出现指定字符串与主题所要求的形式不符的问题. 经过查阅资料发现原因是主题里面你的字符串中有一些特殊字符导致出错.去掉改类字符即可成功. 比如: 我出现的错误原因是主题中有回车 ...

  3. Scrapy

    Scrapy 从Python的Urllib.Urlllib2到scrapy,当然,scrapy的性能且效率是最高的,自己之前也看过一些资料,在此学习总结下. Scrapy介绍 关于scrapy scr ...

  4. C语言 百炼成钢6

    //题目16:输入两个正整数m和n,求其最大公约数和最小公倍数. #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include< ...

  5. SOAP和WSDL的一些必要知识(转)

    原文地址:SOAP和WSDL的一些必要知识 SOAP和WSDL对Web Service.WCF进行深入了解的基础,因此花一些时间去了解一下是很有必要的. 一.SOAP(Simple Object Ac ...

  6. 使用Uploadify实现上传图片生成缩略图例子,实时显示进度条

    不了解Uploadify的,先看看前一篇详细说明 http://www.cnblogs.com/XuebinDing/archive/2012/04/26/2470995.html Uploadify ...

  7. python数字图像处理(8):对比度与亮度调整

    图像亮度与对比度的调整,是放在skimage包的exposure模块里面 1.gamma调整 原理:I=Ig 对原图像的像素,进行幂运算,得到新的像素值.公式中的g就是gamma值. 如果gamma& ...

  8. Listview实现不同类型的布局

    打开各种客户端发现 Listview的布局多种多样,在我以前的认知中listview不是只能放一种item布局嘛,我就震惊了,现在我自己的项目上要用到这种方式那么就去做下 原理是listview 的a ...

  9. AWS S3使用小结

    使用场景一:储存网站的图片,并能被任何人访问 1. 创建一个bucket,名字与需要绑定的域名一致. 例如,根域名是mysite.com,希望把所有图片放在pic.mysite.com下面,访问的时候 ...

  10. Thrift搭建分布式微服务(四)

      第一篇 <连接配置> 第二篇 <连接池> 第三篇 <标准通信> 第四篇 快速暴露接口 之前的文章,我们介绍了如何使用连接池管理Thrift节点,以及使用Thri ...