博主昨天发了一篇文章,后来用三组数据及乘法验证之后发现原来的程序有非常多的错误,于是博主又花了一个多小时的时间将原来的代码进行了优化,主要改动如下:
1.利用字符数组转字符串再转浮点数的方式向操作数栈添加操作数。
2.改进了原来用‘#’结束式子的方式,利用判断最后操作符栈的栈顶是否是一开始入栈的‘=’来判断程序主体是否结束并促使之后的运算。
3.为防止循环判断条件的‘=’与一开始入栈的‘=’发生冲突,所以将第一个操作符在循环之前入栈,并在主循环中跳过第一个操作符进栈的步骤。
4.实现了小数的四则运算。
原文章链接如下:
http://blog.csdn.net/atomyzd/article/details/50974496
由于博主之前没检验发现这代码只能做两个操作数的运算,多操作数会发生错误,并且类型转换也极易出错。
现将该进代码发布如下:
using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _5._3Timu6
{
class Program
{
static char Precede(char t1, char t2)
{
char f='\0';
switch (t2)
{
case '+':
case '-':if (t1 == '(' || t1 == '=')
f = '<';
else
f = '>';
break;
case '*':
case '/':if (t1 == '*' || t1 == '/' || t1 == '=')
f = '>';
else
f = '<';
break;
case '(':if (t1 == ')')
{
Console.WriteLine("Error");
}
else
f = '<';
break;
case ')':switch (t1)
{
case '(':f = '=';
break;
case '=':Console.WriteLine("Error");
break;
default:
f = '>';
break;
}
break;
case '=':switch (t1)
{
case '(':Console.WriteLine("error");
break;
case '=':f = '=';
break;
default:
f = '>';
break;
}
break;
}
return f;
}
static float Operate(float a, char theta, float b)
{
float c=0;
switch (theta)
{
case '+':c =(float)(a + b);
break;
case '-':c = (float)(a - b);
break;
case '*':c = (float)(a * b);
break;
case '/':c = (float)(a / b);
break;
}
return c;
}
static void Main(string[] args)
{
string suanshi;
float a, b;
int f;
char[] z = new char[6];
char theta;
Console.WriteLine("请输入式子,以=结束");
suanshi = Console.ReadLine();
char[] exp = suanshi.ToCharArray();
Stack op = new Stack();
Stack od = new Stack();
op.Push('=');
for (int k = 0; exp[k]!= '='; k++)
{
if (exp[k] == '+' || exp[k] == '-' || exp[k] == '*' || exp[k] == '/' || exp[k] == '(' || exp[k] == ')' || exp[k] == '=')
{
op.Push(exp[k]);
break;
}
}
int i = 0;
int flag = 0;
while (exp[i]!='='||(char)(op.Peek()) != '=')
{
if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/' || exp[i] == '(' || exp[i] == ')' || exp[i] == '=')
{
flag++;
if (flag == 1)
{
i++;
continue;
}
switch (Precede((char)(op.Peek()), exp[i]))
{
case '<':
op.Push(exp[i]);
i++;
break;
case '=':
op.Pop();
i++;
break;
case '>':
theta = (char)(op.Pop());
b = (float)(od.Pop());
a = (float)(od.Pop());
od.Push(Operate(a, theta, b));
break;
}
}
else if (exp[i] >= '0' && exp[i] <= '9' || exp[i] == '.')
{
f = 0;
char tmp=exp[i];
do
{
z[f] = tmp;
f++;
i++;
tmp=exp[i];
} while (tmp >= '0' && tmp <= '9' || tmp == '.');
z[f] = '\0';
string g = null;
for (int l = 0; z[l] != '\0'; l++)
{
g += z[l];
}
float h = Convert.ToSingle(g);
od.Push(h);
}
}
Console.WriteLine("该式子的值为:" + od.Peek());
}
}
}
由于博主能力有限,该问题肯定还有许多更好的方法,欢迎各位大牛前来指教