JAVA实现表达式字符串求结果

JAVA实现表达式字符串求结果

这里主要实现0~9以及结果是整数的情况下,具体实现可以根据自己情况改

在求表达式前,我们需要学会一个数据结构和几个名词

数据结构-栈

栈,先进后出的一种基于数组的结构,他由数组和末尾的索引组成。这样看起来很抽象,但我们可以想象一下,像生活中的在拥挤的电车里或者窄长的电梯里,最后一个进去的人总是第一个人出去。

进去人的时候我们叫他进栈、入栈或压栈,出来人的时候我们叫他出栈或退栈。最靠近门的人的位置叫做栈顶,最里面的人的位置交栈底。这里用一下度娘的图。

img

栈在java里用类可以表示为:(JDK自带Stack)一下仅为演示

public class MyStack<E> {
	Object[] elementData = new Object[100];//用于储存信息的数组,预计栈中长度超不过100
	int elementCount = 0;  			//栈顶的下一个位置
	int top = -1;		//栈顶位置
	public MyStack() {
	}
	
	/**
	 * 入栈,加入数据
	 * @param item
	 */
	public void push(E item) {    
		elementData[elementCount++] = item;//放数据
		top++;//栈顶在top位
    }
	
	/**
	 * 出栈,并返回栈顶是什么
	 * @return
	 */
	public  E pop() {
		E obj = (E) elementData[top];
		top --;
		elementCount--;
        return obj;
    }
	
	/**
	 * 返回栈顶变量
	 */
	public  E peek() {
        return (E) elementData[top];
    }
}

几个名词

  • 中缀表达式: (百度)操作符是以中缀形式处于操作数的中间 ,说白了就是咱平时看到的数学表达式,像1+2*(3+4)/5。(老整这些名词像是怕谁万一听懂了一样→n→)
  • 后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行 。emmm…就像3+4吧,转换成后缀表达式就是3 4 +,两个数一个运算符这么个结构。
  • 后缀表达式还有个名字,叫逆波兰式 ,以后可以用这个词装装逼→v→
  • 优先级:谁数高谁先呗(当我凑字数)。

运算法则

