数据结构我好爱:栈的应用 II--字符串表达式的计算

本文介绍了如何利用栈实现字符串表达式的计算,特别关注了括号匹配、运算符优先级处理以及栈的使用技巧。通过实例演示了如何解析表达式并进行局部计算,确保了正确的运算顺序和结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串表达式的计算:栈的使用是其中的基础,其核心是正确分析出程序进行逻辑;

其中需要注意的问题: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;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值