字符串表达式的计算:栈的使用是其中的基础,其核心是正确分析出程序进行逻辑;
其中需要注意的问题:1.读到右括号需要计算到左括号;
2.优先级问题,先乘除后加减
栈的基本操作:初始化,压栈,弹栈就不赘述了。
对于字符串表达式的计算:有一个注意就是要创建两个栈,一个存放运算符号,一个存储数字。
判定数字:pass
int isNumber(char c) {
if (c >= '0' && c <= '9') return 1;
return 0;
}
局部计算:
1.当进行局部计算时,对于栈顶为左括号,直接弹出再进行计算
2.取出一个运算符,两个运算数,注意数字顺序
3.将计算结构压回数字栈
void cal_loc(stackPtr head) {
if (head->dataC[head->topC] == '(') {
popC(head);
return;
}
printf("int:");
PrintI(head);
putchar('\n');
printf("char:");
PrintC(head);
putchar('\n');
int a = popI(head);
int b = popI(head);
char c = popC(head);
printf("c==%c ", c);
int res = 0;
switch (c) {
case'*':
res = a * b;
break;
case'/':
res = (double)b / a;
break;
case'+':
res = a + b;
break;
case'-':
res = b - a;
break;
}
pushI(head, res);
printf("res = %d a=%d ,b=%d\n", res, a, b);
}
主体计算函数:
1.判断数字,还得注意是非个位数的情况;并且因为优先级的问题以及栈空只剩下一个运算符的情况,我们直接判断,对于优先级:*或/直接进行计算,对于加减就交给读到右侧括号的while来进行计算。与凡老师代码不同,优先级的判断交给后边数字。
(举栗子:当出现(1+2*3)的情况,要计算*,但是得先读入后边的3才可以计算,剩下(1+6)就交给后边‘)’的判断while来计算,所以将数字存入之后再判断优先级才是明智之举。
2.对于符号:‘(、 ‘+、-、*、/’ 直接压栈
‘)’ 标志着进行一轮计算,注意要使用while,否则计算不彻底
int calculate(stackPtr head,char* str) {
for (int i = 0; i < strlen(str);i++ ) {
char temp = str[i];
if (isNumber(temp)) {
int j = i;
int sum = 0;
while (isNumber(str[j]) && j<strlen(str)) {
sum = sum * 10 + str[j] - '0';
j++;
}
i = j-1;
pushI(head, sum);
if (head->dataC[head->topC] == '*' || head->dataC[head->topC] == '/') cal_loc(head);
else if (head->topC == -1 && head->topI!=0) cal_loc(head);//有可能直接先只压一个数字。
}
else {
switch (temp) {
case'(':
pushC(head, temp);
break;
case')':
while(head->dataC[head->topC]!='(' && head->topI!=0) cal_loc(head);
popC(head);
break;
case '*':
pushC(head, temp);
break;
case '/':
pushC(head, temp);
break;
case'+':
pushC(head, temp);
break;
case'-':
pushC(head, temp);
break;
}
}
}
if (head->topC != -1) cal_loc(head);
return popI(head);
}
运行截图:
完整代码:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct {
char dataC[20];
int dataI[20];
int topC,topI;
}*stackPtr, stack;
stackPtr InitStack() {
stackPtr head = (stackPtr)malloc(sizeof(stack));
head->topC = -1;
head->topI = -1;
return head;
}
void pushC(stackPtr head, char c) {
if (head->topC >= 18) {
printf("no space");
return;
}
head->topC++;
head->dataC[head->topC] = c;
}
char popC(stackPtr head) {
char tempchar = head->dataC[head->topC];
head->topC--;
return tempchar;
}
void pushI(stackPtr head, int c) {
if (head->topI >= 18) {
printf("no space");
return;
}
head->topI++;
head->dataI[head->topI] = c;
}
int popI(stackPtr head) {
int tempint = head->dataI[head->topI];
head->topI--;
return tempint;
}
int isNumber(char c) {
if (c >= '0' && c <= '9') return 1;
return 0;
}
void PrintC(stackPtr head) {
if (head->topC == -1) return;
for (int i = head->topC; i >= 0; i--) {
printf("%c ", head->dataC[i]);
}
}
void PrintI(stackPtr head) {
if (head->topI == -1) return;
for (int i = head->topI; i >= 0; i--) {
printf("%d ", head->dataI[i]);
}
}
void cal_loc(stackPtr head) {
if (head->dataC[head->topC] == '(') {
popC(head);
return;
}
printf("int:");
PrintI(head);
putchar('\n');
printf("char:");
PrintC(head);
putchar('\n');
int a = popI(head);
int b = popI(head);
char c = popC(head);
printf("c==%c ", c);
int res = 0;
switch (c) {
case'*':
res = a * b;
break;
case'/':
res = (double)b / a;
break;
case'+':
res = a + b;
break;
case'-':
res = b - a;
break;
}
pushI(head, res);
printf("res = %d a=%d ,b=%d\n", res, a, b);
}
int calculate(stackPtr head,char* str) {
for (int i = 0; i < strlen(str);i++ ) {
char temp = str[i];
if (isNumber(temp)) {
int j = i;
int sum = 0;
while (isNumber(str[j]) && j<strlen(str)) {
sum = sum * 10 + str[j] - '0';
j++;
}
i = j-1;
pushI(head, sum);
if (head->dataC[head->topC] == '*' || head->dataC[head->topC] == '/') cal_loc(head);
else if (head->topC == -1 && head->topI!=0) cal_loc(head);
}
else {
switch (temp) {
case'(':
pushC(head, temp);
break;
case')':
while(head->dataC[head->topC]!='(' && head->topI!=0) cal_loc(head);
popC(head);
break;
case '*':
pushC(head, temp);
break;
case '/':
pushC(head, temp);
break;
case'+':
pushC(head, temp);
break;
case'-':
pushC(head, temp);
break;
}
}
}
if (head->topC != -1) cal_loc(head);
return popI(head);
}
void Test() {
stackPtr head = InitStack(head);
char* tempExpression = "(21+2-1)*6";
printf("result = %d ", calculate(head, tempExpression));
}
int main() {
Test();
return 0;
}