回 帖 发 新 帖 刷新版面

主题:[活动]第77次编程比赛题目

编写一个程序可以计算表达式值的程序。

例如: 输入:3+6*8      输出:51

要求: 1. 程序能够进行小数运算
       2. 表达式可以包含 ( ) [ ] { } 数字(0~9) 运算符(+ - * / ^)  小数点
       3. 当用户输入有错时,给出出错位置,提示用户重新输入

比赛结束时间:11月28日(周五) 晚上10:00

网上有这题目的解法,不过,希望大家踊跃参加,提交自己写的程序。期待很好的代码出现!


比赛已经结束了,从提交的代码来看,最厉害的,相信大家都看得出来了。我会尽快给出比赛结果。希望这次比赛对大家有所收获。

回复列表 (共29个回复)

21 楼

挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺挺

22 楼


本以为提交的人这么多,很高兴,结果真正参加比赛的也就 “两个人”,不过,我自己也没编写出完整的程序,不过这都是我自己编的。为了奖励我,我把自己的程序也发到上面。

#include <iostream>
#include <stack>
#include <math.h>

using namespace std;

char prog[80];  // 存储用户输入的表达式

int syn, p;  // syn 是得到单词 的种别码,p 是读字符数组的 下标
double sum;  // 计算表达式中的数字的值

#define BOUND 13

//参加运算的运算符
char symbol[BOUND] = { '+', '-', '*', '/', '^', '{', '}', '[', ']', '(', ')', 'D', '#'};
//        syn      =    0    1      2       3    4    5    6    7    8    9   10   11    12     D 代表数字

//每两种运算符之间的关系, 若两者之间不存在比较关系, 为'$'
char prior[BOUND][BOUND] = {
//            +     -    *    /    ^    {    }    [    ]    (    )   digit #
/* + */     {'>', '>', '<', '<', '<', '<', '>', '<', '>', '<', '>', '<', '>'},
/* - */     {'>', '>', '<', '<', '<', '<', '>', '<', '>', '<', '>', '<', '>'},
/* * */        {'>', '>', '>', '>', '<', '<', '>', '<', '>', '<', '>', '<', '>'},
/* / */      {'>', '>', '>', '>', '<', '<', '>', '<', '>', '<', '>', '<', '>'},
/* ^ */        {'>', '>', '>', '>', '>', '<', '>', '<', '>', '<', '>', '<', '>'},
/* { */        {'<', '<', '<', '<', '<', '<', '=', '<', '$', '<', '$', '<', '$'},
/* } */        {'>', '>', '>', '>', '>', '$', '$', '$', '$', '$', '>', '$', '>'},    
/* [ */     {'<', '<', '<', '<', '<', '<', '$', '$', '=', '<', '$', '<', '$'},
/* ] */        {'>', '>', '>', '>', '>', '$', '>', '$', '$', '$', '>', '$', '>'},
/* ( */        {'<', '<', '<', '<', '<', '<', '$', '<', '$', '<', '=', '<', '$'},
/* ) */        {'>', '>', '>', '>', '>', '$', '>', '$', '>', '$', '>', '$', '>'},
/* digit */ {'>', '>', '>', '>', '>', '$', '>', '$', '>', '$', '>', '$', '>'},
/* # */        {'<', '<', '<', '<', '<', '<', '$', '<', '$', '<', '$', '<', '='}
};


int isDigit(char chElem)
{ // if chElem is char or Didit, return 1; else return 0
    if( (chElem >= '0' && chElem <= '9') )
        return 1;
    else
        return 0;    
}



23 楼


