为了重温下list的用法,特地写了个简单的计算器,还有些问题,不过基本功能实现就不继续改进了。主要算法需要把我们习惯的中序换成后序,这样能够消除小括号,后序排序后就非常好处理了。
另外输入时若有空格会出问题,不知道为什么,望C++大神能够解答。
#include <iostream>
#include <list>
#include <string>
using namespace std;
int operatorPriority(char s){
if (s >= '0' && s <= '9' || s == '.'){
return 0;
}
else if (s == '-' || s == '+'){
return 1;
}
else if (s == '*' || s == '/'){
return 2;
}
else if (s == '^'){
return 3;
}
else if (s == '(' || s == ')'){
return 4;
}
else{
return -1;
}
}
void showList(list<string> list){
while(!list.empty()){
cout << list.front() << " ";
list.pop_front();
}
cout << "\n";
}
int main(){
list<string> plt; // numbers and operators queue
list<string> tlt; // temporary operator stack
list<string> rlt; // postfix queue
list<int> clt; // number stack when calculating
string s = "";
cout << "input \"quit\" to exit program or input to calculate something(please do not type in space)\n";
cin >> s;
while (s != "quit"){
int index = 0;
bool isValid = true;
// seperate number and operator
for (int i = 0; i < s.length(); ++i){
if (i == s.length()-1 && operatorPriority(s[i]) == 0){
plt.push_back(s.substr(i-index, index+1));
}
else if (operatorPriority(s[i]) == 0){
++index;
}
else if (operatorPriority(s[i]) > 0){
if (index != 0) plt.push_back(s.substr(i-index, index));
plt.push_back(s.substr(i, 1));
index = 0;
}
else{
cout << "error \n";
isValid = false;
break;
}
}
// convert infix to postfix
if (isValid){
while (!plt.empty()){
string strPop = plt.front();
plt.pop_front();
if (strPop[0] >= '0' && strPop[0] <= '9'){
rlt.push_back(strPop);
}
else if (strPop == "("){
tlt.push_back(strPop);
}
else if (strPop == ")"){
while(tlt.back() != "("){
rlt.push_back(tlt.back());
tlt.pop_back();
}
tlt.pop_back();
}
else if (tlt.empty() || operatorPriority(tlt.back()[0]) < operatorPriority(strPop[0])){
tlt.push_back(strPop);
}
else {
bool s = true;
while(s){
if (tlt.back() == "(" || operatorPriority(tlt.back()[0]) < operatorPriority(strPop[0])){
s = false;
}
else {
rlt.push_back(tlt.back());
tlt.pop_back();
}
if (tlt.empty()){
s = false;
}
}
tlt.push_back(strPop);
}
}
while (!tlt.empty()){
rlt.push_back(tlt.back());
tlt.pop_back();
}
}
showList(rlt);
// calculate
while (!rlt.empty()){
string p = rlt.front();
rlt.pop_front();
if (operatorPriority(p[0]) == 0){
clt.push_back(atoi(p.c_str()));
}
else {
int num1 = clt.back();
clt.pop_back();
int num2 = clt.back();
clt.pop_back();
int result = 1;
if (p == "+"){
result = num2 + num1;
}
else if (p == "-"){
result = num2 - num1;
}
else if (p == "*"){
result = num2 * num1;
}
else if (p == "/"){
result = num2 / num1;
}
else if (p == "^"){
for (int i = 1; i <= num1; ++i){
result *= num2;
}
}
clt.push_back(result);
}
}
cout << "result: " << clt.back() << "\ninput \"quit\" to exit program or input to calculate something(please do not type in space)\n";
plt.clear();
rlt.clear();
tlt.clear();
clt.clear();
cin >> s;
}
}