棧
構造一個棧類
<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>