首页 > 其他分享 >Stack----带优先级的四则运算

Stack----带优先级的四则运算

时间:2024-06-02 21:59:02浏览次数:24  
标签:index 优先级 top pop stack ---- operator return Stack

Infix to postfix conversion

1.operand ---> output ; 

2.operator ---> 1) pop and output all operators >= precedence ;  (弹出优先级大的所有操作符)

                 ---> 2) push the operator ;

3."(" ---> push;

4.")" ---> 1)pop all oporators until "(" ;   (弹出"("之上的所有操作符)

        ---> 2)  pop the ")" without output ;

5. No more ---> pop and output all;

Postfix Calculator

1.operator ---> pop two operant off ,push result ;

2.operand ---> push on stack;

代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

typedef struct {
	char *operator;
	double *operand;
	int top;
	int size;
}stack;

void init_stack(stack *s){
	s->size = 100;
	s->operator = (char*)malloc(sizeof(char) * s->size);
	s->operand = (double*)malloc(sizeof(double) * s->size);
	s->top = -1;//空栈
}

void free_stack(stack* s) {
	if (s != NULL) {
		if (s->operator != NULL) {
			free(s->operator); 
			s->operator = NULL; 
		}
		if (s->operand != NULL) {
			free(s->operand); 
			s->operand = NULL; 
		}
		s->top = -1;
	}
}

int is_empty(stack* s) {
	if (s->top == -1)
		return 1; //为空
	else
		return 0; //不为空
}

int is_full(stack* s) {
	if (s->top == s->size - 1)
		return 1;  //栈满
	else
		return 0;  //栈未满
}

void push_stackR(stack* s, char op) {
	if (is_full(s)) {
		printf("\nThe stack is full!\n");
	}
	else {
		s->top++;
		s->operator[s->top] = op;
	}
}

char pop_stackR(stack* s) {
	if (is_empty(s)) {
		printf("\nThe stack is empty!\n");
		exit(1);  //退出程序
	}
	else {
		s->top--;
		return s->operator[s->top + 1];
	}
}

void push_stackD(stack* s, double op) {
	if (is_full(s)) {
		printf("\nThe stack is full!\n");
	}
	else {
		s->top++;
		s->operand[s->top] = op;
	}
}

double pop_stackD(stack* s) {
	if (is_empty(s)) {
		printf("\nThe stack is empty!\n");
	}
	else {
		s->top--;
		return s->operand[s->top + 1];
	}
}

char top_stack(stack* s) {
	if (is_empty(s)) {
		printf("The stack is empty!\n");
	}
	else {
		return s->operator[s->top];   //返回栈顶元素
	}
}

double top_stackD(stack* s) {
	if (is_empty(s)) {
		printf("The stack is empty!\n");
	}
	else {
		return s->operand[s->top];   //返回栈顶元素
	}
}

int is_operator(char operator) {
	switch (operator)
	{
	case '+':
	case '-':
		return 1; break;
	case '*':
	case '/':
		return 2; break;
	default:
		return 0; break;
	}
}

double calculate(double a, double b, char op) {
	switch (op) {
	case '+':
		return a + b; break;
	case '-':
		return a - b; break;
	case'*':
		return a * b; break;
	case '/':
		return a / b; break;
	default:
		printf("Invalid operator!\n");
	}
}

