括号匹配算法

利用栈先进后出的特性,思路分三步:
1.遇到左括号,直接入栈,继续向后遍历;
2.遇到右括号,
(1).如果栈为空,说明无对应左括号,则返回表达式不匹配;
(2).如果栈不为为空,将栈顶元素弹出判断是否是相匹配的括号;
如果匹配,将栈顶元素弹出,继续遍历;如果不匹配,说明不是同类括号,直接返回表达式不匹配。
3.遍历到表达式末尾,如果栈中有剩余元素,说明存在多余左括号,返回表达式不匹配;如果栈为空,返回表达式匹配。
测试样例:

 //(56-20)/(4+2)//9 * (10 + 11 * (12 + 13)) + 14//(15 + 16) * (17 + 18 * (19 + 20)//((21 + 22) * 23 + (24 * 25)) + 26 * 27)) + 28 //{asdsd{ddads}sa}[]sassada[]sda{{aassaddsd[]}dsad}

完整程序实现如下:

#include<bits/stdc++.h>
using namespace std;bool judge(char str[]){stack<char> s;int n = strlen(str);for(int i = 0; i < n; i++){if(str[i]=='(') s.push(str[i]);//左括号入栈 if(str[i]=='[') s.push(str[i]);if(str[i]=='{') s.push(str[i]);if(str[i]==')'){if(s.empty()) return false;//无左括号不匹配 else if(s.top()=='(') s.pop();//匹配 else return false;//不是同类括号 }if(str[i]==']'){if(s.empty()) return false;else if(s.top()=='[') s.pop();else return false;}if(str[i]=='}'){if(s.empty()) return false;else if(s.top()=='{') s.pop();else return false;}}return s.empty();//空匹配 非空说明存在多余左括号
}
int main(){char str[10000];cin>>str; //(56-20)/(4+2)//9 * (10 + 11 * (12 + 13)) + 14//(15 + 16) * (17 + 18 * (19 + 20)//((21 + 22) * 23 + (24 * 25)) + 26 * 27)) + 28  //{asdsd{ddads}sa}[]sassada[]sda{{aassaddsd[]}dsad}bool v = judge(str);if(v) cout<<"匹配"<<endl;else cout<<"不匹配"<<endl;return 0;
}

简单计算器实现:设计一个计算器,实现加减乘除和小括号的计算。

设计思路:构建两个栈,一个压入要进行计算的数字,一个压入运算符,运算符涉及到优先级问题,括号>乘除>加减。遍历要计算的字符串,数字压入栈num,运算符压入栈s:
1.如果栈s为空,直接将运算符压入栈s;
2.如果栈s不为空,且栈顶运算符优先级大于等于待入栈运算符,将栈顶运算符弹出,从栈num弹出两个数字,进行运算,将计算结果压入栈num,直至栈空或栈顶运算符优先级小于待入栈运算符,将待入栈元素入栈;
3.如果栈s不为空,且栈顶运算符优先级小于待入栈运算符,直接将待入栈运算符入栈;
4.遇到左括号直接入栈,重复2,3步骤,遇到右括号时,若栈s栈顶运算符为左括号,直接将左括号弹出;若不为左括号,将运算符依次弹出进行运算,直至栈顶运算符为左括号,将其弹出。
5.字符串遍历完成后,若栈s为空,栈num栈顶元素即运算结果;栈s不为空,将运算符依次弹出进行计算。

涉及程序时,我们先写一个函数prio来返回运算符的优先级,加减返回1,乘除返回2,小括号返回3和4。

int prio(char ch){switch(ch){case '+':case '-':return 1;case '*':case '/':return 2;case'(':return 3;case ')':return 4;}
}

再写一个运算函数:

int cal(int a,int b,char ch){switch(ch){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;}
}

上述5步我们慢慢拆分:
首先是遍历字符串:

for(int i=0;i<n;i++)

数字入栈:

if('0'<=str[i]&&str[i]<='9'){x = x*10+(str[i]-'0'); v=1;
}
if(str[i]>'9'||str[i]<'0'||i==n-1){if(v==1){num.push(x);              //cout<<"push:"<<x<<endl;x=0;}v=0;
}

加v标记的原因是如果多个运算符相连,会导致压入不必要的数字0。
运算符入栈:

if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='('||str[i]==')'){

1.如果栈s为空,直接将运算符压入栈s;

if(s.empty()) s.push(str[i]);

2.如果栈s不为空,且栈顶运算符优先级大于等于待入栈运算符,将栈顶运算符弹出,从栈num弹出两个数字,进行运算,将计算结果压入栈num,直至栈空或栈顶运算符优先级小于待入栈运算符,将待入栈元素入栈;

while(!s.empty()&&prio(s.top())>=prio(str[i])&&s.top()!='('){int x2 = num.top();num.pop();int x1 = num.top();num.pop();char ch = s.top();s.pop();//cout<<x1<<ch<<x2<<" "<<cal(x1,x2,ch)<<endl;num.push(cal(x1,x2,ch));
}

3.如果栈s不为空,且栈顶运算符优先级小于待入栈运算符,直接将待入栈运算符入栈;

s.push(str[i]);

4.遇到左括号直接入栈,重复2,3步骤,遇到右括号时,若栈s栈顶运算符为左括号,直接将左括号弹出;若不为左括号,将运算符依次弹出进行运算,直至栈顶运算符为左括号,将其弹出。

if(str[i]=='('){s.push(str[i]);continue;
}
if(str[i]==')'){while(!s.empty()&&s.top()!='('){int x2 = num.top();num.pop();int x1 = num.top();num.pop();char ch = s.top();s.pop();//cout<<x1<<ch<<x2<<" "<<cal(x1,x2,ch)<<endl;num.push(cal(x1,x2,ch));}s.pop();continue;
}

5.字符串遍历完成后,若栈s为空,栈num栈顶元素即运算结果;栈s不为空,将运算符依次弹出进行计算。

while(!s.empty()){int x2 = num.top();num.pop();int x1 = num.top();num.pop();char ch = s.top();s.pop();//cout<<x1<<ch<<x2<<" "<<cal(x1,x2,ch)<<endl;num.push(cal(x1,x2,ch));
}
return num.top();

完整程序实现如下:

#include<bits/stdc++.h>
using namespace std;int prio(char ch){switch(ch){case '+':case '-':return 1;case '*':case '/':return 2;case'(':return 3;case ')':return 4;}
}int cal(int a,int b,char ch){switch(ch){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;}
}int calculation(char str[]){stack<char> s;stack<int> num;int n = strlen(str);int x = 0;//用于提出字符串数字 int v = 0;//用于判断何时将数字压入栈 for(int i=0;i<n;i++){//cout<<str[i]<<endl;if('0'<=str[i]&&str[i]<='9'){x = x*10+(str[i]-'0'); v=1;}if(str[i]>'9'||str[i]<'0'||i==n-1){if(v==1){num.push(x);                //cout<<"push:"<<x<<endl;x=0;}v=0;}if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]=='('||str[i]==')'){if(str[i]=='('){s.push(str[i]);continue;}if(str[i]==')'){while(!s.empty()&&s.top()!='('){int x2 = num.top();num.pop();int x1 = num.top();num.pop();char ch = s.top();s.pop();//cout<<x1<<ch<<x2<<" "<<cal(x1,x2,ch)<<endl;num.push(cal(x1,x2,ch));}s.pop();continue;}if(s.empty()) s.push(str[i]);else {//cout<<s.top()<<" "<<str[i]<<endl;while(!s.empty()&&prio(s.top())>=prio(str[i])&&s.top()!='('){int x2 = num.top();num.pop();int x1 = num.top();num.pop();char ch = s.top();s.pop();//cout<<x1<<ch<<x2<<" "<<cal(x1,x2,ch)<<endl;num.push(cal(x1,x2,ch));}s.push(str[i]);}}}while(!s.empty()){int x2 = num.top();num.pop();int x1 = num.top();num.pop();char ch = s.top();s.pop();//cout<<x1<<ch<<x2<<" "<<cal(x1,x2,ch)<<endl;num.push(cal(x1,x2,ch));}return num.top();
}int main(){char str[10000];cin>>str; //(56-20)/(4+2)//9*(10+11*(12+13))+14//(15+16)*(17+18*(19+20))//(((21+22)*23+(24*25))+26*27)+28  //10+11*12/12+14-1+2*3*1-5/5*5-5-5-5*5/5*5/5//10+11-12/12+14-1+22/2*5int cnt = calculation(str);cout<<cnt;return 0;
}

也有想过对输入的字符串进行一个合法性的判断,括号匹配,正确的运算符,这两个判断可以简单实现,但下面这两种

1234-1234+-34
12+231*41-

感觉判断起来有些许繁琐,但不判断程序又显得不完美,小记录一下。多给给几组测试样例,因为是整数相除,所以尽量选择整除的数:

 //(56-20)/(4+2)//9*(10+11*(12+13))+14//(15+16)*(17+18*(19+20))//(((21+22)*23+(24*25))+26*27)+28  //10+11*12/12+14-1+2*3*1-5/5*5-5-5-5*5/5*5/5//10+133+(4+22)/2*5//10+11-12/12+14-1+22/2*5

有问题敬请大家指正。

括号匹配,实现简单计算器(加减乘除,小括号)相关推荐

  1. c语言括号匹配输出个数字,C程序括号匹配检查(带详细注释)

    编写一程序检查C源程序文件中{}.()等括号是否匹配,并输出第一个检测到的不匹配的括号及所对应括号所在的行号(程序中只有一个括号不匹配). 注意: 1.     除了括号可能不匹配外,输入的C源程序无 ...

  2. js进阶正则表达式10-分组-多行匹配-正则对象的属性(小括号作用:分组,将小括号里面的东西看成一个整体,因为量词只对前一个字符有效)(多行匹配:m)(属性使用:reg.global)...

    js进阶正则表达式10-分组-多行匹配-正则对象的属性(小括号作用:分组,将小括号里面的东西看成一个整体,因为量词只对前一个字符有效)(多行匹配:m)(属性使用:reg.global) 一.总结 1. ...

  3. 简单计算器——JavaScript小实例

    简单计算器--JavaScript小实例 先来看一下下我们要做的计算器(以iQOO neo5手机计算器为例): 这就是我们今天要做的计算器的模板,成品的样子会略有不同,但功能完善. 好,当我们看到这个 ...

  4. 字符串括号匹配c语言,数据结构C语言括号的检验源程序 , 数据结构(C) 请用类C语言实现括号匹配的检验这个算法...

    问题标题 数据结构C语言括号的检验源程序 , 数据结构(C) 请用类C语言实现括号匹配的检验这个算法 2019-8-21来自ip:13.149.196.77的网友咨询 浏览量:270 手机版 问题补充 ...

  5. python括号匹配问题_支持通配符的括号匹配问题源码+详细流程代码(python)

    问题: 判断一个有左括号和右括号.以及其他ASCII字符组成的表达式是合法. 判断条件是左括号-右括号数目.次序配对,可多层嵌套.如果有*,则*可作为0个或者1个右括号,如果匹配则输出ok,不匹配则输 ...

  6. 判断括号匹配的程序java_java判断左右括号匹配

    java判断左右括号匹配 [2021-02-10 16:36:55]  简介: Java进行正则表达式匹配的方法:首先打开eclipse软件:然后运用d来进行数字的匹配,如果字符串中遇到了空白字符的话 ...

  7. python实现简单计算器加减乘除功能_Python3实现简单加减乘除运算的计算器

    这是用Python3编写的一个简易的计算器,只有加减乘除,没有括号. 个人思路:将公式以字符串形式传入: 1.去掉其中的空格,生成新的字符串进行操作: 2.提取其中的数字和运算符号分别生产新的列表: ...

  8. C程序括号匹配检查(带详细注释)

    编写一程序检查C源程序文件中{}.()等括号是否匹配,并输出第一个检测到的不匹配的括号及所对应括号所在的行号(程序中只有一个括号不匹配). 注意: 1.     除了括号可能不匹配外,输入的C源程序无 ...

  9. 第11.16节 Python正则元字符“()”(小括号)与组(group)匹配模式

    一. 什么是组 关于组匹配模式,Python官网上说得比较简单,也没有这个名词,只有组这个名词,老猿查了比较多的资料和做了相关测试之后才理解. 组匹配模式,就是在匹配的正则表达式中使用小括号" ...

最新文章

  1. Python中使用数据库SQLite
  2. iframe 内嵌第三方网站 cookie 失效,解决办法
  3. Kali Linux 安全渗透教程第六更1.4.2 安装至USB驱动器Kali Linux
  4. mysql C语言API接口及实例
  5. SpringBoot+MySql+ElementUI实现一对多的数据库的设计以及增删改查的实现
  6. 《阿里巴巴Android开发手册》v1.0.1更新,优化部分内容和示例代码
  7. 学校计算机房 作文,第一次去机房作文
  8. C#捕获控制台(console)关闭事件
  9. php pop3,php使用smtp,pop3协议收发邮件代码
  10. Ubuntu各个版本的介绍
  11. atlas 力矩计算_Atlas 2.1.0 实践(2)—— 安装Atlas
  12. matlab求单自由度振动方程为,matlab求解振动方程
  13. 码农小汪-Java Condition
  14. 一个北大毕业生决定去送外卖
  15. 自动化测试和软件测试的区别,自动化测试和手动测试之间的区别
  16. 前端(五)DOM 文档对象模型
  17. 食物链 (种类并查集)
  18. C# Action 使用
  19. 实话实说 —— 心理模型vs实现模型
  20. 腾讯安全与青藤云安全联合发布“天眼云镜”主机安全产品

热门文章

  1. 最全数据集网站汇总,绝对是一个金矿请查收!
  2. Netty空闲检测之写空闲
  3. 条码枪扫码时,只能在文本框录入一位字符的问题
  4. YOLOv3使用笔记
  5. 从CPU架构--x86架构和arm架构处理器--功耗
  6. 卡片互动悬停下载动画
  7. 天勤python_天勤量化
  8. linux find返回数据不一样,Linux学习笔记——find命令
  9. 仿泡团影视网源码 苹果cmsV8版本 电脑端+影视模块
  10. 网格背景教师公开课教学课件PPT模板