首页 > 编程语言 >C语言逆波兰式算法

C语言逆波兰式算法

时间:2024-01-05 19:11:32浏览次数:45  
标签:shuchu vIndex ++ C语言 shuru scIndex 算法 波兰 opIndex

  1 #include <stdio.h>
  2 
  3 //数字模式识别 
  4 #define IS_NUM(c)    (((c)>='0') && ((c)<='9') || ((c)=='.'))
  5 //符号字符识别 
  6 #define IS_OPERATOR(c) (((c)=='+') || ((c)=='-') || ((c)=='*') || ((c)=='/') || ((c)=='('))
  7 //加减符号识别 
  8 #define IS_AS(c) (((c)=='+') || ((c)=='-'))
  9 //乘除符号识别 
 10 #define IS_MD(c) (((c)=='*') || ((c)=='/'))
 11 
 12 
 13 //逆波兰式 识别原则
 14 //1、遇见数字直接压入输出数组里边;
 15 //2、遇见乘除符号,则先把前边紧跟着的所有乘除符号逆序弹出到输出数组中 ,然后把当前的符号压入符号栈;
 16 //3、遇见加减号,则把最近前括号“(”之后的的所有符号全部弹出到输出数组中,然后压入当前符号;
 17 //4、每次遇见任何符号,都表明之前的数据识别完成,这里需要添加空格用来区分两个数据
 18 //5、如果算式刚开始或者其他符号之后出现“-”,这这个符号会被识别成符号,
 19 //   负数标志位置1,先在输出数组中压入0和空格,且在后边数据识别完成之后,直接添加“-”,用0-x的方式实现负数 
 20 //6、如果遇见前括号“(” 则直接压入符号栈;如果遇见后括号“)”,则把最近的前括号之后所有的符号逆序弹出到输出数组;
 21 //7、原式子识别完成之后,如果符号栈还有数据,则按照逆序分别弹出到输出数组中;
 22 //缺陷:没有进行括号匹配识别,也没有处理连续两个符号重新一块输入的bug,还有一个数据输入多个小数点的bug!!!!! 
 23  
 24 //例如 1.2+-42.8/2*(1*-2.56/(3-4))*(10/5+2.6)
 25 //a、根据原则1和原则3和原则4,输出数组:1.2(空格),符号栈:+
 26 //b、根据原则5、1、2,输出数组 1.2 0 42.8 - 2 符号栈:+ /
 27 //c、根据原则2,输出数组:1.2 0 42.8 - 2 /  符号栈:+ *
 28 //d、根据原则6,输出数组:1.2 0 42.8 - 2 /  符号栈:+ * (
 29 //e、根据原则1、2、3、4、5、6 输出数组:1.2 0 42.8 -2 /1 0 2.56 -*  符号栈:+ * (/(
 30 //f、根据原则1、3 输出数组:1.2 0 42.8 -2 /1 0 2.56 -*3 4 -  符号栈:+ * (/(
 31 //g、根据原则6  输出数组:1.2 0 42.8 -2 /1 0 2.56 -*3 4 -/  符号栈:+ * 
 32 //h、之前的原则,则后续结果1.2 0 42.8 -2 /1 0 2.56 -*3 4 -/*10 5 /2.6 +*+
 33 void RPN(char shuru[],char shuchu[]) {
 34     char i;    
 35     char scIndex     = 0;        //输出栈顶索引 
 36     char opera[20]    = {0};        //符号栈 
 37     char opIndex     = 0;        //符号栈顶索引 
 38     char fushu        = 0;        //负数标志位 
 39     char errNum        = OK;        //返回错误置 
 40     
 41     for(i=0;shuru[i]!='\0';i++) {
 42         if(IS_NUM(shuru[i])) {                //数据字符 
 43             shuchu[scIndex++] = shuru[i];    //把数组直接输出        
 44         } else     if(IS_MD(shuru[i])) {        //乘除字符 
 45             if(IS_NUM(shuchu[scIndex-1])) {    //添加空格来区分数据,如果是负数模式,则添加负号,下同 
 46                 shuchu[scIndex++] = ' ';    //添加数据分割的空格 
 47                 if(fushu==1) {                //负数模式 
 48                     shuchu[scIndex++] = '-';//把符号添加到结果中 
 49                     fushu=0;                //负数标志位清零 
 50                 }
 51             }            
 52             //如果是上一个字符是乘除则一个一个弹出来填充到结果中,
 53             //直到符号栈没有符号,或者遇见前括号“(”    
 54             while(IS_MD(opera[opIndex-1]) && (opIndex>0) ) {//&& (opera[opIndex-1]!='(')
 55                 shuchu[scIndex++] = opera[--opIndex];            
 56             }            
 57             opera[opIndex++] = shuru[i];    //填充当前符号到符号栈 
 58         } else if(IS_AS(shuru[i])) {        //如果是加减模式 
 59             if(IS_NUM(shuchu[scIndex-1])) {    //添加空格,区分负号,同上 
 60                 shuchu[scIndex++] = ' ';
 61                 if(fushu==1) {
 62                     shuchu[scIndex++] = '-';
 63                     fushu=0;
 64                 }
 65             }    
 66             //如果算式刚开始就是“-”,或者其他符号紧跟着“-”则这个减号起到负数所用 
 67             if((shuru[i]=='-') && ((scIndex==0) || (IS_OPERATOR(shuru[i-1])))) {
 68                 shuchu[scIndex++] = '0'; //先添加0 把负数处理成0-x的模式 
 69                 shuchu[scIndex++] = ' ';
 70                 fushu=1;                //负数标志位 
 71             } else {
 72                 while((opIndex>0) && (opera[opIndex-1]!='(')) {//把前括号之前的符号全部弹出 
 73                     shuchu[scIndex++] = opera[--opIndex];            
 74                 }    
 75                 opera[opIndex++] = shuru[i];//压入当前符号                
 76             }            
 77             
 78         } else if(shuru[i]=='(') {                 //如果是前括号  则直接压入括号 
 79             if(IS_NUM(shuchu[scIndex-1])) {        //添加空格,区分负号,同上 
 80                 shuchu[scIndex++] = ' ';
 81                 if(fushu==1) {
 82                     shuchu[scIndex++] = '-';
 83                     fushu=0;
 84                 }
 85             }    
 86             opera[opIndex++] = shuru[i];        //压入前括号 
 87         } else if(shuru[i]==')') {                //如果是后括号,则直接弹出前括号后边的所有符号 
 88             if(IS_NUM(shuchu[scIndex-1])) {
 89                 shuchu[scIndex++] = ' ';
 90                 if(fushu==1) {
 91                     shuchu[scIndex++] = '-';
 92                     fushu=0;
 93                 }
 94             }    
 95             while(opera[opIndex-1]!='(') {         //弹出前括号之后的所有符号 
 96                 shuchu[scIndex++] = opera[--opIndex];            
 97             }        
 98             opIndex--;                            //栈顶减1,剔除前括号 
 99         }
100     }
101     //puts(shuchu);    
102     while((opIndex>0)) {                        //如果循环之后符号栈还有数据,则逆序弹出 
103         shuchu[scIndex++] = opera[--opIndex];
104     }    
105 }
106 
107 //根据逆波兰式计算数据原则
108 //1、遇见数据进行数字识别,注意识别的时候有整数和小数模式,遇见空格,表明当前数据识别完成,识别完成的数据压入数据栈 ; 
109 //2、如果遇见符号,则按照顺序弹出两个数据,然后这两个数据按照顺序进行符号匹配的运算,结果压入数据栈; 
110 //3、所有数据计算完成之后,数据栈就留下唯一结果,就是最终结果 
111 //例如上边逆波兰式 1.2 0 42.8 -2 /1 0 2.56 -*3 4 -/*10 5 /2.6 +*+
112 //a、先压入1.2 0 42.8 ,当看见符号,则弹出42.8和0 ,然后计算0-42.8,把结果压入数据栈,1.2 -42.8 
113 //b、然后出现2,则先把2压入数据栈;
114 //c、遇见/,则弹出2和-42.8,计算-42.8/2结果为-21.4压入数据栈,结果为1.2 -21.4
115 //d、后边的数据以此类推 
116 float RPNOperation (char shuru[]) {        
117     char i;
118     float value[10]={0};    //数据和计算数据的栈 
119     char vIndex=0;        //数据栈顶索引 
120     char xs=0;            //小数标志位 
121     float xishu=0.1;    //小数系数 
122     float s0,s1;        //运算数据变量 
123     
124     
125     for(i=0;shuru[i] != '\0';i++) {         //遍历所有逆波兰式字符串 
126         if(IS_NUM(shuru[i])) {                //数字模式 
127             if(shuru[i]=='.') {                //如果判断小数点,则小数标志位置1 
128                 xs=1;
129             } else {                        //纯数字模式,则计算数据 
130                 if(xs==0) {                    //整数模式计算方法,a=a*10+b,其中a是上一次数据,b是当前数据 
131                     value[vIndex] = value[vIndex]*10 + (shuru[i]-'0');    
132                  } else if(xs==1){            //如果是小数模式,则每一个新数据都要倍一个小数系数 
133                      value[vIndex] += xishu*(shuru[i]-'0');
134                      xishu/=10;                //小数系数缩小到原来的十分之一,供下次使用 
135                  }
136             }              
137         } else if(shuru[i]==' ') {            //如果是空格,则表明上边的数据已经完结 
138             xs=0;                            //小数标志位清零 
139             vIndex++;                         //数据栈加1 
140             xishu=0.1;                        //小数系数恢复到0.1 
141         } else if(IS_OPERATOR(shuru[i])) {    //如果遇见符号 
142             s0=value[--vIndex];                //弹出第一数据 
143             value[vIndex] = 0;                //原数据必须清零,否则,影响下一次数据识别 
144             s1=value[--vIndex];                //弹出第二个数据 
145             switch (shuru[i]){                //根据符号进行计算 
146                 case '+':value[vIndex]=s1+s0;break;
147                 case '-':value[vIndex]=s1-s0;break;
148                 case '*':value[vIndex]=s1*s0;break;
149                 case '/':value[vIndex]=s1/s0;break;
150             }
151             vIndex++;                         
152             xs=0;
153             xishu=0.1;
154         }
155     }
156     return value[0];                        //运算完成之后,栈里边只留下最终结果 
157 }
158 
159 main() {
160     //带带括号嵌套,带负数的运算式 
161     char shuru[]="1.2+-42.8/2*(1*-2.56/(3-4))*(10/5+2.6)";
162     //逆波兰式输出数组 
163     char shuchu[35]={0};
164     float v;                //最终结果 
165     RPN(shuru,shuchu);        //计算逆波兰式 
166     puts(shuchu);            //打印逆波兰式 
167     v=RPNOperation(shuchu);    //计算数据结果 
168     printf("%f",v);            //打印结果 
169 }

 

