栈
构造一个栈类
<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>