功能:从控制台接受输入的一行表达式,计算其值.
如果有无效字符输入则忽略(45,67===>4567)
可以现实负数,双精度数(54.3 54. 54E-4)作为运算数.不能判断54.5Ee-4是错误的.
还没想好怎么改Orz............
实在想不出应该怎样写四则运算的正则表达式.验证表达式的正确是通过中缀能否转化成合理的后缀.代码如下:
import java.util.*;
import java.io.*;
public class StackTest
{
public static void main(String[] args)
{
String sentence="";
try
{
System.out.println("请输入表达式");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
sentence = in.readLine();
}
catch(IOException e)
{
e.printStackTrace();
}
Operate op = new Operate(sentence);
System.out.println(op + " = " + op.execute());
}
}
class Operate
{
private String sentence;
private ArrayList<Object> opers;
private ArrayList<Object> suffixExpression;
public Operate() {}
public Operate(String sentence)
{
opers = new ArrayList<Object>();
suffixExpression = new ArrayList<Object>();
this.sentence = sentence;
init();
setSuffixExpression();
}
//将输入的字符串分割,存放到opers中.
//只能说Double.parseDouble()太好用了=.=,什么样的都能接受
public void init()
{
char[] chars = sentence.toCharArray();
String value = "";
boolean flag = false;
for(char c : chars)
{
if(isBelongToDecimal(c))
{
value += c;
flag = true;
if(c == 'e' || c == 'E')
flag = false;
}
else if((c == '-' || c== '+') && !flag)
{
value += c;
flag = true;
}
else if(isAvailableCode(c))
{
if(flag)
{
opers.add(value);
flag = false;
}
value = "";
opers.add(c);
}
}
if(flag)
opers.add(value);
}
//将opers中存放的表达式转化成后缀形式,存放至suffixExpression中
public void setSuffixExpression()
{
Stack<Object> op = new Stack<Object>();
Object top = new Object();
for(int i = 0; i < opers.size(); i++)
{
String current = opers.get(i).toString();
if(current.equals("("))
op.push(current);
else if(current.equals(")"))
for(; ;)
{
assert(!op.empty());
top = op.pop();
if(top.equals("("))
break;
suffixExpression.add(top);
}
else if(current.equals("+") ||
current.equals("-") ||
current.equals("*") ||
current.equals("/"))
for(; ;)
{
if(op.empty() ||
op.peek().toString().equals("(") ||
((current.equals("*") || current.equals("/")) &&
(op.peek().toString().equals("+") || op.peek().toString().equals("-"))))
{
op.push(current);
break;
}
else
{
top = op.pop();
suffixExpression.add(top);
}
}
else
suffixExpression.add(current);
}
for(; ;)
{
if(op.empty())
break;
top = op.pop();
if(top != "(")
suffixExpression.add(top);
else
{
System.out.println("错误的表达式");
return;
}
}
}
//计算后缀表达式的值.
public double execute()
{
Stack<Object> temp = new Stack<Object>();
for(int i = 0; i < suffixExpression.size(); i++)
{
try
{
double value = Double.parseDouble(suffixExpression.get(i).toString());
temp.push(value);
}
catch(NumberFormatException e)
{
String exp = suffixExpression.get(i).toString();
double right = Double.parseDouble(temp.pop().toString());
double left = Double.parseDouble(temp.pop().toString());
temp.push(executeSingleExpression(left, right, exp));
}
}
return Double.parseDouble(temp.pop().toString());
}
public double executeSingleExpression(double left, double right, String exp)
{
if(exp.equals("+"))
return left + right;
else if(exp.equals("-"))
return left - right;
else if(exp.equals("*"))
return left * right;
else if(exp.equals("/"))
return left / right;
return 0.0;
}
public boolean isAvailableCode(char c)
{
return (AVAILABLE_CODE.indexOf(c) != -1);
}
public boolean isBelongToDecimal(char c)
{
return (AVAILABLE_DECIMAL_CODE.indexOf(c) != -1);
}
public String toString()
{
StringBuilder builder = new StringBuilder();
for(int i = 0; i < opers.size(); i++)
{
builder.append(opers.get(i));
builder.append(" ");
}
return builder.toString();
}
public static final String AVAILABLE_CODE = "+-*/()";
public static final String AVAILABLE_DECIMAL_CODE = "1234567890.Ee";
}
意外发现
1:JAVA中,参数的传递顺序是从左至右的如 function(int args1, int args2){}
如果这样调用: int i = 0; function(++i, i++){} 则args1 = 1, args2= 1;
2:String a = "a"; if( a == "a") .... else ... 实在太郁闷了!!!!!!!!!!!!!!!!!低级错误Orz...
3:main函数的参数 args 居然不认识 * , 遇到*,对应的字符串居然是当前目录下的所有文件(文件夹)的名字. 想不出什么办法对付它..
写完了.睡觉ZZZZZZZZZZZZZZZZZZZ