定义节点
typedef struct CharStack
{
int top;
int data[MAXSIZE];
}*CharStackPtr;
栈的初始化
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top = -1;
return resultPtr;
}
入栈
void push(CharStackPtr paraStackPtr, int paraValue)
{
// Step 1. Space check.
if (paraStackPtr->top >= MAXSIZE - 1)
{
printf("Cannot push element: stack full.\r\n");
return;
}//Of if
// Step 2. Update the top.
paraStackPtr->top ++;
// Step 3. Push element.
paraStackPtr->data[paraStackPtr->top] = paraValue;
}// Of push
出栈
char pop(CharStackPtr paraStackPtr)
{
// Step 1. Space check.
if(paraStackPtr->top < 0)
{
printf("Cannot pop element: stack empty.\r\n");
return '\0';
}
// Step 2. Update the top.
paraStackPtr->top --;
// Step 3. Push element.
return paraStackPtr->data[paraStackPtr->top + 1];
}
栈中的括号匹配
bool bracketMatching(char* paraString, int paraLength) {
CharStackPtr tempStack = charStackInit();
push(tempStack, '#');//让#成为栈底比-1更加方便,因为有时-1会被判定为ture
char tempChar, tempPopedChar;
for (int i = 0; i < paraLength; i++) {
tempChar = paraString[i];
switch (tempChar) {
case '(':
case '[':
case '{':
push(tempStack, tempChar);
break;
case ')':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '(') {
return false;
} // Of if
break;
case ']':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '[') {
return false;
} // Of if
break;
case '}':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '{') {
return false;
} // Of if
break;
default:
// Do nothing.
break;
}// Of switch
} // Of for i
tempPopedChar = pop(tempStack);
if (tempPopedChar != '#') {
return false;
} // Of if
return true;
}// Of bracketMatching
总代码
#include <stdio.h>
#include <malloc.h>
#define STACK_MAX_SIZE 10
typedef struct CharStack {
int top;
int data[STACK_MAX_SIZE];
} *CharStackPtr;
void outputStack(CharStackPtr paraStack) {
for (int i = 0; i <= paraStack->top; i ++) {
printf("%c ", paraStack->data[i]);
}
printf("\r\n");
}
CharStackPtr charStackInit() {
CharStackPtr resultPtr = (CharStackPtr)malloc(sizeof(struct CharStack));
resultPtr->top = -1;
return resultPtr;
}
void push(CharStackPtr paraStackPtr, int paraValue) {
if (paraStackPtr->top >= STACK_MAX_SIZE - 1) {
printf("Cannot push element: stack full.\r\n");
return;
}
paraStackPtr->top ++;
paraStackPtr->data[paraStackPtr->top] = paraValue;
}
char pop(CharStackPtr paraStackPtr) {
if (paraStackPtr->top < 0) {
printf("Cannot pop element: stack empty.\r\n");
return '\0';
}
paraStackPtr->top --;
return paraStackPtr->data[paraStackPtr->top + 1];
}
void pushPopTest() {
printf("---- pushPopTest begins. ----\r\n");
CharStackPtr tempStack = charStackInit();
printf("After initialization, the stack is: ");
outputStack(tempStack);
char ch;
for ( ch = 'a'; ch < 'm'; ch ++) {
printf("Pushing %c.\r\n", ch);
push(tempStack, ch);
outputStack(tempStack);
}
int i;
for ( i = 0; i < 3; i ++) {
ch = pop(tempStack);
printf("Pop %c.\r\n", ch);
outputStack(tempStack);
}
printf("---- pushPopTest ends. ----\r\n");
}
bool bracketMatching(char* paraString, int paraLength) {
CharStackPtr tempStack = charStackInit();
push(tempStack, '#');
char tempChar, tempPopedChar;
for (int i = 0; i < paraLength; i++) {
tempChar = paraString[i];
switch (tempChar) {
case '(':
case '[':
case '{':
push(tempStack, tempChar);
break;
case ')':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '(') {
return false;
}
break;
case ']':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '[') {
return false;
}
break;
case '}':
tempPopedChar = pop(tempStack);
if (tempPopedChar != '{') {
return false;
}
break;
default:
break;
}
}
tempPopedChar = pop(tempStack);
if (tempPopedChar != '#') {
return false;
}
return true;
}
/**
* Unit test.
*/
void bracketMatchingTest() {
char* tempExpression = "(()(";
bool tempMatch = bracketMatching(tempExpression, 17);
printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);
tempExpression = "( ) )";
tempMatch = bracketMatching(tempExpression, 6);
printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);
tempExpression = "()()(())";
tempMatch = bracketMatching(tempExpression, 8);
printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);
tempExpression = "({}[])";
tempMatch = bracketMatching(tempExpression, 6);
printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);
tempExpression = ")(";
tempMatch = bracketMatching(tempExpression, 2);
printf("Is the expression '%s' bracket matching? %d \r\n", tempExpression, tempMatch);
}// Of bracketMatchingTest
/**
The entrance.
*/
int main() {
pushPopTest();
bracketMatchingTest();
}// Of main
运行结果
---- pushPopTest begins. ----
After initialization, the stack is:
Pushing a.
a
Pushing b.
a b
Pushing c.
a b c
Pushing d.
a b c d
Pushing e.
a b c d e
Pushing f.
a b c d e f
Pushing g.
a b c d e f g
Pushing h.
a b c d e f g h
Pushing i.
a b c d e f g h i
Pushing j.
a b c d e f g h i j
Pushing k.
Cannot push element: stack full.
a b c d e f g h i j
Pushing l.
Cannot push element: stack full.
a b c d e f g h i j
Pop j.
a b c d e f g h i
Pop i.
a b c d e f g h
Pop h.
a b c d e f g
---- pushPopTest ends. ----
Is the expression '(()(' bracket matching? 0
Is the expression '( ) )' bracket matching? 0
Is the expression '()()(())' bracket matching? 1
Is the expression '({}[])' bracket matching? 1
Is the expression ')(' bracket matching? 0
二:表达式求值
我们首先建立两个栈,一个用于存放运算符,一个用于存放操作数
然后获取一个表达式,对表达式从左向右扫描,因为要符合算术运算先乘除后加减的运算规则,故并不是遇见一个运算符就可以进行运算,要与上一次遇见的运算符进行比较,优先级大的可以进行计算。
‘()’优先级最高,‘(’和‘)’优先级相同,故若优先级相同,则说明是括号
如果栈顶运算符和扫描到的运算符相同,则栈顶运算符优先级高。例如:栈顶运算符为‘+’,扫描到的运算符为‘+’或‘-’,则栈顶运算符优先级高
#include <stdio.h>
struct Sqstack {
int data[100];
int top;
};
char opset[10] = {'+', '-', '*', '/', '(', ')', '#'};
//用来进行比较运算符优先级的矩阵,3代表'=',2代表'>',1代表'<',0代表不可比
int cmp[7][7] = {
{ 2, 2, 1, 1, 1, 2, 2 },
{ 2, 2, 1, 1, 1, 2, 2 },
{ 2, 2, 2, 2, 1, 2, 2 },
{ 2, 2, 2, 2, 1, 2, 2 },
{ 1, 1, 1, 1, 1, 3, 0 },
{ 2, 2, 2, 2, 0, 2, 2 },
{ 1, 1, 1, 1, 1, 0, 3 } };
Sqstack Num;
Sqstack Oper;
void InitStack(Sqstack &s);//初始化栈
void Push(Sqstack &s, char ch);//入栈
char GetTop(Sqstack &s);//获取栈顶元素的值
int In(char ch, char operArr[10]);//判断是否为运算符
int Cal();
int Pop (Sqstack &s, char &x);//出栈
char Compare(char oper1, char oper2);
int Count(int x1, char op, int x2);
void InitStack(Sqstack &s) {
s.top = -1;
}
void Push(Sqstack &s, char ch) {
if(s.top == 99) {//栈满
return ;
}
s.top++;
s.data[s.top] = ch;
return ;
}
char GetTop(Sqstack &s) {
if(s.top == -1) {
return 0;
}
char ch;
ch = s.data[s.top];
return ch;
}
int Pop(Sqstack &s, char &x) {
if(s.top == -1)
return 0;
x = s.data[s.top];
--(s.top);
return 1;
}
int In(char ch, char operArr[10]) {
for(int i = 0; i < 7; i++) {
if(ch == operArr[i]) {
return 1;
}
}
return 0;
}
char Compare(char oper1, char oper2) {
int m = 0, n = 0, i, ans;
char ch;
for(i = 0; i < 7; i++) {
if(oper1 == opset[i]) {
m = i;
}
if(oper2 == opset[i]) {
n = i;
}
}
ans = cmp[m][n];
switch (ans) {
case 2:
return (char)('<');
case 1:
return (char)('>');
case 3:
return (char)('=');
default:
printf("表达式错误!\n");
break;
}
}
int Count(int x1, char op, int x2) {
int val;
switch(op) {
case '+': val = x1 + x2; break;
case '-': val = x1 - x2; break;
case '*': val = x1 * x2; break;
case '/': val = x1 / x2; break;
}
return val;
}
int Cal() {
char ch, x, op, a1, a2, val;
int data, ans;
InitStack(Num);//初始化操作数栈
InitStack(Oper);//初始化运算符栈
Push(Oper, '#');//在运算符栈中加入终止符为了进行比较,结束运算
printf("请输入一个表达式:\n");
ch = getchar();
while(ch != '#' || GetTop(Oper) != '#') {
//opset为运算符集合
if(!In(ch, opset)) {//如果读入的是操作数
data = ch - '0';
ch = getchar();
while(!In(ch, opset)){//读入的不是运算符,是操作数
data = data * 10 + ch - '0';//读入操作数的各位数码,并转化为十进制数data
ch = getchar();
}
Push(Num, data);//操作数入栈
} else {
switch(Compare(GetTop(Oper), ch)) {
case '>':
Push(Oper, ch);
ch = getchar();
break;
case '=':
Pop(Oper, x);
ch = getchar();
break;
case '<':
Pop(Oper, op);
Pop(Num, a2);
Pop(Num, a1);
val = Count(a1, op, a2);
Push(Num, val);
break;
}
}
}
val = GetTop(Num);
return val;
}
int main() {
int answer;
answer = Cal();
printf("%d", answer);
}
运行结果
请输入一个表达式:
3*(5+7)-8#
-114