我的C#编的四则运算在编译好运行时,光是+,-,*,/ 全部都能实现,但是一用括号就要出错,错误如下:
我把代码发出来(一共是5个类,都是一个命名空间的),大家给我看看,可以复制下去改下哦,尽快改好啊、、拜托了、、using System;
using System.Collections ;namespace HomeWork
{
/// <summary>
/// Calculate 的摘要说明。
/// 计算实现主类
/// </summary>
public class Calculate
{
/// <summary>
/// 算术符栈
/// </summary>
private ArrayList HList;
/// <summary>
/// 数值栈
/// </summary>
public ArrayList Vlist;
/// <summary>
/// 读算试工具
/// </summary>
private CalUtility cu;
/// <summary>
/// 运算操作器工厂
/// </summary>
private OperFactory of;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="str"> 算式 </param>
public Calculate(string str)
{
HList = new ArrayList();
Vlist = new ArrayList();
of = new OperFactory();
cu = new CalUtility(str);
}
/// <summary>
/// 开始计算
/// </summary> public object DoCal()
{
string strTmp=cu.getItem();
while(true)
{
if(cu.IsNum(strTmp))
{
///如果是数值,则写入数据栈
Vlist.Add(strTmp);
}
else
{
///数值
Cal(strTmp);
}
if(strTmp.Equals(""))
break;
strTmp=cu.getItem();
}
return Vlist[0];
} /// <summary>
/// 计算
/// </summary>
/// <param name="str"> 计算符 </param>
private void Cal(string str)
{
if(str.Equals("")&&this.HList.Count==0)
return;
if(this.HList.Count>0)
{
if(this.HList[this.HList.Count-1].ToString().Equals("(")|| str.Equals(")"))
{
this.HList.RemoveAt(this.HList.Count-1);
if(this.HList.Count>0)
{
str=this.HList[this.HList.Count-1].ToString();
this.HList.RemoveAt(this.HList.Count-1);
this.Cal(str);
}
return ;
}
if(cu.Compare(this.HList[this.HList.Count-1].ToString(),str))
{
IOper p=of.CreateOper(this.HList[this.HList.Count-1].ToString());
if(p!=null)
{
this.Vlist[this.Vlist.Count-2]=p.Oper(this.Vlist[this.Vlist.Count-2],this.Vlist[this.Vlist.Count-1]);
this.HList.RemoveAt(this.HList.Count-1);
this.Vlist.RemoveAt(this.Vlist.Count-1);
this.Cal(str);
}
return;
}
if(!str.Equals(""))
{
this.HList.Add(str);
}
}
else
{
if(!str.Equals(""))
{
this.HList.Add(str);
}
}
}
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
// Console.WriteLine("请输入表达式:");
string str=Console.ReadLine();
Calculate obj=new Calculate(str);
obj.DoCal();
//obj.Cal(str);
Console.WriteLine(obj.Vlist[0]);
}
}
}
using System;namespace HomeWork
{
public class CalUtility
{
System.Text.StringBuilder StrB;
private int iCurr=0;
private int iCount=0; public CalUtility(string calStr)
{
StrB=new System.Text.StringBuilder(calStr.Trim());
iCount=System.Text.Encoding.Default.GetByteCount(calStr.Trim());
}
public string getItem()
{
if(iCurr==iCount)
{
return "";
}
char ChTmp=StrB[iCurr];
bool b=IsNum(ChTmp);
if(!b)
{
iCurr++;
return ChTmp.ToString();
}
string strTmp="";
while (IsNum(ChTmp)==b && iCurr<iCount)
{
ChTmp=StrB[iCurr];
if (IsNum(ChTmp) == b)
{
strTmp += ChTmp;
}
else
{
break;
}
iCurr++;
}
return strTmp;
}
public bool IsNum(char c)
{
if((c>='0' && c<='9') || c=='.')
{
return true;
}
else
{
return false;
}
}
public bool IsNum(string c)
{
if(c.Equals (""))
return false;
if((c[0]>='0' && c[0]<='9') || c[0]=='.')
{
return true;
}
else
{
return false;
}
}
public bool Compare(string str1,string str2)
{
return getPriority(str1)>=getPriority(str2);
}
public int getPriority(string str)
{
if(str.Equals(""))
{
return -1;
}
else if (str.Equals("(") || str.Equals(")"))
{
return 0;
}
else if(str.Equals("+") || str.Equals("-"))
{
return 1;
}
else if(str.Equals("*") || str.Equals("/"))
{ return 2;
}
else
return 0;
}
}
}
using System;namespace HomeWork
{
/// <summary>
/// IOper 的摘要说明。
/// </summary>
public interface IOper
{
object Oper(object o1,object o2);
}
}
using System;namespace HomeWork
{
public class OperFactory
{
public OperFactory()
{}
public IOper CreateOper(string Oper)
{
if(Oper.Equals ("+"))
{
IOper p=new OperAdd ();
return p;
}
if(Oper.Equals ("-"))
{
IOper p=new OperDec ();
return p;
}
if(Oper.Equals ("*"))
{
IOper p=new OperRide ();
return p;
}
if(Oper.Equals ("/"))
{
IOper p=new OperDiv ();
return p;
}
return null;
}
}
}
using System;namespace HomeWork
{
public class OperAdd:IOper
{
public OperAdd()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1+d2;
}
}
public class OperDec:IOper
{
public OperDec()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1-d2;
}
}
public class OperRide:IOper
{
public OperRide()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1*d2;
}
}
public class OperDiv:IOper
{
public OperDiv()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1/d2;
}
}
}
我把代码发出来(一共是5个类,都是一个命名空间的),大家给我看看,可以复制下去改下哦,尽快改好啊、、拜托了、、using System;
using System.Collections ;namespace HomeWork
{
/// <summary>
/// Calculate 的摘要说明。
/// 计算实现主类
/// </summary>
public class Calculate
{
/// <summary>
/// 算术符栈
/// </summary>
private ArrayList HList;
/// <summary>
/// 数值栈
/// </summary>
public ArrayList Vlist;
/// <summary>
/// 读算试工具
/// </summary>
private CalUtility cu;
/// <summary>
/// 运算操作器工厂
/// </summary>
private OperFactory of;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="str"> 算式 </param>
public Calculate(string str)
{
HList = new ArrayList();
Vlist = new ArrayList();
of = new OperFactory();
cu = new CalUtility(str);
}
/// <summary>
/// 开始计算
/// </summary> public object DoCal()
{
string strTmp=cu.getItem();
while(true)
{
if(cu.IsNum(strTmp))
{
///如果是数值,则写入数据栈
Vlist.Add(strTmp);
}
else
{
///数值
Cal(strTmp);
}
if(strTmp.Equals(""))
break;
strTmp=cu.getItem();
}
return Vlist[0];
} /// <summary>
/// 计算
/// </summary>
/// <param name="str"> 计算符 </param>
private void Cal(string str)
{
if(str.Equals("")&&this.HList.Count==0)
return;
if(this.HList.Count>0)
{
if(this.HList[this.HList.Count-1].ToString().Equals("(")|| str.Equals(")"))
{
this.HList.RemoveAt(this.HList.Count-1);
if(this.HList.Count>0)
{
str=this.HList[this.HList.Count-1].ToString();
this.HList.RemoveAt(this.HList.Count-1);
this.Cal(str);
}
return ;
}
if(cu.Compare(this.HList[this.HList.Count-1].ToString(),str))
{
IOper p=of.CreateOper(this.HList[this.HList.Count-1].ToString());
if(p!=null)
{
this.Vlist[this.Vlist.Count-2]=p.Oper(this.Vlist[this.Vlist.Count-2],this.Vlist[this.Vlist.Count-1]);
this.HList.RemoveAt(this.HList.Count-1);
this.Vlist.RemoveAt(this.Vlist.Count-1);
this.Cal(str);
}
return;
}
if(!str.Equals(""))
{
this.HList.Add(str);
}
}
else
{
if(!str.Equals(""))
{
this.HList.Add(str);
}
}
}
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此处添加代码以启动应用程序
// Console.WriteLine("请输入表达式:");
string str=Console.ReadLine();
Calculate obj=new Calculate(str);
obj.DoCal();
//obj.Cal(str);
Console.WriteLine(obj.Vlist[0]);
}
}
}
using System;namespace HomeWork
{
public class CalUtility
{
System.Text.StringBuilder StrB;
private int iCurr=0;
private int iCount=0; public CalUtility(string calStr)
{
StrB=new System.Text.StringBuilder(calStr.Trim());
iCount=System.Text.Encoding.Default.GetByteCount(calStr.Trim());
}
public string getItem()
{
if(iCurr==iCount)
{
return "";
}
char ChTmp=StrB[iCurr];
bool b=IsNum(ChTmp);
if(!b)
{
iCurr++;
return ChTmp.ToString();
}
string strTmp="";
while (IsNum(ChTmp)==b && iCurr<iCount)
{
ChTmp=StrB[iCurr];
if (IsNum(ChTmp) == b)
{
strTmp += ChTmp;
}
else
{
break;
}
iCurr++;
}
return strTmp;
}
public bool IsNum(char c)
{
if((c>='0' && c<='9') || c=='.')
{
return true;
}
else
{
return false;
}
}
public bool IsNum(string c)
{
if(c.Equals (""))
return false;
if((c[0]>='0' && c[0]<='9') || c[0]=='.')
{
return true;
}
else
{
return false;
}
}
public bool Compare(string str1,string str2)
{
return getPriority(str1)>=getPriority(str2);
}
public int getPriority(string str)
{
if(str.Equals(""))
{
return -1;
}
else if (str.Equals("(") || str.Equals(")"))
{
return 0;
}
else if(str.Equals("+") || str.Equals("-"))
{
return 1;
}
else if(str.Equals("*") || str.Equals("/"))
{ return 2;
}
else
return 0;
}
}
}
using System;namespace HomeWork
{
/// <summary>
/// IOper 的摘要说明。
/// </summary>
public interface IOper
{
object Oper(object o1,object o2);
}
}
using System;namespace HomeWork
{
public class OperFactory
{
public OperFactory()
{}
public IOper CreateOper(string Oper)
{
if(Oper.Equals ("+"))
{
IOper p=new OperAdd ();
return p;
}
if(Oper.Equals ("-"))
{
IOper p=new OperDec ();
return p;
}
if(Oper.Equals ("*"))
{
IOper p=new OperRide ();
return p;
}
if(Oper.Equals ("/"))
{
IOper p=new OperDiv ();
return p;
}
return null;
}
}
}
using System;namespace HomeWork
{
public class OperAdd:IOper
{
public OperAdd()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1+d2;
}
}
public class OperDec:IOper
{
public OperDec()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1-d2;
}
}
public class OperRide:IOper
{
public OperRide()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1*d2;
}
}
public class OperDiv:IOper
{
public OperDiv()
{}
public object Oper(object o1,object o2)
{
Decimal d1=Decimal.Parse (o1.ToString ());
Decimal d2=Decimal.Parse (o2.ToString ());
return d1/d2;
}
}
}
else if (str.Equals("(") ¦ ¦ str.Equals(")"))
{
return 0;
} 是唯一的一句!
if(str.Equals(""))
{
return -1;
}
else if (str.Equals("(") ¦ ¦ str.Equals(")"))
{
return 0;
}
else if(str.Equals("+") ¦ ¦ str.Equals("-"))
{
return 1;
}
else if(str.Equals("*") ¦ ¦ str.Equals("/"))
{ return 2;
}
else
return 0;
} 我就是觉得这里对括号的处理不够好哦,在字符串的中间有括号就计算不起了,能帮我看下是什么原因哦?
帮我改善下啊
遇到左括号,把后面的字符全部入栈,知道遇到一个右括号,再出栈。同理,计算 a+b*c 也是全部入栈,等*号右边的字符出现完毕再出栈。把表达式看成一棵递归树,这样递归的算法才能保证正确。