每日一题(五):栈的基础应用
日期: 2019-01-20 分类: 个人收藏 353次阅读
1.
题目描述:
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注.
输入:
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。
注意:cin.getline(str,100)最多只能输入99个字符!
输出:
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,"$"和"?"表示与之对应的左括号和右括号不能匹配。
样例输入:
)(rttyy())sss)(
样例输出:
)(rttyy())sss)(
? ?$
#include<iostream>
#include<stack>
using namespace std;
stack<int> S;
char str[110];
char ans[110];
int main() {
while (scanf("%s", str) != EOF) {
int i;
for (i = 0; str[i] != 0; i++) {
if (str[i] == '(') {
S.push(i);
ans[i] = ' ';
}
else if (str[i] == ')') {
if (S.empty() == false){
S.pop();
ans[i] = ' ';
}
else ans[i] = '?';
}
else ans[i] = ' ';
}
while (!S.empty()) {
ans[S.top()] = '$';
S.pop();
}
ans[i] = 0; //输出形成字符串,在其最后一个字符后添加一个空字符
puts(str); //输出原字符串
puts(ans); //输出答案字符串
}
return 0;
}
题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入
30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0
样例输出
12178.21
#include<stack>
#include<stdio.h>
using namespace std;
char str[220];
int mat[][5] = {
//优先级矩阵,若mat[i][j]==1,则表示i号运算符优先级大于j号运算符
//运算符编码规则+为1号,-为2号,*为3号,/为4号
//人为添加在表达式首尾的标记运算符为0号
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0,
};
stack<int> op;
stack<double>in;
void getOp(bool &reto,int &retn,int &i) {
//reto为true表示是运算符,反之为数字
if (i==0&&op.empty()==true) {
//若遍历第一个字符且运算符栈为空,人为添加编号为0的标记字符
reto = true;
retn = 0;
return;
}
if (str[i] == 0) {
//若此时遍历字符为空字符,则表示字符串已遍历完
reto = true;
retn = 0;
return;
}
if (str[i] >= '0'&&str[i] <= '9') {//若当前字符为数字
reto = false;
}
else {
reto = true;
if (str[i] == '+') {
retn = 1;
}
else if (str[i]=='-') {
retn = 2;
}
else if (str[i] == '*') {
retn = 3;
}
else if (str[i] == '/') {
retn = 4;
}
i += 2;
return;
}
retn = 0;
for (; str[i] != ' '&&str[i]!=0; i++) {
retn *= 10;
retn += str[i] - '0';
}
if (str[i] == ' ')
i++;
return;
}
int main() {
while (gets_s(str)) {//vs2015采用C11标准,原来的get需改为gets_s
if (str[0] == '0'&&str[1] == 0)
break;
bool retop;
int retnum;
int idx = 0;
while (!op.empty())
op.pop();
while (!in.empty())
in.pop();
while (1) {//循环遍历表达式字符串
getOp(retop, retnum, idx);//获取表达式中下一个元素
if (retop == false) {
in.push((double)retnum);
}
else {
double tmp;
if (op.empty() == true || mat[retnum][op.top()] == 1) {
op.push(retnum);
}
//若运算符堆栈为空或者当前遍历到的运算符优先级大于栈顶运算符
//将该运算符压入运算符堆栈
else {
while (mat[retnum][op.top()] == 0) {
//只要当前运算符优先级小于栈顶元素运算符,便重复循环
int ret = op.top();//保存栈顶运算符
op.pop();
double b = in.top();
in.pop();
double a = in.top();
in.pop();
switch(ret) {
case 1:tmp = a + b; break;
case 2:tmp = a - b; break;
case 3:tmp = a*b; break;
case 4:tmp = a / b; break;
}
in.push(tmp); //将结果压回数字堆栈
}
op.push(retnum);//将当前运算符压入运算符堆栈
}
}
if (op.size() == 2 && op.top() == 0)
break;
}
printf("%.2f\n", in.top());
}
return 0;
}
除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog
标签:POJ C++
精华推荐