void scaner()
{ // -----------

    // read the next char
    char chElem = prog[p++];
    
    while( chElem == ' ')  // read the next char until not ' '
        chElem = prog[p++];
    
    
    if( isDigit(chElem) )
    {
        sum = 0;

        while( isDigit(chElem) )
        {
            sum = sum * 10 + chElem - '0';
            chElem = prog[p++];
        }

        if( chElem == '.' )
        {
            chElem = prog[p++];
            if( isDigit(chElem) )
            {
                int rate = 1;
                while( isDigit(chElem) )
                {
                    rate *= 10;                
                     sum = sum + ((double)(chElem - '0')/rate);
                    chElem = prog[p++];
                }
            }
            else
                syn = -1;            
        }

        p--; // backspace 
        syn = 11;
    }
    else
    {
        switch( chElem )
        {                
        case '+': syn = 0;   break;
        case '-': syn = 1;   break;
        case '*': syn = 2;   break;
        case '/': syn = 3;   break;
        case '^': syn = 4;   break;
        case '{': syn = 5;   break;
        case '}': syn = 6;   break;
        case '[': syn = 7;   break;
        case ']': syn = 8;   break;
        case '(': syn = 9;   break;
        case ')': syn = 10;  break;
        case '#': syn = 12;  break;
            
        default: syn = -1;            
        }
    }
}


double caculate(double a, double b, int chNum)
{  //根据操作符计算出double 型结果返回

    switch( symbol[chNum] )
    {
    case '+':
        return a+b;
    case '-':
        return a-b;
    case '*':
        return a*b;
    case '/':
        if(!b)
        {
            cerr<<"0 不能作为分母 !" <<endl;
            exit(0);
        }
        return a/b;
    case '^':
        if( a == 0.0)
        {
            cerr<<"0 不能作为底数 !" <<endl;
            exit(0);
        }
        return pow(a,b);    
    default:
        cerr<<"you input wrong expression!\n";
        exit(0);
    }
}

24 楼


bool isNotExp(const char exp[])
{  //  检测输入的表达式中括号是否配对, 如果不是表达式,返回true, 否则,返回false;
    stack<char> optr;

    int pos = 0;

    while( exp[pos] != '#' )
    {
        if( exp[pos] == '{' || exp[pos] == '[' || exp[pos] == '(' )
            optr.push(exp[pos]);
        
        if( exp[pos] == '}')
        {
            if( optr.top() == '{')
                optr.pop();
            else
                return true;
        }
        else if(exp[pos] == ']' )
        {
            if( optr.top() == '[')
                optr.pop();
            else
                return true;
        }
        else if( exp[pos] == ')' )
        {
            if( optr.top() == '(')
                optr.pop();
            else
                return true;
        }
        else
            ;
        pos++;
    }

    if( optr.empty() )
        return false;
    else 
        return true;
}

25 楼


