栈--中缀表达式与逆波兰表达式

构造一个栈类

<pre>
class StackArray{
	public int maxiSize;
	public int[] stack;
	public int top;
	public StackArray(int maxiSize) {
		//构造一个栈
		this.top = -1;
		this.maxiSize = maxiSize;
		stack = new int[maxiSize];
	}
	public boolean isEmpty() {
		return this.top == -1 ? true : false;
	}
	public boolean isFull() {
		return this.top == this.maxiSize ? true : false;
	}
	public void push(int data) {
		this.top += 1;
		stack[this.top] = data;
	}
	public int pop() {
		int data = stack[this.top];
		this.top -= 1;
		return data;
	}
	public int getSize() {
		return this.top + 1;
	}
}
</pre>

栈的应用:

1.逆序输出:

a.进制转换: sysConvert(num,b)将num转换成b进制的数

<pre>
private static void sysConvert(int num, int b ) {
	int stackCapacity = 100;
	StackArray stack = new StackArray(stackCapacity);
	while (num != 0) {
		int x = num % b;
		num = num / b;
		stack.push(x);
	}
	stack.traverse();
}
</pre>

b.括号匹配:判断一个表示的括号是否匹配,主要思路如下:遇到(则进栈,遇到)则出栈。若最后栈中为空,则符号匹配;否则括号失配
在这里插入图片描述
在这里插入图片描述
2.递归嵌套:具有自相似性的问题可递归描述,但分支位置和递归深度不确定
a.栈混洗:栈混洗满足的条件是如果原栈中存在一组数据为i<j<k(为距离栈顶的距离),那么栈混洗后不可能出现j>k>i
3.延迟缓冲:线性扫描算法的描述中,在预读取足够长后,方能确定可以处理的前缀

a.中缀表达式:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1)search(a, b):给定当前运算符a,和符号栈运算符b,返回a,b之间的优先级。b > a表示当前运算符优先级更高,此时应该执行运算符b。

<pre>
public static char search(char a, char b) {
	char[] notationArr = {
		//  |--------当前运算符-------------|
		//	        +    -    *    /    ^    !    (    )   \0
		/* || + */ '>', '>', '<', '<', '<', '<', '<', '>', '>',
		/* || - */ '>', '>', '<', '<', '<', '<', '<', '>', '>',
		/* 栈   * */ '>', '>', '>', '>', '<', '<', '<', '>', '>',
		/* 顶   / */ '>', '>', '>', '>', '<', '<', '<', '>', '>',
		/* 运   ^ */ '>', '>', '>', '>', '>', '<', '<', '>', '>',
		/* 算   ! */ '>', '>', '>', '>', '>', '>', ' ', '>', '>',
		/* 符   ( */ '<', '<', '<', '<', '<', '<', '<', '=', ' ',
		/* || ) */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
		/* || \0*/ '<', '<', '<', '<', '<', '<', '<', ' ', '=',
	};
	char[] curNotation = {'+', '-', '*', '/', '^','!', '(', ')', '\0'};
	int i = 0;
	int j = 0;
	for (int k = 0; k < curNotation.length; k++) {
		if (a == curNotation[k]) {
			i = k;
			break;
		}
	}
	for (int k = 0; k < curNotation.length; k++) {
		if (b == curNotation[k]) {
			j = k;
			break;
		}
	}
	return notationArr[i+9*j];
}
</pre>

2)getResult(data1,data2,nota):给定计算nota,和数据data1和data2计算结果并返回

<pre>
public static int getResult(int data1, int data2, char nota) {
	int sum = 0;
	switch (nota) {
	case '+':
		sum = data1 + data2;
		break;
	case '-':
		sum = data1 - data2;
		break;
	case '*':
		sum = data1 * data2;
		break;
	case '/':
		sum = data1 / data2;
		break;
	case '^':
		sum = data1^data2;
		break;
	}
return sum;
}
</pre>

