| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4343 人关注过本帖
标题:完整的数学表达式求值计算器(标准C++语言编写)
只看楼主 加入收藏
lhjok
Rank: 1
来 自:江西瑞金
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-16
结帖率:33.33%
收藏
已结贴  问题点数:0 回复次数:9 
完整的数学表达式求值计算器(标准C++语言编写)
程序代码:
#include <iostream>     //标准输入输出流头文件。
#include <cstdlib>     //标准“exit()”所包含的头文件。
#include <cmath>      //标准数学库函数。
#include <iomanip>     //标准流格式头文件。
#include <windows.h>    //Windows头文件。
#include "stack.h"     //自定义(栈)类模板头文件。
using namespace std;     //命名空间。
stack<long double> A;     //数据栈(存有效数字)。
stack<char> B;     //字符栈(存运算符)。
void Run();     //综合运算函数。
int Priority( char );     //运算符优先级。
long double Computing( char );     //简单运算函数。
void SetColor( unsigned short FColor=4, unsigned short BColor=0 )    //字体颜色设置。
{    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute( hCon, FColor | BColor );    }
void help()    //帮助与程序说明。
{    cout<<"&-Calculator 1.1---------------------------------------->\n"
        <<"数学表达式求值计算器: 程序编写者(C++ Language): 刘华军\n"
        <<"说 明:(^)是乘方运算符,键入(S)清屏,键入(Q)退出。\n"
        <<"本程序支持负数运算以及错误警告。\n"
        <<"请在下面输入数学表达式: 例 6+(6+8/2*(8-5)^8)*2\n"
        <<"&---------------------------------------------->";   }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    system("cls");    //清屏函数。(调用DOS命令)
    help();    //帮助与程序说明。
    for(;;)   //无限循环。
        Run();   //调用综合运算函数。
    return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Run()
{
    int c,d;
    long double P,Z=0;
    const long double Max=999999999999.999;     //long double 的最长数字是15位包括小数点后面的精度位数,小数点不包括在内。
    char ch,ab=0;     //"ab"变量用来标记上一次进栈的是数字还是运算符。
    cout<<endl;
    SetColor(7,0);
    cin.clear();    cin.sync();      //清空输入流。
    A.clear();        B.clear();       //清空A-B栈。
    while ( cin )      //检查输入流是否可用。
    {
        cin.get( ch );      //输入表达式。(能读取空格符、换行符、回车符。)
        switch ( ch )
        {
            case '(': if ( ab !='A' )     //左括号前不能是数字。
                      { B.push( ch ); break; }
                      SetColor();  cerr<<"Error:01";  return;
            case ')': if ( B.find('(') && ab =='A' )    //运算符栈中必须有左括号与右括号前必须是数字。(右括号不进栈)
                      {
                          while ( B.top() != '(' )
                          {
                              try     //异常定义。(可能抛出异常的语句)
                              { A.push( Computing(B.top()) ); }    //如果出现异常,函数内部会抛出异常。
                              catch ( long double )     //捕获并处理异常。
                              { SetColor(); cerr<<"Error:04"; return; }
                              B.pop();     //运算符出栈。
                          }
                          B.pop();    break;     //左括号出栈。
                      }
                      SetColor();  cerr<<"Error:01";  return;
            case '+':
            case '-':
            case '*':
            case '/':
            case '^': if ( ch =='-' && ab !='A' )     //当上一次进栈的数据是运算符,当前'-'为负数标号。
                      {
                          cin.putback( ch );     //此函数将当前字符送回到缓冲区中。
                          if ( cin>>P )          //检查读取的数字是否有效。
                          { A.push( P );  ab='A';  break; }     //读取的数字进栈,"ab"变量记录下来。
                          SetColor();  cerr<<"Error:01";  return;
                      }
                      else if ( ab =='A' )     //运算符前面必须是数字。
                      {
                          while ( !B.empty() && B.top() != '(' )     //运算符栈为空或栈顶元素为左括号时停止循环。
                          {
                              c= Priority( B.top() );
                              d= Priority( ch );
                              if ( c >= d )
                              {
                                  try     //异常定义。(可能抛出异常的语句)
                                  { A.push( Computing(B.top()) ); }    //如果出现异常,函数内部会抛出异常。
                                  catch ( long double )     //捕获并处理异常。
                                  { SetColor(); cerr<<"Error:04"; return; }
                                  B.pop();
                              }
                              else
                                  break;     //跳出循环。
                          }
                          B.push( ch );  ab='B';  break;     //运算符进栈,"ab"变量记录下来。
                      }
                      SetColor();  cerr<<"Error:01";  return;
            case '\n':
            case '\r':
            case '=': if ( B.empty() && A.empty() || B.find('(') || ab !='A' )    //A-B栈不能为空,等号前不能出现左括号和不能没有数字。
                      { SetColor(); cerr<<"Error:01"; return; }
                      else if ( B.empty() && !A.empty() )     //等号前只有一个数字。
                          Z= A.top();
                      while ( !B.empty() )
                      {
                          try     //异常定义。(可能抛出异常的语句)
                          { Z= Computing( B.top() ); }    //如果出现异常,函数内部会抛出异常。
                          catch ( long double )     //捕获并处理异常。
                          { SetColor(); cerr<<"Error:04"; return; }
                          A.push( Z );  B.pop();
                      }
                      A.pop();      //清空最后一个数据栈。
                      if ( Max < Z )     //检查结果是否超出最大数据范围。
                      { SetColor(); cerr<<"Error:03"; return; }
                      SetColor(2,0);
                      cout<<fixed<<setprecision(3)<<Z;  return;
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case '.': cin.putback( ch );     //此函数将当前字符送回到缓冲区中。
                      if ( cin>>P && ab !='A' )      //检查读取的数字是否有效,上一次进栈的数据不可以还是数字。
                      { A.push( P );  ab='A';  break; }      //读取的数字进栈,"ab"变量记录下来。
                      SetColor();  cerr<<"Error:01";  return;
            case 'Q':
            case 'q': exit(1);    //退出程序。
            case 's':
            case 'S': system("cls");  help();  return;     //清屏后打印帮助与程序说明。
            default : SetColor();  cerr<<"Error:02";  return;
        }
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Priority( char x )
{
    switch ( x )
    {
        case '+':
        case '-':  return 0;     //将运算符优先级标记为数字。
        case '*':
        case '/':  return 1;     //将运算符优先级标记为数字。
        case '^':  return 2;     //将运算符优先级标记为数字。
        default :  exit(1);
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
long double Computing( char x )
{
    int n;
    long double a,b;
    switch ( x )
    {
        case '+':  b= A.top();   A.pop();     //(数字栈)栈顶元素赋给b,然后出栈。
                   a= A.top();   A.pop();     //(数字栈)栈顶元素赋给a,然后出栈。
                   return a+b;
        case '-':  b= A.top();   A.pop();     //(数字栈)栈顶元素赋给b,然后出栈。
                   a= A.top();   A.pop();     //(数字栈)栈顶元素赋给a,然后出栈。
                   return a-b;
        case '*':  b= A.top();   A.pop();     //(数字栈)栈顶元素赋给b,然后出栈。
                   a= A.top();   A.pop();     //(数字栈)栈顶元素赋给a,然后出栈。
                   return a*b;
        case '/':  b= A.top();   A.pop();     //(数字栈)栈顶元素赋给b,然后出栈。
                   a= A.top();   A.pop();     //(数字栈)栈顶元素赋给a,然后出栈。
                   if ( b != 0 )
                       return a/b;
                   throw b;    //抛出异常。
        case '^':  n= static_cast<int>( A.top() );   A.pop();     //(数字栈)栈顶元素(强制转换成整型)赋给n,然后出栈。
                   a= A.top();   A.pop();     //(数字栈)栈顶元素赋给a,然后出栈。
                   return pow(a,n);    //数学库函数。(乘方运算函数)
        default :  exit(1);
    }
}
[local]1[/local]
搜索更多相关主题的帖子: 数学 计算器 求值 语言 
2010-09-19 10:34
lhjok
Rank: 1
来 自:江西瑞金
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-16
收藏
得分:0 
回复 楼主 lhjok
Calculator.rar (80.22 KB)
2010-09-19 13:23
xxlovemf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:49
专家分:88
注 册:2009-8-6
收藏
得分:7 
厉害
我之前也写过一个
回头发给你
2010-09-20 16:41
lhjok
Rank: 1
来 自:江西瑞金
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-16
收藏
得分:0 
回复 3楼 xxlovemf
谢谢您的回复!!没想到有人会给出这么高的评价,呵呵!你有空把你写的发给我看一下,大家共同学习。
我的邮箱:lhjok@
2010-09-20 20:03
xxlovemf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:49
专家分:88
注 册:2009-8-6
收藏
得分:0 
这就是我写的 呵呵
有点简陋
程序代码:
#include<iostream>//计算器
#include<string>
using namespace std;

int main(int argc,char **argv)
{
    static double s_num;//输入第一个数
    int iNum,ix=0;//下一个数以及计数器
    const TIMES=3;//运算总次数
    char cOperator;//运算符
    cout<<"请输入一组运算式(注意:只限于加 减 乘 除!)\n";
    cout<<"例如:45*3  "<<endl;
    cin>>s_num;
    while(ix<TIMES)
    {
        cin>>cOperator>>iNum;
    //    cout<<s_num<<cOperator<<iNum<<'=';
        switch(cOperator)
        {
        case '+':
            s_num+=iNum;break;
        case '-':
            s_num-=iNum;break;
        case '*':
            s_num*=iNum;break;
        case '/':
            s_num/=iNum;break;
        default:
            cerr<<"error!"<<endl;break;
        }
    cout<<s_num<<endl;
    cout<<"请继续输入运算符以及下一个数字"<<endl;
    ++ix;
    }
    cout<<endl<<"您已经进行了"<<TIMES<<"次运算,本次运算完毕!"<<endl;

    return 0;
}

 
2010-09-20 20:19
ToBeOOP
Rank: 3Rank: 3
等 级:论坛游侠
威 望:3
帖 子:106
专家分:181
注 册:2010-7-8
收藏
得分:7 
程序代码:
#include <iostream>
#include <cctype> 

using std::endl; 
using std::cin;
using std::cout;

void eatspace(char* Str);  //用于取消在输入时输入的空格.
double FirstP(char* Str);  //用于处理一级运算.
double SecondP(char* Str,int& index);  //用于处理二级运算.
double number(char* Str,int& index); //用于将字符串中的数字组合起来.

int main(void)
{
    const int MAX = 20;
    char Str[MAX] = {0};

    for(;;)
    {
        cin.getline(Str,MAX);  

        eatspace(Str);
   
        if( !Str[0] )  // 注意:( !Str )等价于 ( Str == 0 ).
            return 0;

        cout << "Reasult = " << FirstP(Str);
    }
    system ( "Pause" ) ;
    return 0;
}
void eatspace(char* Str)
{
    int a = 0;
    int b = 0;

    while( (*(Str + a ) = *(Str + b++ )) != '\0' )  // 注意:不能写成 *(Str + a ) = *(Str + b++ ) != '\0'
    {
        if( *( Str + a ) != ' ' )
            a++ ;
    }
    return;
}
double FirstP(char* Str)
{
    int index = 0;
    double value = 0.0;
   
    value = SecondP(Str,index);

    for( ; *(Str + index) != '\0'; )
    {
        switch( *(Str + index++) )
        {
            case '+' :
                value += SecondP(Str,index);
                break;
            case '-'  :
                value -= SecondP(Str,index);
                break;
            default :
                cout << endl
                        << "Warning!"
                        << endl;
        }
    }
        return value;
}
double SecondP(char* Str,int& index)
{
    double value = 0.0;

    value = number(Str,index);
   
    while( (*(Str + index) == '*' ) || (*(Str + index) == '/') )
    {
        if( *(Str + index) == '*' )
        {
            index++;
            value *= number(Str,index);
        }
        else
            if( *(Str +index) == '/' )
            {
                index++;
                value /= number(Str,index);
            }
    }
    return value;
}
double number(char* Str,int& index)
{
    double value = 0.0;

    while( isdigit( *( Str + index) ) )
        value = 10 * value + ( *(Str + index++) - '0' );
    if( *(Str + index) == '.' )
    {
        index++;
        double lessen = 0.1;

        while( isdigit( *(Str + index) ) )
        {
            value += lessen * ( *(Str + index++) - '0' );
            lessen *= lessen;
        }
    }
    return value;
}
献丑了= =
2010-09-20 23:04
lhjok
Rank: 1
来 自:江西瑞金
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-16
收藏
得分:0 
回复 5楼 xxlovemf
不会啊!!呵呵!!谢谢你关注我!以后可以交个朋友的。我的QQ:1395875889
2010-09-21 19:47
lhjok
Rank: 1
来 自:江西瑞金
等 级:新手上路
帖 子:20
专家分:0
注 册:2010-9-16
收藏
得分:0 
回复 6楼 ToBeOOP
好像不能处理优先级和错误检查?不知道是不是我没仔细看清楚!谢谢你的回复!!!你写得不错。。。
2010-09-21 19:59
ToBeOOP
Rank: 3Rank: 3
等 级:论坛游侠
威 望:3
帖 子:106
专家分:181
注 册:2010-7-8
收藏
得分:0 
一则运算二则运算的优先级没问题...圆括号没考虑在内
2010-09-22 07:39
leger28
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2011-12-1
收藏
得分:0 
很强大的程序呀。但看长度就不简单了。
2011-12-01 21:27
快速回复:完整的数学表达式求值计算器(标准C++语言编写)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023643 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved