栈的应用:实现简易计算器

栈是一种插入和删除操作都只能在尾端进行的线性表。它具有后进先出的性质,在各种软件系统中有着广泛的应用。

运用栈将中缀表达式转化为后缀表达式

  • 中缀表达式:
    一个二元运算符对应的运算量分别放在其两端,这是人们惯用且容易理解的写法。

  • 后缀表达式:
    一个二元运算符对应的运算量依次放在其左端(即运算符放在两运算量之后)。这一种方法不需要括号来提升子表达式的优先级,且运算符依照出现的先后顺序进行运算,不需要关心后续的表达式,非常适合计算机的计算和存储。

中缀表达式转换为后缀表达式的方法:

  • 手动转换

     - 将所有子表达式按照优先级加上圆括号
     - 在每一个子表达式中,移动运算符的位置到两个运算量之后
     - 去除所有圆括号
    
  • 编程转换

     - 建一个存放运算符的空栈
     - 创建存放后缀表达式的空串
     - 从左往右扫描中缀表达式:
     		* 如果是运算量:进入空串
     		* 如果是运算符:
     			 如此时栈为空:进栈
     			 如此时非空:当前运算符优先级高于栈顶运算符:进栈
     			 如此时非空:当前运算符优先级低于栈顶运算符:将栈顶依次追加到后缀表达式,直到栈为空或者栈顶优先级低于当前运算符
     			 如为 “(” :直接入栈
     			 如为 “)” :将栈顶依次出栈追加到后缀表达式,直到出现 "(“ ,则一并丢弃。
     -扫描结束后,若栈非空,将栈顶依次出栈追加到后缀表达式。
    

简易计算器实现

此计算器能够将用户输入的中缀表达式转化为后缀表达式,完成带有括号的浮点数和多位数的加、减、乘、除、乘方、模运算。

public class Example3_3 {

	public static void main(String[] args) throws Exception {  
		Example3_3 p = new Example3_3();

		Scanner sc = new Scanner(System.in);
		System.out.print("请输入中缀表达式:"); 
		String inFix = sc.nextLine();
		System.out.println();
		
		String postFix = p.covertToPostFix(inFix);
		System.out.println("\n后缀表达式为:" + postFix); 
		
		System.out.println("\n表达式运算结果为:" + p.numberCalculate(postFix));
	} 

	public int priority(char operator)
	{
		switch(operator)
		{
			case '^': return 3;

		    case '%': 
	        case '*':
	        case '/': return 2;

		    case '+':
		    case '-': return 1;
		}
		return 0;
	}
	
	public String covertToPostFix(String inFix) throws Exception{
		if ("".equals(inFix) || inFix == null)
			throw new Exception("错误:算术表达式不能为空");// 抛出异常

		LinkStack<Character> stack = new LinkStack();
		String postFix = "";
		char token=' ',topToken=' ';
		
		for (int i = 0; i < inFix.length(); i++) {
			token = inFix.charAt(i);
		    if (token == '(') {
	       		stack.push(token);
		    } 
		    else if (token == ')') {
		        topToken = stack.pop();
		        while (topToken != '(') {
		        	postFix = postFix + topToken;
		            topToken = stack.pop();
		        }
		    } 
		    else if (isOperator(token)) {
		        while (!stack.isEmpty() && (priority(token) <= priority(stack.peek()))) {
                	topToken = stack.pop();
	                postFix = postFix + topToken;
	            }
	            stack.push(token);
		    } 
		    else{
		    	String number = String.valueOf(token);		    	
		    	while(i<inFix.length()-1){
		    		if((inFix.charAt(i+1)>='0'&&inFix.charAt(i+1)<='9')||inFix.charAt(i+1)=='.'){
		    			number=number.concat(String.valueOf(inFix.charAt(i+1)));
		    			i=i+1;
		    		}
		    		else
		    			break;
		    	}
	            postFix = postFix + number + " ";
		    }	
		}
		
		while (!stack.isEmpty()) {
			token = stack.pop();
		    postFix = postFix + token;
	    }
		
		return(postFix);
	}

	public double numberCalculate(String postFix) throws Exception{
		if ("".equals(postFix) || postFix == null)
			throw new Exception("错误:后缀算术表达式不能为空");// 抛出异常
		
		LinkStack<Double> stack = new LinkStack();
		for (int i = 0; i < postFix.length(); i++){
			char token = postFix.charAt(i);
			if (isOperator(token)){
				Double d2 = stack.pop();
				Double d1 = stack.pop();
				double result = 0;
				
				if (token == '+')	result = d1 + d2;
				if (token == '-')	result = d1 - d2;
				if (token == '*')	result = d1 * d2;
				if (token == '^')	result = Math.pow(d1,d2);
				if (token == '/' && d2 != 0)	result = d1 / d2;
				if (token == '%' && d2 != 0)	result = d1 % d2;
				
				stack.push(result);
				i++;
			}else {
				    int j = postFix.indexOf(" ",i);
				    String number = postFix.substring(i,j);
					stack.push(Double.valueOf(number));
					i=j;
			}
		}
		
		return stack.pop();
	}

	public boolean isOperator(char c){
		return (c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '%' );
	}
}
经过这学期对数据结构的学习, 我们学习了理论知识, 了解了数据结构设计的思想, 这些知识都为我们的下一步学习打下了坚实的基础。通过课程设计,一方面是为了检查 我们一个学期来我们学习的成果,另一方面也是为了让我们进一步的掌握和运用它,同 时也让我们认清自己的不加以弥补和加强。足之处和薄弱环节,加以弥补和加强。 说起数据结构,它为程序提供了一种思想。计算机本身是无生命的机器,要是计算 机能够运行起来,为人类完成各种各样的工作,就必须让他执行相应的程序,这些程序 都是依靠程序设计语言编写出来的。它是一种思想,在编写程序时可以方便、灵活地运 用。同时,他还向程序员提供了直接操作计算机硬件的功能,具备低级语言的特点,适 合各种类型的软件开发。 说到课程设计,要明确自己的目标。在课设前要明确实训的相关要点,课程设计为 学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结 合起来,锻炼分析解决实际问题的能力。提高适应实际,实践编程的能力。课程设计的 基本理论是该课程设计的 C 语言为基础,掌握程序设计方法,为科学研究中的基层开发 工作奠定良好基础;同时培养学生的分析能力、设计能力和整体设计思想,以提高学生 的科学研究素质和在工作岗位中的具体应用能力。课程设计内容和基本要求,首先课程 设计内容是利用学到的编程知识和编程技巧,通过布置具有一定难度的程序设计题目, 熟悉程序编写,及时查究错误,独立完成。 通过本次课程设计, 自学掌握了随机函数与文件读写的知识, 独立完成了设计任务, 虽然思路和想法还有些不成熟,但是对自己的设计能力有很大的提高,今后仍要更加努 力的深入钻研,是自己的能力有进一步的提高。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值