using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace SalaryCalculationProject
{
/// <summary>
/// 薪酬集合
/// </summary>
public class SalaryItems
{
private List<string> strOperators; //算术运算符
private List<string> strBaseItem; //存放操作数
private List<string> strItems;
private string salaryItemsTitle; //薪酬项集合的标题
private DateTime SalaryItemsTime; //计算的时间
private string strFormula;
private static readonly char[] spliter = new char[] { ' ' };
private static readonly char[] operatorMatrix = new char[] { '+', '-', '*', '/', '(', ')' };
private static readonly int[] operatorValues = new int[] { 0, 0, 1, 1, -1, -2 };
private string[] spliterMatrix;
private StringBuilder strFormulaSb;
private StringBuilder strSb;
private int i;
private int j;
private int currentOperatorValue;
private string strTmp;
/// <summary>
/// 薪酬项的集合
/// </summary>
public SalaryItems()
{
strOperators = new List<string>();
strItems = new List<string>();
strBaseItem = new List<string>();
strFormulaSb = new StringBuilder();
strSb = new StringBuilder();
//添加基础表和二级表的表项
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="salaryItemsTitle">标题</param>
public SalaryItems(string salaryItemsTitle)
: this()
{
this.salaryItemsTitle = salaryItemsTitle;
}
/// <summary>
/// 接受公式
/// </summary>
/// <param name="strExpression">公式表达式</param>
/// <returns>是否符合表达式</returns>
public bool AcceptExpression(string strExpression)
{
int Rst = 0;
int ILen = 0;
int OLen = 0;
strFormulaSb.Remove(0, strFormulaSb.Length);
strFormula = strExpression;
spliterMatrix = strFormula.Split(spliter);
if (spliterMatrix == null || spliterMatrix.Length == 0)
{
return false;
}
strItems.Clear();
strBaseItem.Clear();
for (i = 0; i < spliterMatrix.Length; ++i)
{
strItems.Add(spliterMatrix[i]);
}
strItems.Insert(0, "(");
strItems.Add(")");
for (i = 0; i < strItems.Count; ++i)
{
if (IsStrOperator(strItems[i], out Rst)) //如果是操作符
{
if (strItems[i] == "(")
{
strOperators.Add(strItems[i]);
currentOperatorValue = Rst;
continue;
}
else if (strItems[i] == ")")
{
while ((OLen = strOperators.Count) > 0 && (currentOperatorValue = GetOperatorValue(strOperators[OLen - 1])) != -1)
{
if (currentOperatorValue > Rst)
{
if ((ILen = strBaseItem.Count) >= 2 && (OLen = strOperators.Count) >= 2)
{
strSb.Remove(0, strSb.Length);
strSb.Append(strBaseItem[ILen - 2]);
strSb.Append(" ");
strSb.Append(strBaseItem[ILen - 1]);
strSb.Append(" ");
strSb.Append(strOperators[OLen - 1]); //后缀表达式
strBaseItem.RemoveAt(ILen - 1); //将操作数和运算符弹出
strBaseItem.RemoveAt(ILen - 2);
strOperators.RemoveAt(OLen - 1);
strBaseItem.Add(strSb.ToString());
}
else
{
return false; // 公式有误
}
}
else
{
return false;
}
}
if (strOperators.Count > 0)
{
strOperators.RemoveAt(strOperators.Count - 1);
}
currentOperatorValue = Rst;
continue;
}
if (currentOperatorValue != -1 && Rst > currentOperatorValue)
{
if (currentOperatorValue == -2) //如果为')'
{
if (strOperators.Count > 0)
{
if (GetOperatorValue(strOperators[(OLen = strOperators.Count) - 1]) >= Rst)
{
if ((ILen = strBaseItem.Count) >= 2)
{
strSb.Remove(0, strSb.Length);
strSb.Append(strBaseItem[ILen - 2]);
strSb.Append(" ");
strSb.Append(strBaseItem[ILen - 1]);
strSb.Append(" ");
strSb.Append(strOperators[OLen - 1]);
strBaseItem.RemoveAt(ILen - 1);
strBaseItem.RemoveAt(ILen - 2);
strOperators.RemoveAt(OLen - 1);
strBaseItem.Add(strSb.ToString());
}
else
{
return false;
}
}
}
}
strOperators.Add(strItems[i]);
if (i + 1 < strItems.Count)
{
if (!IsStrOperator(strItems[i + 1], out Rst))
{
strBaseItem.Add(strItems[i + 1]);
if ((ILen = strBaseItem.Count) > 1 && (OLen = strOperators.Count) > 1)
{
strSb.Remove(0, strSb.Length);
strSb.Append(strBaseItem[ILen - 2]);
strSb.Append(" ");
strSb.Append(strBaseItem[ILen - 1]);
strSb.Append(" ");
strSb.Append(strOperators[OLen - 1]);
strBaseItem.RemoveAt(ILen - 1);
strBaseItem.RemoveAt(ILen - 2);
strOperators.RemoveAt(OLen - 1);
strBaseItem.Add(strSb.ToString());
++i;
}
else
{
return false;
}
}
else if (Rst == -1) //为左括号
{
currentOperatorValue = Rst;
strOperators.Add(strItems[i + 1]);
++i;
}
else
{
return false;
}
}
}
else if (currentOperatorValue != -1 && Rst == currentOperatorValue)
{
if ((ILen = strBaseItem.Count) >= 2 && (OLen = strOperators.Count) >= 2)
{
strSb.Remove(0, strSb.Length);
strSb.Append(strBaseItem[ILen - 2]);
strSb.Append(" ");
strSb.Append(strBaseItem[ILen - 1]);
strSb.Append(" ");
strSb.Append(strOperators[OLen - 1]);
strBaseItem.RemoveAt(ILen - 1);
strBaseItem.RemoveAt(ILen - 2);
strOperators.RemoveAt(OLen - 1);
strBaseItem.Add(strSb.ToString());
}
else
{
return false; // 公式有误
}
strOperators.Add(strItems[i]);
currentOperatorValue = Rst;
}
else if (currentOperatorValue == -1)
{
strOperators.Add(strItems[i]);
currentOperatorValue = Rst;
}
}
else
{
strBaseItem.Add(strItems[i]);
}
}
if (strBaseItem.Count != 1)
{
return false;
}
return true;
}
public string GetSuffixFormula()
{
return strBaseItem[0];
}
/// <summary>
/// 判断是不是操作符
/// </summary>
/// <param name="strItem">公式项</param>
/// <param name="nResult">优先级</param>
/// <returns>是否是操作符</returns>
public bool IsStrOperator(string strItem, out int nResult)
{
if (strItem != null && strItem.Length == 1)
{
for (j = 0; j < operatorMatrix.Length; ++j)
{
if (strItem[0] == operatorMatrix[j])
{
nResult = operatorValues[j];
return true;
}
}
}
nResult = -3;
return false;
}
/// <summary>
/// 返回运算符的优先级
/// </summary>
/// <param name="strOper">运算符</param>
/// <returns>优先级</returns>
private int GetOperatorValue(string strOper)
{
for (j = 0; j < operatorMatrix.Length; ++j)
{
if (strOper.CompareTo(operatorMatrix[j].ToString()) == 0)
{
return operatorValues[j];
}
}
return -3;
}
/// <summary>
/// 判断是不是+-*/
/// </summary>
/// <param name="op">字符串</param>
/// <returns></returns>
public bool IsOperator(string op)
{
bool oop = false;
string[] operator1 = new string[] { "+", "-", "*", "/" };
for (int i = 0; i < operator1.Length; i++)
{
if (operator1[i] == op)
{ oop = true; break; }
}
return oop;
}
}
}
测试程序
class Program
{
static string strFormula = "( A + 3 ) / 4 + ( F + G ) * ( K - A ) / 3 - ( ( J - F ) * H )";
static void Main(string[] args)
{
SalaryItems salaryItems = new SalaryItems("Test");
if (salaryItems.AcceptExpression(strFormula))
{
Console.WriteLine("{0}\n", strFormula);
Console.WriteLine(salaryItems.GetSuffixFormula());
}
else
{
Console.WriteLine("Bad");
}
Console.Read();
}
}