点击目录传送ฅʕ•̫͡•ʔฅ
C#实现字符串解析
类似于数据结构的一元多项式
字符串解析
对老师代码的理解
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//能自己实现很重要。。。回去要加把劲了
namespace HL10._10jiSuanQi
{
public enum Opt //操作的枚举类型
{
Add,
Minus,
Mul,
Div,
None
}
static class StringParse //解析字符串
{
public static int Parse(string str)
{
Stack<int> numStack = new Stack<int>(); //创建一个存放数据的int类型的栈
Stack<Opt> optStack = new Stack<Opt>(); //创建一个存放运算符的枚举类型(Opt)的栈
optStack.Push(Opt.None); //可以理解为将#压入栈中
bool preDigit = false; //判断是否为数字
string curNumStr = string.Empty; //当前数字,就是将字符串里的数抠出来
Opt curOpt = Opt.None;
Opt preOpt = Opt.None; //定义两个枚举类型的变量,一个用来存放前一个运算符,一个存放当前的运算符,都赋初值None
//删除多余的运算符
char[] trimChars = { '+', '-', '*', '/' };
str = str.TrimEnd(trimChars); //从字符串尾删
for (int i = 0; i < str.Length; i++)
{
//如果当前字符是数字
if(char.IsDigit(str[i]) == true)
{
//判断前一个字符是否为数字
if (preDigit == true)
{
curNumStr += str[i]; //字符拼接,比如123
}
else if (preDigit == false)
{
curNumStr = str[i].ToString(); //将字符串里的数字字符抠出来,比如3
}
//当i表示最后一个字符时并且这个字符是数字时,压入栈中
if (i < str.Length - 1)
{
preDigit = true; //让下一个字符知道当前字符(下一个字符的前一个字符)是数字
}
else if (i == str.Length-1)
{
numStack.Push(int.Parse(curNumStr)); //转化为int并压入栈顶,最后再取出计算
break;
}
}
else if (char.IsDigit(str[i]) == false) //不是数字,则当前字符是运算符
{
switch (str[i])
{
case '+':
numStack.Push(int.Parse(curNumStr)); //将当前数字(不一定是字符)转为整型并压入栈中
curOpt = Opt.Add; //当前运算符等于 +
//获取栈顶元素。元素不出栈
preOpt = optStack.Peek(); //取出此时运算符栈中栈顶的运算符
while (preOpt != Opt.None) //只要当前opt栈顶元素不为#(即None)
{
int num1 = numStack.Pop(); //从数字栈中出栈一个元素赋值给num1
int num2 = numStack.Pop(); //同上
//取出符号栈顶的元素,进行计算,把计算结果加到数字栈中。
numStack.Push(Calculate(num2, num1, optStack.Pop()));
preOpt = optStack.Peek(); //获取此时栈顶元素
}
optStack.Push(curOpt); //将当前运算符压入栈顶,因为运算用的是之前存入栈中的运算符
break;
case '-':
numStack.Push(int.Parse(curNumStr));
curOpt = Opt.Minus;
preOpt = optStack.Peek();
while (preOpt != Opt.None) //只要前一个运算符不是*或/,就压入栈中
{
int num1 = numStack.Pop();
int num2 = numStack.Pop();
numStack.Push(Calculate(num2, num1, optStack.Pop()));
preOpt = optStack.Peek();
}
optStack.Push(curOpt);
break;
case '*':
numStack.Push(int.Parse(curNumStr));
curOpt = Opt.Mul;
preOpt = optStack.Peek();
while (preOpt == Opt.Mul || preOpt == Opt.Div)
{
int num1 = numStack.Pop();
int num2 = numStack.Pop(); //上一个数据元素出栈后栈顶元素会变成下一个,不会出现num1与num2相等的情况
numStack.Push(Calculate(num2, num1, optStack.Pop()));
preOpt = optStack.Peek();
}
optStack.Push(curOpt);
break;
case '/':
numStack.Push(int.Parse(curNumStr));
curOpt = Opt.Div;
preOpt = optStack.Peek();
while (preOpt == Opt.Mul || preOpt == Opt.Div)
{
int num1 = numStack.Pop();
int num2 = numStack.Pop();
numStack.Push(Calculate(num2, num1, optStack.Pop()));
preOpt = optStack.Peek();
}
optStack.Push(curOpt);
break;
default:
break;
}
preDigit = false; //让下一个字符知道当前字符是运算符
}
}
while (numStack.Count > 1) //此时若num栈中不为空,将元素取出并相加,然后再入栈
{
int num1 = numStack.Pop();
int num2 = numStack.Pop();
numStack.Push(Calculate(num2, num1, optStack.Pop()));
}
return numStack.Pop(); //返回栈顶元素
}
static int Calculate(int num1, int num2, Opt opt) //静态方法
{
int result = 0;
switch (opt)
{
case Opt.Add:
result = num1 + num2;
break;
case Opt.Minus:
result = num1 - num2;
break;
case Opt.Mul:
result = num1 * num2;
break;
case Opt.Div:
result = num1 / num2;
break;
default:
break;
}
return result;
}
}
class Program
{
static void Main(string[] args)
{
string str;
Console.WriteLine("请输入表达式:");
str = Console.ReadLine();
Console.WriteLine(Parse(str));
Console.ReadKey(); //读取一个字符,防止程序直接跳出
}
}
}
等待自己实现。。。任重道远