3).infixNotation(str,length)给定一个中缀表达式str和表达式长度length,计算表达式的值

<pre>
public static int infixNotation(String str, int length) {
	int i = 0;
	IntStackArray intStack = new IntStackArray(100);
	CharStackArray charStack = new CharStackArray(100);
	while(i < length) {
		char a = str.charAt(i);
		if ('0' <= a && a <= '9') {
			int data = a - '0';
			intStack.push(data);
		}else {
			boolean flag = true;
			while(flag) {
				if (charStack.isEmpty()) {
					charStack.push(a);
					break;
				}
				char notati = search(a, charStack.getTopData());
				switch (notati) {
				case '<':
					charStack.push(a);
					flag = false;
					break;
				case '=':
					char not = charStack.pop();
					flag = false;
					break;
				case '>':
					char nota = charStack.pop();
					if (nota =='!') {
						int data2 = intStack.pop();
						int sum = 1;
						for (int j = 1; j <= data2; j++) {
							sum *= j;
						}
						intStack.push(sum);
					}else {
						int data2 = intStack.pop();
						int data1 = intStack.pop();
						intStack.push(getResult(data1, data2, nota));
					}
					break;
				}
			}
		}
		i++;	
	}
	while (!charStack.isEmpty()) {
		int data2 = intStack.pop();
		int data1 = intStack.pop();
		char nota = charStack.pop();
		intStack.push(getResult(data1, data2, nota));
	}
	return intStack.getTopData();
}
</pre>

4).测试:

<pre>
public static void main(String[] args) {
	String notation = "(4+2)*(3-8)/5";
	int length = notation.length();
	int a = infixNotation(notation, length);
	System.out.println(a);	
}
</pre>

4.栈式计算:基于栈结构的特定计算模式

a.逆波兰表达式:

1)从逆波兰表达式到中缀表达式:
在这里插入图片描述
在这里插入图片描述

<pre>
public static char[] infixNotation(String str, int length) {
	int i = 0;
	char[] postfix = new char[length];
	IntStackArray intStack = new IntStackArray(100);
	CharStackArray charStack = new CharStackArray(100);
	while(i < length) {
		char a = str.charAt(i);
		if ('0' <= a && a <= '9') {
			int data = a - '0';
			intStack.push(data);
			postfix[i] = a;      //计算出中缀表达式
		}else {
			boolean flag = true;
			while(flag) {
				if (charStack.isEmpty()) {
					charStack.push(a);
					break;
				}
				char notati = search(a, charStack.getTopData());
				switch (notati) {
				case '<':
					charStack.push(a);
					flag = false;
					break;
				case '=':
					char not = charStack.pop();
					flag = false;
					break;
				case '>':
					char nota = charStack.pop();
					postfix[i] = nota;   //计算出中缀表达式
					if (nota =='!') {
						int data2 = intStack.pop();
						int sum = 1;
						for (int j = 1; j <= data2; j++) {
							sum *= j;
						}
						intStack.push(sum);
					}else {
				  		int data2 = intStack.pop();
						int data1 = intStack.pop();
						intStack.push(getResult(data1, data2, nota));
					}
					break;
				}
			}
		}
		i++;	
	}
	while (!charStack.isEmpty()) {
		int data2 = intStack.pop();
		int data1 = intStack.pop();
		char nota = charStack.pop();
		intStack.push(getResult(data1, data2, nota));
	}
	return postfix;	
}
					break;
				}
			}
		}
		i++;	
	}
	while (!charStack.isEmpty()) {
		int data2 = intStack.pop();
		int data1 = intStack.pop();
		char nota = charStack.pop();
		intStack.push(getResult(data1, data2, nota));
	}
	return postfix;	
}
</pre>
发布了14 篇原创文章 · 获赞 0 · 访问量 1852

猜你喜欢

转载自blog.csdn.net/dfjaadada/article/details/103930550