主要是掌握住压栈算法,在校期间教辅提过这个设计案例:
设算数 “i0”,“i1”,“i2”,……
设算符 优先级0 “+”,“-”, 优先级1 “*”,“/”, 优先级2 “(”,“)”
设算式 i = i0 + i1 - i2 * i3 / (i4 * i5)……
Class Sign{
public int Priority{get;private set}//优先级
public int NumberCount{get;private set}//表示几元运算
public string Value{get;private set}//表现值
}
int Calculate(string i){
int index;
Stack numbers = new Stack();
Stack signs = new Stack();
int n;
Sign s;
while(index < i.length){
n = GetNumber(i, ref index);
if(n >= 0){//匹配成功
numbers.push(n);
}
else{
s = GetSign(i, ref index);
if(s == null){//非法字符?
........//可以 Throw Exception 或 做忽略等处理
}
if(s.Priority > signs.Current.Priority){//压栈
signs.push(s);
}
else{//计算 signs.Current
int[] ns = new int[signs.Current.NumberCount];
for(int j = 0;j < ns.length;j ++){
ns[j] = numbers.pop();
}
numbers.push(Calculate(signs.Current, ns));//计算并保存子式
signs.push(s);
}
}
}
//计算余式
while(signs.Count > 0){
int[] ns = new int[signs.Current.NumberCount];
for(int j = 0;j < ns.length;j ++){
ns[j] = numbers.pop();
}
numbers.push(Calculate(signs.Current, ns));//计算并保存子式
signs.pop();
}
}
int GetNumber(string i, ref int charIndex){//读取算数
//如果能运用正则表达式一次性清理出所有 算数、算符 则最好:),那本方法就可以省去了
}
Sign GetSign(string i, ref int charIndex){//读取算符
//如果能运用正则表达式一次性清理出所有 算数、算符 则最好:),那本方法就可以省去了
}
int Calculate(Sign sign, int[] numbers){//计算该算式
switch(sign.Value){
case("+"):
//处理加法逻辑
break;
Default:
//Throw Exception 或 返回默认运算等
break;
}
}
大概的算法脉络或许是这样,其中有很多细节需要自行把握了(异常处理等)。
从几何时,我也能徒手编程了:),偶尔练练算法感觉挺舒畅的。
--------------------------------------------------------------------------
貌似“负数”没考虑进去!