棧--中綴表達式與逆波蘭表達式

構造一個棧類

<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>
發佈了11 篇原創文章 · 獲贊 0 · 訪問量 1763
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章