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为字符串类型日期

 

  1  public class DataTableCompute
  2     {
  3         /// <summary>
  4         /// 对DataTabella行上的列根据运算式计算
  5         /// </summary>
  6         /// <param name="dicDecimal">数值类型表达式键值对</param>
  7         /// <param name="dicTime">时间类型表达式键值对</param>
  8         /// <param name="row">DataTable表上的行</param>
  9         public static void ComputeColumns(Dictionary<string, string> dicDecimal, Dictionary<string, string> dicTime, DataRow row)
 10         {
 11             if (dicDecimal != null && dicDecimal.Count > 0)
 12             {
 13                 foreach (KeyValuePair<string, string> kvp in dicDecimal)
 14                 {
 15                     GetExpressionByType(row, kvp, "decimal");
 16                 }
 17             }
 18             if (dicTime != null && dicTime.Count > 0)
 19             {
 20                 foreach (KeyValuePair<string, string> kvp in dicTime)
 21                 {
 22                     GetExpressionByType(row, kvp, "time");
 23                 }
 24             }
 25 
 26         }
 27 
 28         private static void GetExpressionByType(DataRow row, KeyValuePair<string, string> kvp, string type)
 29         {
 30             string result = kvp.Key;
 31             string expression = kvp.Value;
 32             string[] cols = expression.Split(new char[] { '(', ')', '+', '-', '*', '/', '\\' },StringSplitOptions.RemoveEmptyEntries);
 33             for (int m = 0; m < cols.Length; m++)
 34             {
 35                 if (type == "time")
 36                 {
 37                     DateTime time = DateTime.Now;
 38                     if (cols[m].ToLower() != "now")
 39                     {
 40                         DateTimeFormatInfo dtfi = new CultureInfo("zh-CN", true).DateTimeFormat;
 41                         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))
 42                         {
 43                             time = DateTime.Now;
 44                         }
 45                     }
 46                     cols[m] = (time.Year * 12 + time.Month).ToString();
 47                 }
 48                 else
 49                 {
 50                     double d = 0;
 51                     if (double.TryParse(row[cols[m]].ToString(), out d))
 52                     {
 53                         d = Math.Round(d, 3);
 54                     }
 55                     cols[m] = d.ToString();
 56                 }
 57             }
 58             StringBuilder newExpression = new StringBuilder();
 59             int n = 0;
 60             for (int k = 0; k < expression.Length; k++)
 61             {
 62                 char c = expression[k];
 63                 int intAsciiCode = (int)c;
 64                 if (intAsciiCode >= 40 && intAsciiCode <= 47)
 65                 {
 66                     newExpression.Append(c.ToString() + " ");
 67                     continue;
 68                 }
 69                 if (c == 'F' || c == 'n')
 70                 {
 71                     newExpression.Append(cols[n] + " ");
 72                     n++;
 73                 }
 74             }
 75             string str = newExpression.ToString();
 76             row[result] = CalculateResult(str);
 77         }
 78         private static double CalculateResult(string expre)
 79         {
 80             List<string> temp = getColuExpression(expre);
 81             try
 82             {
 83                 while (temp.Count > 1)
 84                 {
 85                     for (int i = 0; i < temp.Count; i++)
 86                     {
 87                         double resultTemp = 0;
 88                         if (temp[i] == "+")
 89                             resultTemp = Convert.ToDouble(temp[i - 2]) + Convert.ToDouble(temp[i - 1]);
 90                         else if (temp[i] == "-")
 91                             resultTemp = Convert.ToDouble(temp[i - 2]) - Convert.ToDouble(temp[i - 1]);
 92                         else if (temp[i] == "*")
 93                             resultTemp = Convert.ToDouble(temp[i - 2]) * Convert.ToDouble(temp[i - 1]);
 94                         else if (temp[i] == "/")
 95                             resultTemp = Convert.ToDouble(temp[i - 2]) / Convert.ToDouble(temp[i - 1]);
 96                         else
 97                             continue;
 98                         temp[i - 2] = resultTemp.ToString();
 99                         temp.RemoveAt(i);
100                         temp.RemoveAt(i - 1);
101                         break;
102                     }
103                 }
104             }
105             catch (Exception ex)//计算表达式的值错误,导致无法运算   
106             {
107                 temp.Clear();
108                 temp.Add("0");
109             }
110             return Convert.ToDouble(temp[0]);
111         }
112         private static List<string> getColuExpression(string exp)
113         {
114             System.Text.ASCIIEncoding asc = new System.Text.ASCIIEncoding();
115             Stack st = new Stack();
116             string[] temp = exp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
117             List<string> value = new List<string>();
118 
119             for (int i = 0; i < temp.Length; i++)
120             {
121                 int num = (int)asc.GetBytes(temp[i])[0];
122                 if (num < 48 && num > 39)
123                 {
124                     if (st.Count > 0)
125                     {
126                         string operatorStr = st.Peek().ToString();
127                         if (temp[i] == "*" || temp[i] == "/")
128                         {
129                             if (temp[i + 1] == "(")
130                             {
131                                 st.Push(temp[i]);
132 
133                                 continue;
134                             }
135                             else
136                             {
137                                 if (operatorStr == "(")
138                                 {
139                                     st.Push(temp[i]);
140                                     continue;
141                                 }
142                                 else if (operatorStr == "*" || operatorStr == "/")
143                                 {
144                                     value.Add(st.Pop().ToString());
145                                     st.Push(temp[i]);
146                                     continue;
147                                 }
148                                 else
149                                 {
150                                     st.Push(temp[i]);
151                                     continue;
152                                 }
153                             }
154                         }
155                         else if (temp[i] == "+" || temp[i] == "-")
156                         {
157                             if (operatorStr == "(")
158                             {
159                                 st.Push(temp[i]);
160                                 continue;
161                             }
162                             else
163                             {
164                                 value.Add(st.Pop().ToString());
165                                 if (st.Count > 0 && st.Peek().ToString() != "(")
166                                 {
167                                     value.Add(st.Pop().ToString());
168                                 }
169                                 st.Push(temp[i]);
170                                 continue;
171                             }
172                         }
173                         else if (temp[i] == "(")
174                         {
175                             st.Push(temp[i]);
176                             continue;
177                         }
178                         else
179                         {
180                             if (i + 1 == temp.Length)
181                             {
182                                 value.Add(st.Pop().ToString());
183                                 st.Pop();
184                                 while (st.Count > 0)
185                                     value.Add(st.Pop().ToString());
186                                 break;
187                             }
188                             else
189                             {
190                                 value.Add(st.Pop().ToString());
191                                 st.Pop();
192                                 continue;
193                             }
194                         }
195                     }
196                     else
197                     {
198                         st.Push(temp[i]);
199                         continue;
200                     }
201                 }
202                 else if (i + 1 == temp.Length)
203                 {
204                     value.Add(temp[i]);
205                     value.Add(st.Pop().ToString());
206                     while (st.Count > 0)
207                         value.Add(st.Pop().ToString());
208                     break;
209                 }
210                 else
211                 {
212                     value.Add(temp[i]);
213                     continue;
214                 }
215             }
216             return value;
217         }
218     }
DataTable列计算类

 

posted @ 2015-06-12 14:20  jiapeng  阅读(898)  评论(0编辑  收藏  举报