// Infix to postfix conversion
char* to_postfix(char exp[]) {
	stack s;
	init_stack(&s);
	char pexp[100];
	int i,index=0;
	for (i = 0; i < strlen(exp); i++) {
		// 1.operand ---> output ; 
		if ((exp[i] >= '0' && exp[i] <= '9') || exp[i] == '.') {
			pexp[index] = exp[i];
			index++;
		}
		// 2.operator ---> pop and output all operators >= precedence ;  push the operator;
		else if (is_operator(exp[i])) {
			pexp[index] = ' ';
			index++;
			while (!is_empty(&s) && is_operator(top_stack(&s)) > is_operator(exp[i]))
			{
				pexp[index] = pop_stackR(&s);
				index++;
				pexp[index] = ' ';
				index++;
			}
			push_stackR(&s, exp[i]);
		}
		// 3."(" ---> push;
		else if (exp[i] == '('&&!is_full(&s)) {
			push_stackR(&s, exp[i]);
		}
		// 4.")" ---> pop all oporators until "(" ;  pop the ")" without output;
		else if (exp[i] == ')') {
			pexp[index] = ' ';
			index++;
			while (top_stack(&s) != '(') {
				pexp[index] = pop_stackR(&s);
				index++;
			}
			pop_stackR(&s);
		}
	}
	pexp[index] = ' ';
	index++;
	// 5. No more ---> pop and output all;
	while (!is_empty(&s)) {
		pexp[index] = pop_stackR(&s);
		index++;
		pexp[index] = ' ';
		index++;
	}
	pexp[index] = '\0';
	free_stack(&s);
	return pexp;
}

double is_digit(char* c) {
	int i = 0, hasPoint = 0;
	double num = 0.0, fac = 1.0;

	if (c[0] < '0' || c[0] > '9') {
		return 0;
	}
	else {
		for (i = 0; i < strlen(c); i++) {
			if (c[i] == '.') {
				hasPoint = 1;
				fac = 0.1;
			}
			else if (c[i] >= '0' && c[i] <= '9') {
				if (hasPoint) {
					num += (c[i] - '0') * fac;
					fac *= 0.1;
				}
				else {
					num = num * 10 + (c[i] - '0');
				}
			}
		}
	}
	return num;
}

double postfix_calculator(char* exp) {
	stack s;
	init_stack(&s);
	char ch[50];
	double num = 0, op1 = 0, op2 = 0, result = 0;
	int i, j, ch_len = 0; 
	for (i = 0; i < strlen(exp); i++) {
		/*printf("\n------------------------------\n");
		printf("exp[i]=%c , i=%d", exp[i],i);
		printf("\n------------------------------\n");*/
		ch_len = 0; // 重置ch的长度
		if (exp[i] >= '0' && exp[i] <= '9') {
			for (j = i; j < strlen(exp) && exp[j] != ' '; j++, ch_len++) {
				ch[ch_len] = exp[j];
			}
			ch[ch_len] = '\0'; // 添加字符串终止符
			i = j-1;
		}
		
		if (is_digit(ch)) {
			num = is_digit(ch);
		}
		if (num != 0 && exp[i]==' ') {
			//printf("\n********operand***********\n");
			push_stackD(&s, num);
			//printf("push_num:%.2f\n", top_stackD(&s));
			num = 0;
		}
		else if (is_operator(exp[i])) {
			//printf("\n########operator#########\n");
			num = 0;
			op2 = pop_stackD(&s);
			op1 = pop_stackD(&s);
			//printf("%.2f %.2f %c\n", op1, op2, exp[i]);
			result = calculate(op1, op2, exp[i]);
			//printf("result:%.2f\n", result);
			push_stackD(&s, result);
			i++;
		}
	}
	result = top_stackD(&s);
	free_stack(&s);
	return result;
}

void test() {
	char exp[100], * pexp, pexp1[100];
	double result = 0, result2 = 0, result1 = 0;
	printf("请输入表达式:");
	scanf("%s",exp);
	pexp = to_postfix(exp);
	printf("\n该表达式的后缀形式为:%s\n", pexp);
	strcpy(pexp1, pexp);
	result = postfix_calculator(pexp1);
	printf("该表达式的结果为:%.2f\n", result);
}

int main() {
	test();
	return 0;
}


//   3+2*(3-1.5)-5/2    3.5
//   5+15*(4.5-(7/2))-6*(3/2)     11   

结果展示

参考资料

http://t.csdnimg.cn/BeRHx   【栈(stack) C语言实现 详解】

http://t.csdnimg.cn/pNxPS   【C语言实现栈(Stack)数据结构】

http://t.csdnimg.cn/GCcH3  【四则运算表达式求值(支持括号、负数)】

标签:index,优先级,top,pop,stack,----,operator,return,Stack
From: https://blog.csdn.net/m0_74219898/article/details/139294104

