欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  资讯频道

设计模式 之 解释器模式

程序员文章站 2022-03-24 08:41:06
...

 

  好多的  加法运算 ,没有发现  加括号的 的加减乘除的 解释器,参考了 别人的 算法,写了 这个 ,只能说别人的算法好,,,,

 

算法地址:http://blog.sina.com.cn/s/blog_6759f4610100j2qt.html

 

 

 

 

package 设计模式.解释器模式;

import java.util.HashMap;
import java.util.Map;

public class Context {
	private final Map<String, Integer> valueMap = new HashMap<String, Integer>();

	public void addValue(final String key, final int value) {
		valueMap.put(key, Integer.valueOf(value));
	}

	public int getValue(final String key) {
		return valueMap.get(key).intValue();
	}
}

 

package 设计模式.解释器模式;

public abstract class AbstractExpression {
	 public abstract int interpreter(Context context);
}

 

package 设计模式.解释器模式;

public class TerminalExpression extends AbstractExpression {
	private final int i;

	public TerminalExpression(final int i) {
		this.i = i;
	}

	@Override
	public int interpreter(final Context context) {
		return this.i;
	}

}

  

 

package 设计模式.解释器模式;

public class AddNonterminalExpression extends AbstractExpression {
	private final AbstractExpression left;
	private final AbstractExpression right;

	public AddNonterminalExpression(final AbstractExpression left,
			final AbstractExpression right) {
		this.left = left;
		this.right = right;
	}

	@Override
	public int interpreter(final Context context) {
		return this.left.interpreter(context) + this.right.interpreter(context);
	}

}

 

package 设计模式.解释器模式;

public class SubtractNonterminalExpression extends AbstractExpression {
	private final AbstractExpression left;
	private final AbstractExpression right;

	public SubtractNonterminalExpression(final AbstractExpression left,
			final AbstractExpression right) {
		this.left = left;
		this.right = right;
	}

	@Override
	public int interpreter(final Context context) {
		return this.left.interpreter(context) - this.right.interpreter(context);
	}
}

 

package 设计模式.解释器模式;

public class MultiplyNonterminalExpression extends AbstractExpression {
	private final AbstractExpression left;
	private final AbstractExpression right;

	public MultiplyNonterminalExpression(final AbstractExpression left,
			final AbstractExpression right) {
		this.left = left;
		this.right = right;
	}

	@Override
	public int interpreter(final Context context) {
		return this.left.interpreter(context) * this.right.interpreter(context);
	}

}

  

package 设计模式.解释器模式;

public class DivisionNonterminalExpression extends AbstractExpression {
	private final AbstractExpression left;
	private final AbstractExpression right;

	public DivisionNonterminalExpression(final AbstractExpression left,
			final AbstractExpression right) {
		this.left = left;
		this.right = right;
	}

	@Override
	public int interpreter(final Context context) {
		final int value = this.right.interpreter(context);
		if (value != 0) {
			return this.left.interpreter(context) / value;
		}
		return -1111;
	}
}

  

package 设计模式.解释器模式;
 
//解释器模式定义语言的文法,并且建立一个解释器来解释该语言中的句子。它属于类的行为模式。这里的语言意思是使用规定格式和语法的代码。
//应用环境:
//如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。
//这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。而且当文法简单、效率不是关键问题的时候效果最好。
public class InterpreterDemo {
	// 40~47  ( ) * + , - . /      0~9 是 48~57 a~z 是 97~122 A~Z 是 65~90     61 =
	// ( a+ b * ( a + b ) * a ) * b + a
	
	// [1, +, 2, *, (, 3, +, 4, *, 5, ), *, 1, #]
	

class NumQueue {
	char num[];
	int head, rear;

	NumQueue() {
		num = new char[1];
		head = -1;
		rear = -1;
	}

	public boolean isEmpty() {
		if (head == rear)
			return true;
		else
			return false;
	}

	public void inQueue(char ch) {
		num[++rear] = ch;
	}

	public void init() {
		head = -1;
		rear = -1;
		for (int i = 0; i < 1; i++)
			num[i] = '\0';
	}

	public String getNumber() {
		String str = new String(num); 
		return str;
	}
}
 
class StackAbstractExpression {
	AbstractExpression data[];
	int top;
	int base;

	StackAbstractExpression() {
		data = new AbstractExpression[15];
		top = -1;
		base = -1;
	}

	public AbstractExpression getTop() {
		return data[top];
	}

	public void push(AbstractExpression ae) {
		data[++top] = ae;
	}

	public AbstractExpression pop() {
		return data[top--];
	}

	public boolean isEmpty() {
		if (top == base)
			return true;
		else
			return false;
	}