int main(void)
{
    stack<double> opnd;
    stack<int> optr;

    bool flagLoop = true;
    
    while( flagLoop )
    {
        flagLoop = false;

        cout << "请输入表达式:" << endl;
        cin.getline(prog, 80);        
    //    strcpy(prog, "3++9.632*{9-8*2+1}");
    //    strcpy(prog, "2*(2+4)4");
        strcat(prog, "#");  // 在输入的字符串中末尾加入结束字符'#'

    //  确保字符堆栈和数据堆栈都为空
        while( !optr.empty() )
            optr.pop();

        while( !opnd.empty() )
            opnd.pop();
        
        optr.push(12);  //  将 "#" 压入符号栈
    
        p = 0;    

        flagLoop = isNotExp(prog);  //  检测是否为表达式

        scaner();
        
        while(!optr.empty() && !flagLoop)
        {
            switch( syn )
            {            
            case 11: 
                opnd.push(sum); 
                scaner();

                if( syn < 0 || syn == 5 || syn == 7 || syn == 9 )
                {
                    cout << "数字输入有误!" << endl;
                    flagLoop = true; // 重新输入
                }
                    
                break;
            case -1:
                cout << "  您在表达式中输入了不正确的字符!\n";
                flagLoop = true;  // 重新输入
                break;
            default:    
                
            

26 楼

    switch( prior[optr.top()][syn] )   
                {     
                case '>':  // 符号栈的第一个字符 比当前字符 的优先级高 进行计算
                    while( prior[optr.top()][syn] == '>')
                    {
                        double a, b, result;
                        a = opnd.top();
                        opnd.pop();
                        b = opnd.top();
                        opnd.pop();
                        
                        result = caculate( b, a, optr.top() );//删除 堆栈中的 第一个运算符
                        optr.pop();
                        
                        opnd.push( result );  // 将结果压入数据栈
                        
                    }
                    
                    if( prior[optr.top()][syn] == '<')
                    {
                        optr.push(syn);   // 运算符入栈

                        if( syn < 5)  // 当前符号是运算符
                        {                            
                            scaner();
                            if( syn != 11 && syn != 5 && syn != 7 && syn != 9 ) // 下一个字符不是数字、{、[、(
                            {
                                cout << "运算符后必须为数字!" << endl;
                                flagLoop = true; // 重新输入
                            }                        
                        }
                        else
                            scaner();
                    }
                    else if( prior[optr.top()][syn] == '=')
                    {
                        optr.pop();
                        scaner();
                    }
                    else
                    {
                        cout << " 运算符不配对!" << endl;
                        exit(0);
                    }
                    break;
                    
                

27 楼

case '<':
                    optr.push(syn);   // 运算符入栈                    
                    
                    if( syn < 5)  // 当前符号是运算符
                    {        
                        scaner();
                        if( syn != 11 && syn != 5 && syn != 7 && syn != 9 ) // 下一个字符不是数字、{、[、(
                        {
                            cout << "运算符后必须为数字!" << endl;
                            flagLoop = true;
                        }                        
                    }
                    else
                        scaner();
                    
                    break;
                case '=':
                    optr.pop();  //  删除运算符堆栈的字符
                    scaner();
                    break;
                    
                default:
                    flagLoop = true;  
                }
            }
        }
        
        if( flagLoop )
        {
            cout << "您输入的有误,请重新输入!" << endl;        
            cout << endl;
        }
        else
        {
            cout << "结果为:" << opnd.top() << endl;
            cout << endl;

            char choose;
            cout << "继续输入吗?(y/n): " << endl;
            cin >> choose;

        //    cout << choose << endl;
            if(choose == 'Y' || choose == 'y')
            {
                flagLoop = true;
                cin.getline(prog, 80);
            }
            else
                flagLoop = false;
        }        
    }
    return 0;  
}

28 楼

#include <stdio.h>
#include <string.h>
#include <conio.h>
#define PLUS 0
#define MINUS 1
#define POWER 2
#define DIVIDE 3
#define LEFTP 4
#define RIGHP 5
#define STARTEND 6
#define DIGIT 7
#define POINT 8
#define NUM 7
#define NO 32767
#define STACKSIZE 20
//运算符
   char a[] = {'+', '-', '*', '/', '(', ')', '#'};
   //优先关系矩阵,规定:=为0,>为1,<为-1, 空为NO
   int PriorityTables[7][7] = {{ 1, 1, -1, -1, -1, 1, 1},  
                              { 1, 1, -1, -1, -1, 1, 1},
                              { 1, 1,  1,  1, -1, 1, 1},
                              { 1, 1,  1,  1, -1, 1, 1},  
                              {-1,-1, -1, -1, -1, 0, NO},
                              { 1, 1,  1,  1, NO, 1, 1 },  
                              {-1,-1, -1, -1, -1, NO, 0}
                              };
   int menu(void);
/*--------------------------------------------*/
/*             输入表达式函数               */
/*--------------------------------------------*/
void InputExpression(char str[])
{ int len;
  printf("Input expression string:\n");
  scanf("%s",str);
  len = strlen(str);
  str[len]='#';
  str[len+1]='\0';
}
/*--------------------------------------------*/
/*              确定当前字符类型              */
/*--------------------------------------------*/
/*--------------------------------------------*/
/*若为运算符,则返回运算符在运算符数组中的序号 */
/* 若为数字字符,则返回DIGIT    */
/* 若为小数点字符,则返回POINT   */
/* 否则为非法字符,返回-1   */
/*--------------------------------------------*/
int GetCharType(char ch)
{int i;
 for(i=0;i<NUM;i++) if(ch==a[i]) return (i);
 if(ch>='0' && ch<='9') return (DIGIT);
 if(ch=='.')return(POINT);
 return (-1);
}

29 楼

#include<stdio.h>
{int a,b,c,sum;
scanf("%d,%d,%d"&a,&b,&c);
sum=a+b*c;
printf("%d",sum);
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册