标签:shuchu,vIndex,++,C语言,shuru,scIndex,算法,波兰,opIndex
From: https://www.cnblogs.com/pengpai/p/17947886

相关文章

  • 2024年小红书最新x-s-common签名算法分析以及点赞api接口测试nodejs(2024-01-05)
      2024年小红书又更新了x-s-common算法,现在的版本是:3.6.8。这个签名算法现在是越来越重要了,许多接口都要用到。比如:评论,点赞等接口,没有这个算法采集不到数据。  一、chrome逆向x-s-common算法  1、x-s-common  打开chrome,按f12,打开开发者模式,随便找一接口,全局......
  • 经典算法之图形问题
    图形问题的万金解决方法就是创建一个二维数组,然后将填数组,最后打印数组就行了。其本质还是找出图形的规律。首先来找规律,先从外形上来找。奇数高,看图形,是上下左右对称的。所以只找上半区的规律。然后首行比其他行少两个字符也就是多两个空格,最外层都是A,数组可以提前都赋值。只......
  • C语言学习随笔-03 基本语法
    c语言程序由函数构成,每个函数可以实现一个或多个功能。 一个正规程序可以有多个函数,但是有且只有一个主函数。 函数只有在被调用的时候才执行,主函数由系统调用执行。 函数的格式必须按照规范书写。 C语言程序文件的后缀为.c1、C的令牌(Token):C程序由各种令牌组成,令牌可......
  • 排序算法
    冒泡排序思想:1、一个无序的数组,n个元素,一共需要排序n-1轮2、在每一轮中,从数组第0位开始,比较相邻两个元素,如果与需求逆序,就交换这两个元素,在每一轮中,可以将当前最大(最小)的元素交换到最后,3、直到执行完n-1轮,没有需要比较的元素为止。代码实现:publicstaticvoidbubSort(in......
  • 生物识别应用锁控二合一和三合一芯片的算法描述和特点
    主控集成电容触控按键(二合一),外接指纹模组方案特点•主控:采用集成TouchKey的芯片ACM32FP0•算法:采用金融级安全芯片ACH512/高性能算法芯片ACM32FP4•非接:采用A32NQ32C3读卡芯片•支持指纹、按键、钥匙、非接、蓝牙等多种开锁方式•指纹、密码安全存储、敏感信息不外泄•提供......
  • 在Python中,有几个库可以帮助我们自动寻找最适合的机器学习模型和参数。这里有两个主要
    在Python中,有几个库可以帮助我们自动寻找最适合的机器学习模型和参数。这里有两个主要的库:1.**lazypredict**¹:这个库可以快速地比较多种机器学习算法的性能,从而帮助我们选择最佳的算法。它可以在循环中迭代多个模型,这通常需要一些时间,但是使用lazypredict可以克服这个限制。下......
  • 【教3妹学编程-算法题】经营摩天轮的最大利润
    3妹:“打个中国结,再系个红腰带,愿善良的人们天天好运来,你勤劳生活美,你健康春常在,你一生的忙碌为了笑逐颜开。”2哥 :3妹,元旦快乐啊。3妹:2哥元旦快乐~。2哥:祝新的一年,3妹技术突飞猛进,工资涨涨涨。3妹:祝新的一年,2哥能够找到女朋友,哈哈哈......
  • Landsat 7地表温度计算:单窗算法的ENVI、ERDAS实现
    本文介绍基于ENVI与ERDAS软件,对Landsat7遥感影像数据加以单窗算法的地表温度(LST)反演操作。(基于ENVI与ERDAS的Landsat7ETM+单窗算法地表温度(LST)反演)1原理部分与前期操作准备首先说一个批量计算LST的方法——基于GEE的Landsat地表温度反演可以看谷歌地球引擎GEE批量计算Land......
  • 智能分析网关V4算法配置步骤2.0——睡岗检测
    AI智能分析网关V4是TSINGSEE青犀视频旗下的一款高效分析网关,可分别作为上级或下级平台进行级联,还可实现人体行为检测、车辆事件检测、环境卫生检测与消防事件检测等等,广泛应用在工地、工厂、园区、楼宇、校园、仓储等场景中。将智能分析网关V4结合我们的视频融合平台EasyCVR一起使......
  • 生物识别应用指纹的算法是什么样的?有什么性能?
    方案特点•采用金融级安全芯片ACH512的指纹模组,指纹和密码安全存储,云端数据安全传输•采用高性能指纹专用安全MCU芯片ACM32FP4,支持小点阵图像算法处理•支持80*64、88*112、96*96、160*160、192*192等像素传感器•已适配传感器厂家:FPC、比亚迪、贝特莱、芯启航、集创、迈瑞微......