计算表达式代码

来源:互联网 发布:机器人c语言编程实例 编辑:程序博客网 时间:2024/05/15 10:26
/*实验三  顺序栈实现算术表达式的计算(1)
输入格式:一行一个算术表达式
输出格式:一行一个输出结果
样例:
输入样例:
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;
}


原创粉丝点击