Java之Stack --- 栈

前几天,写那个带有算符优先级的计算器的时候用到了,又查了一些资料,感觉栈还是很重要的。故而,再次总结一下。

栈是一种先进后出的数据集合。它通过五个操作对类Vector 进行了扩展 ,允许将向量视为堆栈。它提供了通常的pushpop 操作,以及取堆栈顶点的peek 方法、测试堆栈是否为空的 empty 方法、在堆栈中查找项并确定到堆栈顶距离的search 方法。 

首次创建堆栈时,它不包含项。

它的构造方法是 public Stack()

一共有五个方法,这五个方法在你用到栈的时候基本都会用到,所以要掌握。

1. boolean   |   empty()  返回值是boolean值。 用于测试栈是否为空

2. E  |  peek()  返回值是你定义栈的时候的数据类型。 用于查看栈顶部的对象,但是不从栈中移除。这个很重要,因为它不移除对象,只是查看这个对象,而 pop() 这个方法会从栈中移除栈顶的对象。注意这两个的区别!

3. E  |  pop()  用于移除堆栈顶部的对象,并返回该对象

4. E  |  push(E item)    将item压入栈中,即压入堆栈顶部。

5. int  |  search(Object o)  查找某对象在堆栈中的位置。返回对象在堆栈中的位置,以1为基数。此方法返回距堆栈顶部最近的出现位置到堆栈顶部的距离;堆栈中最顶部项的距离为1。



下面说一下我的那个计算器吧!

目前一般的计算器进行计算时不能输入括号,而且需要事先得到表达式的各项才能使用它,例如:若直接输入:3+4*5,一般的计算器会在输入乘号时,先得到7,输入完成后的结果是35。

具有算符优先级的计算器就是。按照数学中的符号优先级 来计算。

这里主要用到两个栈,一个符号栈,一个数字栈

最主要的还是以一个算法  ----  算符优先算法


OperandType EvaluateExpression(){
	//算术表达式求值的算符优先算法。设OPTR和OPND分别为运算符和运算数栈
	//OP为运算符集合
	InitStack(OPTR); Push(OPTR, '#');
	InitStack(OPND); c = getchar();
	while(c!= '#' || GetTop(OPTR)!='#'){
		if(!In(c, op)){
			Push(OPND, c);
			c = getchar();
		}else{
			while(Precede(GetTop(OPTR),c)){
				case '<'://栈顶元素优先权低
					Push(OPTR, C);
					c = getchar();
					break;
				case '='://脱括号并接受下一个字符
					pop(OPTR, x);
					c = getchar();
					break;
				case '>'://退栈并将运算结果入栈
					Pop(OPTR, theta);
					Pop(OPND, b);
					Pop(OPND, a);
					Push(OPND, Operate(a, theta, b));
					break;
			}
		}	
	}
	return GetTop(OPND);
}

Precede(GetTop(OPTR),c) 这个函数用来比较算符的优先级

Operate(a, theta, b)  这个函数是用来计算结果

最后用GetTop(OPND)取出运算符栈的栈底,即结果存放的位置。。。


以下是我写的具体实现:

//计算结果函数
	private static String Operate(String a, String theta, String b) {
		String result = "";
		double reusltDouble = 0.0;
		double aDouble = Double.parseDouble(a);
		double bDouble = Double.parseDouble(b);
		switch (theta) {
		case "+":
			reusltDouble = aDouble + bDouble;
			break;
		case "-":
			reusltDouble = aDouble - bDouble;
			break;
		case "*":
			reusltDouble = aDouble * bDouble;
			break;
		case "/":
			if (bDouble != 0.0) {
				reusltDouble = aDouble / bDouble;
			}
			else {
				System.out.println("被除数不能为0!");
				return null;
			}
			break;
		default:
			System.out.println("操作符输入错误!");
			return null;
		}
		result = reusltDouble+"";
		return result;
		
	}


//判断符号的优先级
	private static String Precede(String ch1, String ch2) {
		String ch = "";
		if (ch1.equals("+")) {
			if (ch2.equals("+")) {
				ch = ">";
			}else if (ch2.equals("-")) {
				ch = ">";
			}else if (ch2.equals("*")) {
				ch = "<";
			}else if (ch2.equals("/")) {
				ch = "<";
			}else if (ch2.equals("(")) {
				ch = "<";
			}else if (ch2.equals(")")) {
				ch = ">";
			}else if (ch2.equals("#")) {
				ch = ">";
			}
		}else if (ch1.equals("-")) {
			if (ch2.equals("+")) {
				ch = ">";
			}else if (ch2.equals("-")) {
				ch = ">";
			}else if (ch2.equals("*")) {
				ch = "<";
			}else if (ch2.equals("/")) {
				ch = "<";
			}else if (ch2.equals("(")) {
				ch = "<";
			}else if (ch2.equals(")")) {
				ch = ">";
			}else if (ch2.equals("#")) {
				ch = ">";
			}
		}else if (ch1.equals("*")) {
			if (ch2.equals("+")) {
				ch = ">";
			}else if (ch2.equals("-")) {
				ch = ">";
			}else if (ch2.equals("*")) {
				ch = ">";
			}else if (ch2.equals("/")) {
				ch = ">";
			}else if (ch2.equals("(")) {
				ch = "<";
			}else if (ch2.equals(")")) {
				ch = ">";
			}else if (ch2.equals("#")) {
				ch = ">";
			}
		}else if (ch1.equals("/")) {
			if (ch2.equals("+")) {
				ch = ">";
			}else if (ch2.equals("-")) {
				ch = ">";
			}else if (ch2.equals("*")) {
				ch = ">";
			}else if (ch2.equals("/")) {
				ch = ">";
			}else if (ch2.equals("(")) {
				ch = "<";
			}else if (ch2.equals(")")) {
				ch = ">";
			}else if (ch2.equals("#")) {
				ch = ">";
			}
		}else if (ch1.equals("(")) {
			if (ch2.equals("+")) {
				ch = "<";
			}else if (ch2.equals("-")) {
				ch = "<";
			}else if (ch2.equals("*")) {
				ch = "<";
			}else if (ch2.equals("/")) {
				ch = "<";
			}else if (ch2.equals("(")) {
				ch = "<";
			}else if (ch2.equals(")")) {
				ch = "=";
			}
		}else if (ch1.equals(")")) {
			if (ch2.equals("+")) {
				ch = ">";
			}else if (ch2.equals("-")) {
				ch = ">";
			}else if (ch2.equals("*")) {
				ch = ">";
			}else if (ch2.equals("/")) {
				ch = ">";
			}else if (ch2.equals("(")) {//此时会报错!
				System.out.println("语法错误!()");
				ch = " ";
			}else if (ch2.equals(")")) {
				ch = ">";
			}else if (ch2.equals("#")) {
				ch = ">";
			}
		}else if (ch1.equals("#")) {
			System.out.println(ch2);
			if (ch2.equals("+")) {
				ch = "<";
			}else if (ch2.equals("-")) {
				ch = "<";
			}else if (ch2.equals("*")) {
				ch = "<";
			}else if (ch2.equals("/")) {
				ch = "<";
			}else if (ch2.equals("(")) {//此时会报错!
				ch = "<";
			}else if (ch2.equals(")")) {
				ch = " ";
				System.out.println("语法错误!#)");
			}else if (ch2.equals("#")) {
				ch = "=";
			}
		}
		
		return ch;
	}

// 计算器
	public static double EvaluateExpression() {
		double result = 0.0;
		Stack<String> OPTR = new Stack<String>();
		Stack<String> OPND = new Stack<String>();
		OPTR.push("#");
		int i = 0;
		String c = "";
		c = tolArray[i];
		while (!c.equals("#") || !OPTR.peek().equals("#")) {
			System.out.println(OPTR.peek());
			if (!exitInOtherArray(c)) {
				System.out.println(c);
				OPND.push(c);
				i++;
				c = tolArray[i];
			} else {
				System.out.println(OPTR.peek());
				System.out.println(c);
				switch (Precede(OPTR.peek(), c)) {
				case  "<":
					OPTR.push(c);
					i++;
					c = tolArray[i];
					break;
				case "=":
					OPTR.pop();
					i++;
					c = tolArray[i];
					break;
				case ">":
					String theta = OPTR.pop();
					String b = OPND.pop();
					String a = OPND.pop();
					OPND.push(Operate(a, theta, b));
					break;

				default:
					break;
				}
			}

		}
		result = Double.parseDouble(OPND.peek());
		return result;
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值