public string ToHalfWidth(string str = null) { return(ResultPipe(StringTool.ToHalfWidth(str))); }
/// <summary> /// 算术逆波兰表达式生成(也叫后缀表达式)Reverse Polish Notation /// </summary> /// 首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则 /// 如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。 /// ///参考 https://bbs.csdn.net/topics/200010856 private string BuildingRPN(string originExpression) { originExpression = originExpression.ToLower();//仅支持小写 #region 先把所有支持的函数名替换为单个字符 originExpression = StringTool.ToHalfWidth(originExpression); if (originExpression.IsMatch("[a-z]")) { originExpression = originExpression.ReplaceAllFromPairSet(_supportFunction); } #endregion StringBuilder originStr = new StringBuilder(originExpression); //存入要转成的字符串为stringBuilder Stack operatorStack = new Stack(); //运算符栈 StringBuilder parsingStr = new StringBuilder(); //存放处理后的结果 char nowChar = ' '; //遍历用当前字符 //这一步遍历是挑出有用的字符,去除一些空格或无用字符等干扰因素 for (int i = 0; i < originStr.Length; i++) { nowChar = originStr[i]; //added c==',' for german culture if (char.IsDigit(nowChar) || nowChar == ',')//数字当然要了. { parsingStr.Append(nowChar); } else if (char.IsWhiteSpace(nowChar)) { continue; } else if (char.IsLetter(nowChar))//注意可能会有用户乱输入的字母 还未处理 { parsingStr.Append(nowChar); } else { switch (nowChar)//如果是其它字符...列出的要,没有列出的不要. { case '+': case '-': case '*': case '/': case '%': case '^': case '!': case '(': case ')': case '.': parsingStr.Append(nowChar); break; default: continue; } } } originStr = new StringBuilder(parsingStr.ToString()); #region 对负号进行预转义处理.负号变单目运算符求反. for (int i = 0; i < originStr.Length - 1; i++) { if (originStr[i] == '-' && (i == 0 || originStr[i - 1] == '('))//这里是支持开头为负号的数字,但中间有数字负号必须用括号括起来 { originStr[i] = '!'; } } //字符转义. #endregion #region 将中缀表达式变为后缀表达式. parsingStr = new StringBuilder(); for (int i = 0; i < originStr.Length; i++) { if (char.IsDigit(originStr[i]) || originStr[i] == '.')//如果是数值. { parsingStr.Append(originStr[i]); //加入后缀式 } else if (originStr[i] == '+' || originStr[i] == '-' || originStr[i] == '*' || originStr[i] == '/' || originStr[i] == '%' || originStr[i] == '^' || originStr[i] == '!' || isInSupportedArray(originStr[i])) { #region 运算符处理 主要按照优先级刷新运算顺序 while (operatorStack.Count > 0) //栈不为空时 { nowChar = (char)operatorStack.Pop(); //将栈中的操作符弹出. if (nowChar == '(') //如果发现左括号.停. { operatorStack.Push(nowChar); //将弹出的左括号压回.因为还有右括号要和它匹配. break; //中断. } else { if (Power(nowChar) < Power(originStr[i]))//如果优先级比上次的高,则压栈. { operatorStack.Push(nowChar); break; } else { parsingStr.Append(' '); parsingStr.Append(nowChar); } //如果不是左括号,那么将操作符加入后缀式中. } } operatorStack.Push(originStr[i]); //把新操作符入栈. parsingStr.Append(' '); #endregion } else if (originStr[i] == '(')//基本优先级提升 { operatorStack.Push('('); parsingStr.Append(' '); } else if (originStr[i] == ')') //基本优先级下调 { while (operatorStack.Count > 0) //栈不为空时 { nowChar = (char)operatorStack.Pop(); //pop Operator if (nowChar != '(') { parsingStr.Append(' '); parsingStr.Append(nowChar); //加入空格主要是为了防止不相干的数据相临产生解析错误. parsingStr.Append(' '); } else { break; } } } else { parsingStr.Append(originStr[i]); } } while (operatorStack.Count > 0)//这是最后一个弹栈啦. { parsingStr.Append(' '); parsingStr.Append(operatorStack.Pop()); } #endregion parsingStr.Append(' '); return(FormatSpace(parsingStr.ToString())); //在这里进行一次表达式格式化.这里就是后缀式了. }