读书人

暑假在家闲得要命写了个简单的算术式

发布时间: 2012-01-03 22:16:06 作者: rapoo

暑假在家闲得要命,写了个简单的算术式解析器,大家来批评一下吧
class Node <E> {

//o:object
public E o;
//p:priority
public int p;
//l:left,r:right
public Node l,r;

public Node(E o){
this.o = o;
}
}

class Stack <E> {

private Node cur;
private int size = 0;

public void push(E o){
Node <E> n = new Node <E> (o);
if(cur!=null){
cur.r = n;
n.l = cur;
}
cur = n;
size++;
}

public E pop(){
if(size==0)
return null;
try{
size--;
return (E)cur.o;
}finally{
cur = cur.l;
if(cur!=null)
cur.r = null;
}
}

public int size(){
return size;
}
}

class Tree{

private Node <String> cur,root,start;
private Stack <Node> nodes;
private String s[],result;

public void insert(String s[]){

if(s.length <=2)
return;
int x = Parser.X_INIT;
nodes = new Stack <Node> ();

//create a root in order to get a start
//and solve the condition of starting with "( "
cur = new Node <String> (Parser.operators[0]);
cur.l = new Node <String> ( "0 ");
cur.p = Parser.p(Parser.operators[0])+x;
root = cur;
start = root;

for(int i=0;i <s.length;i++){

//a new node
Node <String> n = new Node <String> (s[i]);


//while s is () , increase or decrease its priority
x += s[i].equals( "( ")?Parser.X_STEP:s[i].equals( ") ")?-Parser.X_STEP:0;

if(Parser.isOperator(s[i])){

n.p = Parser.p(s[i])+x;

//while this node 's priority is less than the previous '
//then roll back
while(cur.p> n.p)
rollBack();

//while this node 's priority is bigger than the previous '
//then connect this to the right child
//and move the origin right child to its left child
if(cur.p <n.p){
nodes.push(cur);
n.l = cur.r;
cur.r = n;

//while this node 's priority is the same as the previous '
//then connect its left child with the previous '
//and move the parent connect from the previous ' to this
}else if(cur.p==n.p){
n.l = cur;
if(nodes.size()==0)
root = n;
}

cur = n;

//while this node is a number
//then connect it to the current node 's right child
}else if(java.util.regex.Pattern.matches( "(\\d+\\.\\d+)|\\d+ ",s[i])){
cur.r = n;


}
}

//rollback at end
while(nodes.size()> 0)
rollBack();

//remove the temp start:
//find the node which left child is the temp start
//then connect its left child to the temp start 's right child
if(start==root){
root = start.r;
}else{
cur = root;
while(cur.l.l.l!=null)
cur = cur.l;
cur.l = cur.l.r;
}

}

//roll back to the parent tree
private void rollBack(){
Node <String> temp = nodes.pop();
temp.r = cur;
cur = temp;
if(nodes.size()==0)
root = temp;
}

//iterate the tree prefixally
public String prefix(){
result = " ";
prefixIterate(root);
return result;
}
private void prefixIterate(Node n){
if(n==null)
return;
result += n.o+ " ";
prefixIterate(n.l);
prefixIterate(n.r);
}

//iterate the tree postfixally
public String postfix(){
result = " ";
postfixIterate(root);
return result;
}
private void postfixIterate(Node n){
if(n==null)
return;
postfixIterate(n.l);
postfixIterate(n.r);
result += n.o+ " ";
}
}

class Calculator{

//get the result from postfix expression
public static double calculateInPostfix(String s[]){
Stack <Double> num = new Stack <Double> ();
double result = 0;


for(int i=0;i <s.length;i++)
if(Parser.isOperator(s[i])){
double d1 = num.pop();
double d2 = num.pop();
result = calculate(d1,d2,s[i]);
num.push(result);
}else{
num.push(Double.parseDouble(s[i]));
}
return num.pop();
}

//the calculate rule
//you can add your rule here < < < < < < < < < < < < < < < < < < < < < < <
public static double calculate(double d1,double d2,String operator){
double result = 0;
if(operator.equals( "+ ")){
result = d2+d1;
}else if(operator.equals( "- ")){
result = d2-d1;
}else if(operator.equals( "* ")){
result = d2*d1;
}else if(operator.equals( "/ ")){
result = d2/d1;
}else if(operator.equals( "^ ")){
result = Math.pow(d2,d1);
}else if(operator.equals( "# ")){
result = Math.pow(d2,1/d1);
}
return result;
}
}

public class Parser{

//the support operators
public static final String operators[] = new String[]{ "+ ", "- ", "* ", "/ ", "^ ", "# "};
//the support operators in regex
public static final String operators2[] = new String[]{ "\\+ ", "\\- ", "\\* ", "\\/ ", "\\^ ", "# "};
//the prioritie of the operators
//it should be less than X_STEP
public static final int priorities[] = new int[]{2,2,4,4,6,6};
//you can add your operator in upwards 3 arrays < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < <

//x:extension priority
//the extension priority of ()
//X_INIT is the initial value


//and the X_STEP is the extension priority;
public static int X_INIT = 1,X_STEP = 10;

private String s[];
private Tree t = new Tree();

public Parser(String s){
this.s = parseSource(s.trim());
t.insert(this.s);
}

//judge if it is an operator
public static boolean isOperator(String s){
for(int i=0;i <operators.length;i++)
if(operators[i].equals(s))
return true;
return false;
}

//get the priority fo operator
public static int p(String s){
for(int i=0;i <operators.length;i++)
if(operators[i].equals(s))
return priorities[i];
return -1;
}

//hanle the source string
private String[] parseSource(String s){
String rule = "[^\\d|\\(|\\)|\\. ";
for(int i=0;i <operators2.length;i++)
rule += "| "+operators2[i];
rule += "] ";
s = s.replaceAll(rule, " ");
for(int i=0;i <operators2.length;i++)
s = s.replaceAll(operators2[i], " "+operators2[i]+ " ");
s = s.replaceAll( "\\( ", "( ").replaceAll( "\\) ", " ) ");
return s.split( " + ");
}

public double calculate(){
return Calculator.calculateInPostfix(t.postfix().split( " "));
}

//get the infix expression
public String converToInfix(){
String result = " ";
for(int i=0;i <s.length;i++)
result += s[i]+ " ";
return result;
}

//get the prefix expression
public String converToPrefix(){
return t.prefix();
}

//get the postfix expression
public String converToPostfix(){
return t.postfix();


}

public static void main(String args[]){
Parser p = new Parser( "(1+2.7)*3*(7+9)^(2#3)+1/5 ");
System.out.println( "中缀表达式: "+p.converToInfix());
System.out.println( "前缀表达式: "+p.converToPrefix());
System.out.println( "后缀表达式: "+p.converToPostfix());
System.out.println( "计算结果: "+p.calculate());
}
}

[解决办法]
不错不错~~
支持一下
不过这些东西网上应该都有了
可以写些应用的东西
花几天旅游也不错,难得放假~~

读书人网 >J2SE开发

热点推荐