计算表达式代码
来源:互联网 发布:机器人c语言编程实例 编辑:程序博客网 时间:2024/05/15 10:26
输入格式:一行一个算术表达式
输出格式:一行一个输出结果
样例:
输入样例:
2*(3 + 4)
输出样例
14
【基本要求】运算对象均为整数
【选作内容】运算对象扩充为可以是带小数位的浮点数
*/
//----------------------------------------------------------------
//下面是顺序栈的定义
#include<iostream>
#include <cmath>
using namespace std;
//该类是顺序表栈
template<class T>
class SeqStack
{
public:
SeqStack(int sz = 100); //默认maxSize为100
~SeqStack(){ delete[]elements; }
void push(T&x); //将数据x压入栈中
bool pop(T &x); //出栈将数据放在x里面
bool getTop(T&x); //获取栈顶元素
bool isEmpty()const{ return (top == -1) ? true : false; }
bool isFull()const{ return(top == maxSize - 1) ? true : false; }
int getSize()const{ return top + 1; }
void makeEmpty(){ top = -1; }
private:
T *elements; //存放栈中元素数组
int top; //栈顶下标,空时候为-1
int maxSize; //最大元素个数
void overflowProcess(); //溢出时进行的处理
};
template<class T>
SeqStack<T>::SeqStack(int sz)
{
top = -1;
maxSize = sz;
elements = new T[maxSize];
if (elements == 0){ cerr << "存储分配失败!" << endl; exit(1); } //动态存储分配如果出错结束程序
}
template<class T>
void SeqStack<T>::overflowProcess()
{
T *newArray = new T[maxSize + 50];//如果溢出,每次加50个
if (newArray == 0){ cerr << "存储分配失败!" << endl; exit(1); }
for (int i = 0; i <= top; i++)newArray[i] = elements[i];
maxSize = maxSize + 50;
delete[]elements;
elements = newArray;
}
template<class T>
void SeqStack<T>::push(T&x)
{
if (isFull())overflowProcess(); //栈满先溢出处理
elements[++top] = x; //top先加1,再进栈
}
template<class T>
bool SeqStack<T>::pop(T&x)
{
if (isEmpty())return false;
x = elements[top--];
return true;
}
template<class T>
bool SeqStack<T>::getTop(T&x)
{
if (isEmpty())return false;
x = elements[top];
return true;
}
//-------------------------------------------------------------------------------------------
//下面的代码是实现表达式的计算
char *p = new char[500]; //存储表达式的数组
int pos; //字符数组的下标
double translate(int &pos) //将字符数组里面的字符转化为数字
{
int integer = 0;//整数部分
double decimals = 0;//小数部分
while (p[pos] >= '0' && p[pos] <= '9')//得出整数部分的数值
{
integer = integer * 10;
integer = integer + (p[pos] - '0');
pos++;
}
if (p[pos] == '.') //得出小数点后的数值
{
pos++;
int c = 1;
while (p[pos] >= '0' && p[pos] <= '9')
{
double t = p[pos] - '0';
t *= pow(0.1, c);
c++;
decimals =decimals+ t;
pos++;
}
}
return integer + decimals;
}
//运算符级别,栈内isp
int isp(char ch)
{
switch (ch)
{
case')':
return 6; break;
case '+':
case '-':
return 3; break;
case '*':
case '/':
return 5; break;
case '(':
return 1; break;
case '#':
return 0; break;
};
}
//运算符级别,栈外icp
int icp(char ch)
{
switch (ch)
{
case')':
return 1;
case '+':
case '-':
return 3;
case '*':
case '/':
return 5;
case '(':
return 6;
case '#':
return 0;
};
}
//对两个数进行计算
double Operate(double a1, char op, double a2)
{
switch (op)
{
case '+':
return a1 + a2;
case '-':
return a1 - a2;
case '*':
return a1 * a2;
case '/':
return a1 / a2;
};
}
//用两个栈进行计算
double calculator()
{
SeqStack<char>cha; //字符栈
SeqStack<double>num; //数值栈
char cs = '#',cp=' ';//cp是栈外的,cs是栈内的
double n = 0; //n是数值
cha.makeEmpty();//清空栈
num.makeEmpty();//清空栈
cha.push(cs); //将#压入字符栈
for (pos = 0; pos<strlen(p);)
{
if (p[pos] >= '0'&&p[pos] <= '9')
{
n = translate(pos);//将字符转换为数字
num.push(n); //将数字压入数值
}
else if (p[pos] == '*' || p[pos] == '+' || p[pos] == '-' || p[pos] == '/' || p[pos] == '(' || p[pos] == ')' || p[pos] == '#')//如果是字符的话
{
cp = p[pos];
cha.getTop(cs);
if (icp(cp) > isp(cs)&&cha.getTop(cs)&&cs!=')')//如果栈外优先级大于栈内且不为')'进栈
{
cha.push(cp);
pos++;
}
else
{
if (p[pos] == ')')//如果是')'
{
if (cha.getTop(cs) && cs == '(')//如果栈内是'('将'('出栈,继续读下一个字符
{
cha.pop(cs); pos++;
}
else
{
double a1, a2; double result;//如果没有碰到'('进行运算
num.pop(a2);
num.pop(a1);
cha.pop(cs);
result = Operate(a1, cs, a2);
num.push(result);
}
}
else if (p[pos] == '#'&&cha.getTop(cs) && cs == '#')//如果是只输入一个数字的话直接将结果输出
{
num.pop(n);
return n;
}
else //进行运算
{
double a1, a2; double result;
num.pop(a2);
num.pop(a1);
cha.pop(cs);
result = Operate(a1, cs, a2);
num.push(result);
}
}
}
else //输入非法字符出错处理
{
cout << "表达式格式错误,结束运行。" << endl; system("pause"); exit(1);
}
}
if (num.getSize() == 1) //处理结果数字栈里面有一个值,输出
{
num.pop(n);
return n;
}
else if (num.getSize() == 2)//如果有两个值,计算一次输出结果
{
double a1, a2; double result;
num.pop(a2);
num.pop(a1);
cha.pop(cs);
result = Operate(a1, cs, a2);
return result;
}
}
int main()
{
while (1)
{
cin >> p;
int le = strlen(p);
p[le] = '#'; p[le + 1] = '\0'; //在表达式后面加个#,并添加'\0'代表字符结束
cout <<"the result is:"<< calculator() << endl;
}
return 0;
}
//扩展的可以计算负数的,(该算法是以前转载自其他博客的链接已忘)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cmath>
using namespace std;
char s[1000];
int g_pos; // 字符数组的下标
/* 字符转数字 */
double Translation(int & pos)
{
double integer = 0.0; // 整数部分
double remainder = 0.0; // 余数部分
while (s[pos] >= '0' && s[pos] <= '9')
{
integer *= 10;
integer += (s[pos] - '0');
pos++;
}
if (s[pos] == '.')
{
pos++;
int c = 1;
while (s[pos] >= '0' && s[pos] <= '9')
{
double t = s[pos] - '0';
t *= pow(0.1, c);
c++;
remainder += t;
pos++;
}
}
return integer + remainder;
}
/* 返回运算符级别 */
int GetLevel(char ch)
{
switch (ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 0;
case '#':
return -1;
};
}
/* 对两个数进行运算 */
double Operate(double a1, char op, double a2)
{
switch (op)
{
case '+':
return a1 + a2;
case '-':
return a1 - a2;
case '*':
return a1 * a2;
case '/':
return a1 / a2;
};
}
/* 利用两个栈进行模拟计算 */
double Compute()
{
stack<char> optr; // 操作符栈
stack<double> opnd; // 操作数栈
optr.push('#');
int len = strlen(s);
bool is_minus = true; // 判断'-'是减号还是负号
for (g_pos = 0; g_pos < len;)
{
//1. 负号
if (s[g_pos] == '-' && is_minus) // 是负号
{
opnd.push(0);
optr.push('-');
g_pos++;
}
//2. 是右括号 )
else if (s[g_pos] == ')')
{
is_minus = false;
g_pos++;
while (optr.top() != '(')
{
double a2 = opnd.top();
opnd.pop();
double a1 = opnd.top();
opnd.pop();
char op = optr.top();
optr.pop();
double result = Operate(a1, op, a2);
opnd.push(result);
}
optr.pop(); // 删除'('
}
//3. 数字
else if (s[g_pos] >= '0' && s[g_pos] <= '9')
{
is_minus = false;
opnd.push(Translation(g_pos));
}
//4. ( 左括号
else if (s[g_pos] == '(')
{
is_minus = true;
optr.push(s[g_pos]);
g_pos++;
}
//5. + - * / 四种
else
{
while (GetLevel(s[g_pos]) <= GetLevel(optr.top()))
{
double a2 = opnd.top();
opnd.pop();
double a1 = opnd.top();
opnd.pop();
char op = optr.top();
optr.pop();
double result = Operate(a1, op, a2);
opnd.push(result);
}
optr.push(s[g_pos]);
g_pos++;
}
}
while (optr.top() != '#')
{
double a2 = opnd.top();
opnd.pop();
double a1 = opnd.top();
opnd.pop();
char op = optr.top();
optr.pop();
double result = Operate(a1, op, a2);
opnd.push(result);
}
return opnd.top();
}
int main()
{
while (cin >> s)
cout << "结果为:" << Compute() << endl << endl;
return 0;
}
- 表达式计算的代码
- 计算表达式代码
- 基础代码-计算后缀表达式
- [Java代码] java数学表达式计算 QLExpress
- 后缀表达式计算的代码实现
- 计算器C++代码实现—— 中缀表达式的计算
- java代码:计算以 字符串 形式存在的算术表达式
- java几行代码搞定算术表达式的计算
- "括号匹配, 中缀表达式转化为后缀表示式, 计算中缀表达式, 计算后缀表达式"完整代码
- 表达式计算
- 表达式计算
- 表达式计算
- 表达式计算
- 表达式计算
- 表达式计算
- 表达式计算
- 计算表达式
- 表达式计算
- 阿里云配置nginx反向代理tomcat
- 三角形的判定
- Ubuntu 16.04 安装Pycharm
- 画弧+100%
- mysql Access denied for user root@localhost错误解决方法总结 原创 2016年07月06日 17:00:40 41843 问题重现(以下讨论范围仅限Windo
- 计算表达式代码
- The word is not correctly spelled问题解决
- (转)比特币王国的内战与分裂|《财经》特稿
- mysql笔记3
- sed -i
- STM32固件库详解
- 数论
- Visual Studio扩展开发之菜单设置--拒绝反复输入样板代码,编写IDE插件,提升编码效率
- iphone恢复删除的文件-不要钱!