	public void init() {
		top = -1;
		base = -1;
	}
}

class StackOper {
	char data[];
	int top;
	int base;

	StackOper() {
		data = new char[20];
		top = -1;
		base = -1;
	}

	public char getTop() {
		return data[top];
	}

	public void init() {
		top = -1;
		base = -1;
	}

	public void push(char ch) {
		data[++top] = ch;
	}

	public char pop() {
		return data[top--];
	}

	public boolean isEmpty() {
		if (top == base)
			return true;
		else
			return false;
	}
}

	
	
	static StackAbstractExpression stackData;
	static StackOper stackOper;
	static NumQueue queue;
	static boolean  rs, divErr = false;
	public static void   doHandler(String exp, Context context){
		queue = new InterpreterDemo().new NumQueue(); 
		stackData =  new InterpreterDemo().new StackAbstractExpression();
		stackOper =  new InterpreterDemo().new StackOper();
		exp = exp.replaceAll(" ","");
		exp+= "#";
		stackOper.init();
		stackData.init();
		stackOper.push('#');
		String dou = "";
		int ps = 0, pc = 0; 
		System.out.println(" exp: "+exp);
		
		char ch[] = exp.toCharArray();

		char op;
		int i = 0;
		op = ch[i];

		while (op != '#' || stackOper.getTop() != '#') {
			if ((op > 96 && op < 123) ) {
				queue.inQueue(op);
				i++;
				op = ch[i];
			} else {
				if (!queue.isEmpty()) {
					dou = queue.getNumber();
					//System.out.println ("stackData.push  (" + dou + ") ");
					stackData.push(new TerminalExpression(context.getValue(dou)));
					queue.init();
				}
				ps = getSPri(stackOper.getTop());
				pc = getCPri(op);
				if (stackOper.getTop() == '(' && op == '#'
						|| stackOper.getTop() == ')' && op == '('
						|| stackOper.getTop() == '#' && op == ')') { 
					rs = true;
				}
				if (ps < pc) {
					//System.out.println (" 操作符在栈内的优先级 " + ps +" 操作符进栈的优先级优先级 "+ pc +" "+ "stackOper.push  " + op + " ");
					stackOper.push(op);
					i++;
					op = ch[i];
				}
				if (ps == pc) {
					char c = stackOper.pop();
					//System.out.println  (" 操作符在栈内的优先级 " + ps +" 操作符进栈的优先级优先级 "+ pc + "stackOper.pop  " + c + " ");
					op = ch[++i];
				}
				if (ps > pc) {
					char theta = stackOper.pop();
					AbstractExpression b =   stackData.pop();
					AbstractExpression a =  stackData.pop();
					stackData.push(operate(a, b, theta));
					//System.out.println  (" 操作符在栈内的优先级 " + ps +" 操作符进栈的优先级优先级 "+ pc +" stackData.push  "  +operate(a, b, theta)+ " ");
				}
			}
		}
		double res = stackData.getTop().interpreter(context);
		System.out.println(res);
		rs = true;
	
	}
	
	public static AbstractExpression operate(AbstractExpression a, AbstractExpression b, char ch) {
		AbstractExpression res =null;
		switch (ch) {
		case '+':
			res = new AddNonterminalExpression( a, b);
			break;
		case '-':
			res = new SubtractNonterminalExpression( a, b);
			break;
		case '*':
			res = new MultiplyNonterminalExpression( a, b);
			break;
		case '/':
			res = new DivisionNonterminalExpression( a, b);
				break; 
		default: 
			break;
		}
		return res;
	} 

	// 操作符在栈内的优先级
	public static int getSPri(char op) {
		int pr = 0;
		switch (op) {
		case ')':
			pr = 6;
			break;
		case '*':
			pr = 5;
			break;
		case '/':
			pr = 5;
			break;
		case '+':
			pr = 3;
			break;
		case '-':
			pr = 3;
			break;
		case '(':
			pr = 1;
			break;
		case '#':
			pr = 0;
			break;
		}
		return pr;
	}

	// 操作符进栈的优先级优先级
	public static int getCPri(char op) {
		int pr = 0;
		switch (op) {
		case ')':
			pr = 1;
			break;
		case '*':
			pr = 4;
			break;
		case '/':
			pr = 4;
			break;
		case '+':
			pr = 2;
			break;
		case '-':
			pr = 2;
			break;
		case '(':
			pr = 6;
			break;
		case '#':
			pr = 0;
			break;
		}
		return pr;
	}
	
	
	public static void main(String[] args) {
		final Context context = new Context();
		context.addValue("a", 1);
		context.addValue("b", 2); 
		doHandler("(a+b*(a+b)*a)*b+a",context);
	}
}

  

 

 
设计模式 之 解释器模式