相关文章

  • Leetcode 3171. Find Subarray With Bitwise AND Closest to K
    Leetcode3171.FindSubarrayWithBitwiseANDClosesttoK1.解题思路2.代码实现题目链接:3171.FindSubarrayWithBitwiseANDClosesttoK1.解题思路这道题坦率地说让我感觉很挫败,又一次没有自力搞定,是看了大佬们的答案才搞定的……知道比没有搞定更难受的......
  • 为师妹写的《Java并发编程之线程池十八问》被表扬啦!
    写在开头  之前给一个大四正在找工作的学妹发了自己总结的关于Java并发中线程池的面试题集,总共18题,将之取名为《Java并发编程之线程池十八问》,今天聊天时受了学妹的夸赞,心里很开心,毕竟自己整理的东西对别人起到了一点帮助,记录一下!Java并发编程之线程池十八问  经......
  • React(五)UseEffect、UseRef
    (一)useEffectuseEffect–React中文文档 useEffecthook用于模拟以前的class组件的生命周期,但比原本的生命周期有着更强大的功能1.类组件的生命周期在类组件编程时,网络请求,订阅等操作都是在生命周期中完成importReact,{Component}from'react'exportdefaultc......
  • 面试官:说一说如何优雅的关闭线程池,我:shutdownNow,面试官:粗鲁!
    写在开头面试官:“小伙子,线程池使用过吗,来聊一聊它吧!”我:“好的,然后巴拉巴拉一顿输出之前看过的build哥线程池十八问…”面试官满意的点了点头,紧接着问道:“那你知道如何优雅的关闭线程池吗?”我:“知道知道,直接调用shutdownNow()方法就好了呀!”面试官脸色一变,微怒道:“粗......
  • 每天写两道(四)最大子数组和、手撕快排
    53.最大子数组和.-力扣(LeetCode)给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。示例1:输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组 [4,-1,2,1]的和最大,为 6。......
  • 线程创建的函数及应用小结
    进程是计算机分配资源的基本单位,线程是cpu调度的基本单位线程基本概念:LWP:lightweightprocess轻量级的进程。创建线程的底层函数和进程一样,都是clone,因此线程的本质仍是进程(在linux环境下)与进程相比,线程有独立的TCB结构体(类似于进程的PCB),但没有独立的地址空间(共享),类似于合租......
  • 创建医疗知识图谱:导入数据
    将 的代码修改成这样:#!/usr/bin/envpython3#coding:utf-8#File:MedicalGraph.py#Author:lhy<[email protected],https://huangyong.github.io>#Date:18-10-3#-*-coding:utf-8-*-importosimportjsonfrompy2neoimportGraph,NodeclassMedicalGr......
  • Topcoder SRM592-Div1-Lv2 LittleElephantAndPermutationDiv1
    题意设\(A,B\)为两个长为\(n\(\leq50)\)的排列,定义操作\(F(A,B)=\sum\limits_{i=1}^{n}\max(A_i,B_i)\),给定\(n,k\),求有多少种有序对\((A,B)\)满足\(F(A,B)\geqk\),答案模\(10^9+7\)。思路首先还是用经典的思路将无序转为无序,我们假定\(A\)是有序的即\(A={1,2,3,......
  • dbg修改EIP动调 [BJDCTF 2020]Easy
    教程多是patching,但是我下载错误(以后有时间再试试),那用dbg吧还有这道题蜜汁让我幻视pwn题目DieIDA主函数很好找,代码只是输出提示,没有其他东西了关键函数在其他地方 看看左边函数框 发现在main函数前面有一个名字一看就是自定义的函数ques这个函数在main函数之前运行......
  • 测试
    sssd简介SystemSecurityServicesDaemon(简称SSSD)是一种用于Linux和Unix系统的系统服务,它提供了身份验证、身份管理和访问控制等安全功能,可以将多个身份源(如本地LDAP、ActiveDirectory等)整合到一个单一的身份信息库中,简化系统管理员的身份管理任务。●sssd的主要功能包括:......