C#数学表达式计算(中缀转换后缀)数据结构括号四则运算幂运算取模三⾓函
前⾔:
后缀表达式的计算:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进⾏运算,运算结果进栈,⼀直到最终获得结果。
如何区分负号与减号
如果“-”是第⼀个字符时{
在前⾯加上“0-”
否则{
如果“-”前⼀个字符是数字 “-”是减号
如果“-”前⼀个字符是“^”幂运算符 “-”是负号
否则在前⾯加上“0-”
如-1-(-4^2)
会转换成0-1-(0-4^2)来处理
三⾓函数的运算思路(这⾥⽤的是⾓度制)
输⼊式⼦->转换成⼩写->转换成运算符->计算
如输⼊Sin(30)
转换成⼩写sin(30)
转换成运算符s(30)
运算0.5
代码:
若有不正之处,请多多谅解并欢迎指正。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace计算表达式
{
class Program
{
static void Errorchecking(string s,double d){
double a=Calculation(s);
static void Main(string[] args)
{
/*
容易出错的式⼦:
-
2*(5-2)=-6
-2*(-2)=4
1-(-4^2)=17
1+(-4^-2)=0.9375
1+(-4)^-2=1.0625
*/
Errorchecking("-2 * (5 - 2)",-6);
Errorchecking("-2*(-2)",4);
Errorchecking("-64*(-4)^(-2)",-4);
Errorchecking("1-(-4^2)",17);
Errorchecking("-1+(-4^-2)",-1.0625);
Errorchecking("1+(-4)^-2",1.0625);
Errorchecking("Sin(90)",1);
Errorchecking("1-4*Sin(-1*(-2^5+2))",-1);
Errorchecking("8*sin(-1*(-2^5+2))^2",2);
Errorchecking("cos60*4",2);
Errorchecking("tan(44+1)",1);
Console.WriteLine(string.Format("{0}        计算结果{1}  正确结果{2}  ","tan(90)",Calculation("tan(90)"),"不存在的"));
//Console.WriteLine(Calculation("S(-30)"));
}
public static double Calculation(string str)//函数已封装好⽤到的时候直接调⽤该⽅法ok
{
//Console.WriteLine("中缀表达式:"+str);
str=str.ToLower();//把字符串转换成⼩写
RemoveSpaces(ref str);
StrPreprocessing(ref str);
//Console.WriteLine("中缀表达式:" + str + " 预处理");
List<object> list =ToPostfix(str);//转换成中缀表达式
return CalculationPostfix(list);
}
static double CalculationPostfix(List<object>list)//计算后缀表达式
{
List<double> stacks =new List<double>();
/
/计算后缀表达式
for(int i =0; i < list.Count; i++)
{
if(list[i]is double)
{
stacks.Add((double)list[i]);
}
else
{
string c =(string)list[i];
double aa, bb;
switch(c)
{
case"s":
aa = stacks.Last();
stacks.RemoveAt(stacks.Count -1);
stacks.Add(Math.Sin(aa*Math.PI/180));//这⾥⽤的是⾓度制弧度制的话改成Math.Sin(aa)就⾏了break;
case"c":
aa = stacks.Last();
stacks.RemoveAt(stacks.Count -1);
stacks.Add(Math.Cos(aa * Math.PI /180));
stacks.RemoveAt(stacks.Count -1);
stacks.Add(Math.Tan(aa * Math.PI /180));
break;
default:
bb = stacks.Last();
stacks.RemoveAt(stacks.Count -1);
aa = stacks.Last();
stacks.RemoveAt(stacks.Count -1);
stacks.Add(Operation(aa, bb, c));
break;
}
}
}
return stacks[0];//返回计算结果
}
static List<object>ToPostfix(string infix)//转换成后缀表达式
{
List<object> list =new List<object>();//⼀个集合
List<string> stacks =new List<string>();//⽤来存符号的栈
int len = infix.Length;
int a =0, b =0;
for(int i =0; i < len; i++)
{
/
/该for循环作⽤是把字符串的数字括号运算符区分开来并添加到集合list
string c = infix.Substring(i,1);
if(IsNum(c))
{
b++;
if(i == len -1) list.Add(ParseNum(infix.Substring(a, b)));
}
else
{
string sum = infix.Substring(a, b);
if(sum.Length !=0) list.Add(ParseNum(sum));
error parse newa = i +1;
b =0;
}
switch(c)//符号栈操作
{
case"(": stacks.Add(c);break;
case")":
while(stacks.Count >0)
{
if(stacks.Last()!="(")
{
list.Add(stacks.Last());
stacks.RemoveAt(stacks.Count -1);
}
else
{
stacks.RemoveAt(stacks.Count -1);
break;
}
}
break;
case"+":
case"-":
case"*":
case"/":
case"%":
case"^":
case"s":
{
if(Priority(c, stacks.Last()))
{
list.Add(stacks.Last());
stacks.RemoveAt(stacks.Count -1);
}
else break;
}
stacks.Add(c);
break;
}
}
while(stacks.Count >0)//最后的出栈
{
list.Add(stacks.Last());
stacks.RemoveAt(stacks.Count -1);
}
//Console.Write("后缀表达式:");
//for (int i = 0; i < list.Count; i++) Console.Write(list[i]);
return list;
}
static void StrPreprocessing(ref string infix)//字符串预处理
{
int len = infix.Length;
StringBuilder str =new StringBuilder();
//把sin cos tan分别改为s c t⽅便后⾯的运算
while(infix.IndexOf("sin")>=0|| infix.IndexOf("cos")>=0|| infix.IndexOf("tan")>=0) {
int a = infix.IndexOf("sin");
if(a!=-1) infix=infix.Remove(a+1,2);
a = infix.IndexOf("cos");
if(a !=-1) infix=infix.Remove(a +1,2);
a = infix.IndexOf("tan");
if(a !=-1) infix=infix.Remove(a +1,2);
}
len = infix.Length;
str =new StringBuilder();
for(int i =0; i < len; i++)
{
string c = infix.Substring(i,1);
if(c =="-")
{
if(i ==0)
{
str.Append("0-");
}
else
{
string cc = infix.Substring(i -1,1);
if(IsNum(cc))
{
str.Append(c);
}
else if(cc =="^")
{//避免2^-2=0.25转换成2^0-2=-1
str.Append("_");
}
else
{
str.Append("0-");
}
}
}
else str.Append(c);
}
infix = str.ToString();
}
static void RemoveSpaces(ref string infix)//删除空格
{
int len = infix.Length;
StringBuilder str =new StringBuilder();//blog.csdn/qq_28187979/article/details/76607253 //删除空格
for(int i =0; i < len; i++)
{
string c = infix.Substring(i,1);
if(c ==" ")continue;
str.Append(c);
}
infix = str.ToString();
}
static double Operation(double a,double b,string c)//运算
{
switch(c)
{
case"+":return a + b;
case"-":return a - b;
case"*":return a * b;
case"/":return a / b;
case"%":return a % b;
case"^":return Math.Pow(a, b);
}
throw new Exception();
}
static bool Priority(string a,string b)//优先级判断
{
/
/true为a优低于b
if(Grade(a)<=Grade(b))return true;
return false;
}
static int Grade(string s)//返回该运算符的等级
{
switch(s)
{
case"(":return0;
case"-":
case"+":return1;
case"/":
case"*":
case"%":return2;
case"^":return3;
case"s":
case"c":
case"t":return4;
case")":return5;
}
return-1;
}
static bool IsNum(string s)//传⼊⼀个字符判断该字符是不是数字。负号和点也属于数字 -3.14
{
switch(s)
{
case"_"://预处理之后负号(-)转换成_  减号-不变

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。