机试指南 cha 3 栈的应用
括号匹配问题
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stack>
using namespace std;
/*
问题:cha 3 栈的应用 括号匹配问题
思路:如果直接在压栈的时候输出,则连续出现多个((((的$不能及时输出,
必须要等到输入串遍历结束后,站内剩余(((才能将其对应输出串位置修改为$
2 压栈的内容是字符还是字符在字符串中的索引位置?如果是字符则无法找到并修改ans中的字符
*/
char ans[101];
void match(char c[101])
{
stack<int> s;
int i = 0;
while (c[i] !='\0')
{
// 如果为)且为栈底则输出?,如果为(且为栈底则输出$,如果为其他字符则不压栈输出空格
// 如果为左括号则压栈,右括号则判断栈顶,如果为(则弹栈
if (c[i] == ')'&& s.empty())
ans[i] = '?';
else if (c[i] == '(')
{
s.push(i);
ans[i] = ' ';
}
else if (c[i] == ')' && c[s.top()] == '(')
{
s.pop();
ans[i] = ' ';
}
else
ans[i] =' ';
i++;
}
while (!s.empty())
{
ans[s.top()] = '$';
s.pop();
}
ans[i] = '\0';
}
int main()
{
char c[101];
cin >> c;
cout << c << endl;
match(c); // 输出匹配的符号
cout << ans << endl;
return 0;
}
表达式求值(课本)
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stack>
using namespace std;
/*
问题 : 简单计算器(表达式求值)
*/
bool isNum(char c)
{
int num = c-'0';
if (num >= 0 && num <= 9)
return true;
else
return false;
}
char op[8][8] =
{
'0','+','-','*','/','(',')','#',
'+','>','>','<','<','<','>','>',
'-','>','>','<','<','<','>','>',
'*','>','>','>','>','<','>','>',
'/','>','>','>','>','<','>','>',
'(','<','<','<','<','<','=','>',
')','>','>','>','>','0','>','>',
'#','<','<','<','<','<','0','=',
};
char compare(char a,char b)
{
int x,y;
for (int i = 1;i < 8;i++)
if (op[i][0] == a)
x = i;
for (int i = 1;i < 8;i++)
if (op[0][i] == b)
y = i;
return op[x][y];
}
int cal(int a,char op,int b)
{
switch (op)
{
case '+':return a+b;break;
case '-':return b-a;break;
case '*':return a*b;break;
case '/':return b/a;
}
}
int main()
{
char c[201];
stack<char> oper;
stack<int> number;
oper.push('#');
while (cin>>c)
{
if (c[0] =='0')
break;
int i = 0;
while (c[i] != '#' || oper.top()!= '#')
{
if (isNum(c[i]))
{
number.push(c[i]-'0');
i = i+1;
continue;
}
switch(compare(oper.top(),c[i]))
{
case '<':
// 继续压栈
oper.push(c[i]);
i = i+1;
break;
case '=':
// 弹栈
oper.pop();
i = i+1;
break;
case '>':
// 栈顶为优先级高的运算符,进行计算后压栈
char oper1 = oper.top();
oper.pop();
int num1 = number.top();
number.pop();
int num2 = number.top();
number.pop();
int ans = cal(num1,oper1,num2);
number.push(ans);
// 此时c[i]符号并没有压入栈中,所以不用i+2
}
}
cout << number.top()<<endl;
}
return 0;
}
局限性:输入的表达式中数字不能是大于9的整数
改进的表达式求值(计算大于9的整数)
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stack>
using namespace std;
/*
问题 : 简单计算器(表达式求值)
*/
bool isNum(char c[])
{
int num = c[0]-'0';
if (num >= 0 && num <= 9)
return true;
else
return false;
}
int Num(char c[])
{
// 计算数字的值
int sum=0;
int i=0;
while (c[i]!='\0')
{
int a = c[i]-'0';
// cout << c[i];
sum = sum*10+a;
i++;
}
return sum;
}
char op[8][8] =
{
'0','+','-','*','/','(',')','#',
'+','>','>','<','<','<','>','>',
'-','>','>','<','<','<','>','>',
'*','>','>','>','>','<','>','>',
'/','>','>','>','>','<','>','>',
'(','<','<','<','<','<','=','>',
')','>','>','>','>','0','>','>',
'#','<','<','<','<','<','0','=',
};
char compare(char a,char b)
{
int x,y;
for (int i = 1;i < 8;i++)
if (op[i][0] == a)
x = i;
for (int i = 1;i < 8;i++)
if (op[0][i] == b)
y = i;
return op[x][y];
}
int cal(int a,char op,int b)
{
switch (op)
{
case '+':return a+b;break;
case '-':return b-a;break;
case '*':return a*b;break;
case '/':return b/a;
}
}
int main()
{
char c[10];
stack<char> oper;
stack<int> number;
oper.push('#');
while (cin>>c){// 每次仅输入一个单词,如果是运算符则c[0],数字则需要计算一下
int i = 0;
if (c[0] == '0')
break;
while (c[i] != '#' || oper.top()!= '#')
{
if (isNum(c))
{
number.push(Num(c));
// cout << Num(c) << endl;
cin >> c;
continue;
}
switch(compare(oper.top(),c[i]))
{
case '<':
// 继续压栈
oper.push(c[i]);
cin >> c;
break;
case '=':
// 弹栈
oper.pop();
cin >> c;
break;
case '>':
// 栈顶为优先级高的运算符,进行计算后压栈
char oper1 = oper.top();
oper.pop();
int num1 = number.top();
number.pop();
int num2 = number.top();
number.pop();
int ans = cal(num1,oper1,num2);
number.push(ans);
// 此时c[i]符号并没有压入栈中,所以不用i+2
}
}
cout << number.top()<<endl;
}
return 0;
}
测试用例:
10 + 2 * 3 - 8 / ( 3 + 1 ) #
0
简单计算器 2006年浙江大学计算机及软件工程研究生机试真题
这个题第一天重新写了一下课本上的实现方法,第二天改进成可以计算大于9的的算术表达式,第三天修改成符合这道机试题格式要求的题目。
自己还差的很远。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stack>
using namespace std;
/*
问题 : 简单计算器(表达式求值)
改进版3:输入串末尾没有#如何控制,用字符后面有没有空格来控制
*/
bool isNum(char c[],int i)
{
int num = c[i]-'0';
if (num >= 0 && num <= 9)
return true;
else
return false;
}
int Num(char c[],int &i)
{
// 计算数字的值
int sum=0;
while (c[i]!=' ' && c[i]!='\0')
{
int a = c[i]-'0';
// cout << c[i];
sum = sum*10+a;
i++;
}
return sum;
}
char op[8][8] =
{
'0','+','-','*','/','(',')','\0',
'+','>','>','<','<','<','>','>',
'-','>','>','<','<','<','>','>',
'*','>','>','>','>','<','>','>',
'/','>','>','>','>','<','>','>',
'(','<','<','<','<','<','=','>',
')','>','>','>','>','0','>','>',
'\0','<','<','<','<','<','0','=',
};
char compare(char a,char b)
{
int x,y;
for (int i = 1;i < 8;i++)
if (op[i][0] == a)
x = i;
for (int i = 1;i < 8;i++)
if (op[0][i] == b)
y = i;
return op[x][y];
}
float cal(float a,char op,float b)
{
switch (op)
{
case '+':return a+b;break;
case '-':return b-a;break;
case '*':return a*b;break;
case '/':return b/a;
}
return 0;
}
int main()
{
char c[50];
stack<char> oper;
stack<float> number;
oper.push('\0');
while (cin.getline(c,1000)){// 输入一行字符
int i = 0;
if (c[0] == '0')
break;
while (c[i] != '\0' || oper.top()!= '\0')
{
if (isNum(c,i))
{
float sum = Num(c,i);
number.push(sum);
// cout << sum << endl;
if (c[i]!='\0')
i++; // i自增前指向空格或者字符串终止符
continue;
}
switch(compare(oper.top(),c[i]))
{
case '<':
// 继续压栈
oper.push(c[i]);
i = i+1;
if (c[i]!='\0') i++;
break;
case '=':
// 弹栈
oper.pop();
i = i+1;
if (c[i]!='\0') i++;
break;
case '>':
// 栈顶为优先级高的运算符,进行计算后压栈
char oper1 = oper.top();
oper.pop();
float num1 = number.top();
number.pop();
float num2 = number.top();
number.pop();
float ans = cal(num1,oper1,num2);
number.push(ans);
// 此时c[i]符号并没有压入栈中,所以不用i+2
}
}
printf("%.2f\n",number.top());
}
return 0;
}