优先级0123456
栈内#()+ -* /
栈外#)+ -* /(
  • 首先在栈把“#”进行压栈,并在中缀表达式追加“#”。“#”作为结束标志。
  • 对中缀表达式进行遍历,遇到数字进行输出到后缀表达式中
  • 如果遇到运算符,把 栈顶的元素的栈内优先级 与 即将入栈元素的栈外优先级 进行比较,如果 栈顶的元素 小,则运算符入栈,否则,则把 栈顶元素 出栈并输出到后缀表达式中,然后把 即将入栈元素 入栈。(良心短句有木有→v→
  • 循环前两步直至中缀表达式的尾部的“#”。

注意,前面说过,后缀表达式没有括号!!!

后缀表达式的计算

先遍历后缀表达式,碰到的数字让他入栈,每当遇到运算符的时候,取出两个栈用这个运算符运算,结果入栈,一直到结束标记#为止

代码

用到上面写的MyStack< E >

/**
 * 目前只支持求整数,只提供思路,具体功能可以自己加
 * @author 絕了千年良緣
 *
 */
public class Deom {
	
	/**
	 * 中缀表达式->后缀表达式
	 * @param infixExp 中缀表达式
	 * @return 结果
	 */
	public static String calculate_postfixExp(String infixExp) {
		
		//栈外优先级
		int addsub = 2;//加减
		int muldiv = 4;//乘除
		int pound = 0;//井号
		int left_bracket = 6;//前括号
		int right_bracket = 1;//后括号
		
		StringBuffer postfixExp = new StringBuffer("");//后缀表达式
		MyStack<Character> stack = new MyStack<>();//栈
		stack.push('#');//标记
		
		char[] ife = infixExp.toCharArray();
		for (char c : ife) {//遍历
			if (c>'0'&&c<'9') {//如果是数,直接加进去
				postfixExp.append(c);
			}else if (isoperator(c)) {//如果是运算符
				switch (c) {//哪那种字符串,以及出栈入栈的处理
				case '+':if (whichoperator(stack.peek())<addsub) {stack.push(c);}
						else {pop(stack, addsub, postfixExp,c);} ;break;
				case '-':if (whichoperator(stack.peek())<addsub) {stack.push(c);}
					else {pop(stack, addsub, postfixExp,c);} ;break;
				case '*':if (whichoperator(stack.peek())<muldiv) {stack.push(c);}
					else {pop(stack, muldiv, postfixExp,c);} ;break;
				case '/':if (whichoperator(stack.peek())<muldiv) {stack.push(c);}
					else {pop(stack, muldiv, postfixExp,c);} ;break;
				case '#':if (whichoperator(stack.peek())<pound) {stack.push(c);}
					else {pop(stack, pound, postfixExp,c);} ;break;
				case '(':if (whichoperator(stack.peek())<left_bracket) {stack.push(c);}
					else {pop(stack, left_bracket, postfixExp,c);} ;break;
				case ')':if (whichoperator(stack.peek())<right_bracket) {stack.push(c);}
					else {pop(stack, right_bracket, postfixExp,c);} ;break;
				}
			}
		}
		System.out.println("后缀表达式:"+postfixExp.toString());
		return postfixExp.toString();
	}
	
	/**
	 * 判断是不是有效符号运算符
	 */
	public static boolean isoperator(char c) {
		if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#') {
			return true;
		}
		return false;
	}
	
	/**
	 * 返回该字符的站内优先级
	 * @param c
	 * @return
	 */
	public static int whichoperator(char c) {
		//栈内优先级
		int addsub = 3;//加减
		int muldiv = 5;//乘除
		int pound = 0;//井号
		int left_bracket = 1;//前括号
		int right_bracket = 2;//后括号
		
		switch (c) {
		case '+':return addsub;
		case '-':return addsub;
		case '*':return muldiv;
		case '/':return muldiv;
		case '(':return left_bracket;
		case ')':return right_bracket;
		case '#':return pound;
		}
		return 12138;//用不到,但报错就很难受啊
	}
	
	/**
	 * 出栈操作
	 * @param stack 栈
	 * @param num 栈外优先级
	 * @param postfixExp 后缀表达式
	 */
	public static void pop(MyStack<Character> stack ,int num,StringBuffer postfixExp,char c) {
		while (whichoperator(stack.peek())>=num) {
			if (stack.peek()!='('||stack.peek()!=')') {//除去括号
				postfixExp.append(stack.pop());
			}
		}
		stack.push(c);//记得让这个符号入栈
	}
	
	/**
	 * 后缀表达式->结果
	 * @param postfixExp 后缀表达式
	 * @return 运算结果
	 */
	public static int calculate(String postfixExp) {
		char[] c = postfixExp.toCharArray();
		MyStack<Integer> num = new MyStack<>();//用于存放数的栈
		for (int i = 0; i < c.length; i++) {//遍历后缀表达式
			if (c[i]>='0'&&c[i]<='9') {//如果是数
				num.push((int)c[i]-48);//进栈
			}else if (c[i]!='#') {//如果是非#的运算符
				switch (c[i]) {//出栈出两个数算,并将结果进栈
				case '+':num.push(num.pop()+num.pop());break;
				case '-':num.push(num.pop()-num.pop());break;
				case '*':num.push(num.pop()*num.pop());break;
				case '/':num.push(num.pop()/num.pop());break;
				}
			}
		}
		return num.pop();	//此时栈中只有一个数,那就是结果	
	}
	
	public static void main(String[] args) {
		System.out.println("请输入表达式:");
		Scanner sc = new Scanner(System.in);
		String equation = sc.nextLine();
		int result =calculate(calculate_postfixExp(equation));
		System.out.println("结果是:"+result);
	}
}

最后,真爽

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值