标签:style blog http io ar os sp for on
用计算器比较麻烦,因为它不按计算顺序来,需要按很多次(加之平时用得少,又掺进来负数,按上十来次就按错了)。出于统计方便,写了个程序专门算数。效果如下(格式不作要求,只要输对就行):
主要代码:
/*///////////////////////////////////////
带括号的四则运算:
-------------------------------------
1、中序转为后序表达式
顺序读取,对不同对象按不同情况处理:
1)运算数:直接输出
2)左括号:压入堆栈
3)右括号:将栈的运算符弹出并输出,直到遇到左括号(弹出,不输出)
4)运算符:
若优先级大于栈顶运算符,则把它压栈
若优先级小于等于栈顶运算符,将栈顶运算符弹出并输出,再比较新的栈顶运算符,
直到该运算符优先级大于栈顶运算符为止,然后将该运算符压栈
5)若所有对象处理完毕,则把堆栈中残留的运算符一并输出
--------------------------------------
2、计算后序表达式
每遇到运算符则对它之前的两个数计算
--------------------------------------
程序支持形如 -0.3 + 4 * (-1.5 + -6.4 / -2) * -4 形式的算式
////////////////////////////////////////*/
#include "LinkedStack.h"
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
string Calculate(char oper, double a, double b)
{
switch(oper)
{
case '+':a += b; break;
case '-':a -= b; break;
case '*':a *= b; break;
case '/':
if(b != 0)
a /= b;
else
throw BadInput();
}
stringstream stream;
stream << a;
string str;
stream >> str;
return str;
}
// 删除字符串中空格
void trim(string &str, string::size_type pos = 0)
{
static const string delim = " \t"; //删除空格或者tab字符
pos = str.find_first_of(delim, pos);
if(pos == string::npos)
return;
trim(str.erase(pos, 1));
}
// 从某处起略过数字添加右括号
void AddRight(string& line, int i)
{
int len = line.length();
++i;
while(i < len && (line[i] == '0' || line[i] == '1' ||
line[i] == '2' || line[i] == '3' || line[i] == '4' ||
line[i] == '5' || line[i] == '6' || line[i] == '7' ||
line[i] == '8' || line[i] == '9' || line[i] == '.'))
++i;
line.insert(i, ")");
}
// 处理负数和正号
string& HandleExp(string& line)
{
trim(line);
if(line[0] == '-' || line[0] == '+')
{
AddRight(line, 0); // 先补右括号
line = "(0" + line; // 再补左括号
}
// 需用 line.length(),因为长度不断在变化
for(unsigned i = 1; i < line.length(); ++i)
{
if(( line[i] == '-' || line[i] == '+') &&
( line[i - 1] == '+' || line[i - 1] == '-' ||
line[i - 1] == '*' || line[i - 1] == '/' ||
line[i - 1] == '(' ))
{
AddRight(line, i); // 先补右括号
line = line.insert(i, "(0");
}
}
return line;
}
// 处理表达式,并将中序转后序表达式,并进行计算
string InToPost(string& line)
{
line = HandleExp(line);
LinkedStack<string>num;
LinkedStack<char>symb;
char op;
double a,b;
int size = line.length(), i;
string item("");
for(i = 0; i < size; ++i)
{
if(line[i] == '(')
{
symb.Add('(');
continue;
}
if(line[i] == '*' || line[i] == '/')
{
if(item != "")
{
num.Add(item);
item = "";
}
if( !symb.IsEmpty() && symb.Top() != '('
&&(symb.Top() == '*' || symb.Top() == '/'))
{
symb.Delete(op);
num.Delete(item);
b = strtod(item.c_str(), NULL);
num.Delete(item);
a = strtod(item.c_str(), NULL);
num.Add( Calculate(op, a, b) );
item = "";
}
symb.Add(line[i]);
continue;
}
if(line[i] == '+' || line[i] == '-')
{
if(item != "")
{
num.Add(item);
item = "";
}
if(!symb.IsEmpty() && symb.Top() != '(' )
{
symb.Delete(op);
num.Delete(item);
b = strtod(item.c_str(), NULL);
num.Delete(item);
a = strtod(item.c_str(), NULL);
num.Add(Calculate(op, a, b));
item = "";
}
symb.Add(line[i]);
continue;
}
if(line[i] == ')')
{
if(item != "")
{
num.Add(item);
item = "";
}
while(!symb.IsEmpty() && symb.Top() != '(')
{
symb.Delete(op);
num.Delete(item);
b = strtod(item.c_str(), NULL);
num.Delete(item);
a = strtod(item.c_str(), NULL);
num.Add(Calculate(op, a, b));
}
symb.Delete(op); // 删除 (
item = "";
continue;
}
else
{
item += line[i];
}
}
// 最后一个数字
if(item != "")
{
num.Add(item);
item = "";
}
while(!symb.IsEmpty())
{
symb.Delete(op);
num.Delete(item);
b = strtod(item.c_str(), NULL);
num.Delete(item);
a = strtod(item.c_str(), NULL);
num.Add(Calculate(op, a, b));
}
return num.Top();
}标签:style blog http io ar os sp for on
原文地址:http://blog.csdn.net/mywsfxzxb/article/details/41898583