匿名使用者
匿名使用者 發問時間: 電腦與網際網路程式設計 · 2 0 年前

程式設計題目(請使用C語言)......

請寫一程式可接受四則運算式並計算其結果,如: 「 (5+6)*117-88/4」之結果為1265。

2 個解答

評分
  • SiYu
    Lv 5
    2 0 年前
    最佳解答

    C++ 的code .. 請參考

    /*

    compiler : VC++

    把中序轉後序

    輸入的字串必須都以空白分格

    如: 1 + 2 + 3

    function 必須如此輸入, function 區分大小寫

    如: fun( 123 )

    example

    1 + 2 >= 4 + 5

    support 運算

    + - * / %

    >= <= && || == !=

    | &

    IFF( a , b , c ) 如果 a != 0 return b other c

    Max( a , b ) if ( a > b ) then a other b

    Min( a , b ) if ( a < b ) then a other b

    只能用在整數運算

    example

    Please input expression :4 + Max( 5 , 6 )

    Postfix: 4 5 6 Max +

    Result : 10

    */

    #include <stack>

    #include <string>

    #include <assert.h>

    const char* d_zTokenDim="\n\t ";

    typedef std::stack<int> DBStack;

    typedef void (*OPFunction)(DBStack& );

    #define MAX_OPName 30

    struct OP

    {

    char m_zOP[MAX_OPName]; // OP name + - * / ..

    int m_nPriority;// 優先順序

    int m_nOPNumber;// 需要幾個運算子 如 + 要兩個 a + b

    OPFunction m_pOPFun;// 運算的function

    };

    #define FUN (-1)

    #define LeftC (-2)

    class OPRError

    {

    public:

    OPRError(const char* zError)

    {

    strcpy(zErrorMsg,zError);

    }

    OPRError(const OPRError& rhs)

    {

    strcpy(zErrorMsg,rhs.zErrorMsg);

    }

    char zErrorMsg[1000];

    };

    void Add(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A+B);

    }

    void Sub(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A-B);

    }

    void Mul(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A*B);

    }

    void Div(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    if( B == 0 ) throw OPRError("Div By zero");

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A/B);

    }

    void Mod(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    if( B == 0 ) throw OPRError("Div By zero");

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A%B);

    }

    void Or(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A|B);

    }

    void And(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A&B);

    }

    void Max(DBStack& a_stack) // A, B 的max

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A > B )

    a_stack.push(A);

    else

    a_stack.push(B);

    }

    void Min(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A > B )

    a_stack.push(B);

    else

    a_stack.push(A);

    }

    void IFF(DBStack& a_stack) // IFF(a,b,c) a !=0 IFF = b, a=0 IFF = c

    {

    DBStack::value_type A;

    DBStack::value_type B;

    DBStack::value_type C;

    C=a_stack.top();

    a_stack.pop();

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A != 0 ) a_stack.push(B);

    else a_stack.push(C);

    }

    // >

    void Big(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A > B ) a_stack.push(1);

    else a_stack.push(0);

    }

    // >=

    void BigEqu(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A >= B ) a_stack.push(1);

    else a_stack.push(0);

    }

    // ==

    void Equ(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A == B ) a_stack.push(1);

    else a_stack.push(0);

    }

    // <=

    void SmallEqu(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A <= B ) a_stack.push(1);

    else a_stack.push(0);

    }

    // <

    void Small(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A < B ) a_stack.push(1);

    else a_stack.push(0);

    }

    // !=

    void NotEqu(DBStack& a_stack)

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    if( A != B ) a_stack.push(1);

    else a_stack.push(0);

    }

    void BoolAnd(DBStack& a_stack) // &&

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A&&B);

    }

    void BoolOr(DBStack& a_stack) // ||

    {

    DBStack::value_type A;

    DBStack::value_type B;

    B=a_stack.top();

    a_stack.pop();

    A=a_stack.top();

    a_stack.pop();

    a_stack.push(A||B);

    }

    OP g_opTable[] = {

    { "(" , LeftC , 0 , NULL } ,

    { "&&" , 1 , 2 , BoolAnd },

    { "||" , 1 , 2 , BoolOr },

    { "==" , 2 , 2 , Equ },

    { "!=" , 2 , 2 , NotEqu },

    { ">" , 3 , 2 , Big },

    { ">=" , 3 , 2 , BigEqu },

    { "<=" , 3 , 2 , SmallEqu },

    { "<" , 3 , 2 , Small },

    { "|" , 4 , 2 , Or },

    { "&" , 4 , 2 , And },

    { "+" , 5 , 2 , Add },

    { "-" , 5 , 2 , Sub },

    { "*" , 6 , 2 , Mul },

    { "/" , 6 , 2 , Div },

    { "%" , 6 , 2 , Mod },

    { "," , 0 , 0 , NULL },

    { "Max" , FUN , 2 , Max },

    { "Min" , FUN , 2 , Min },

    { "IFF" , FUN , 3 , IFF }

    };

    static const OP* FindOP(const char* a_zToken)

    {

    assert(a_zToken!=NULL);

    const int nOps=sizeof(g_opTable)/sizeof(OP);

    for( int i = 0 ; i < nOps ; ++i)

    {

    if( strcmp(g_opTable[i].m_zOP,a_zToken) == 0 )

    return g_opTable+i;

    }

    return NULL;

    }

    static char* Append(char* o_zResult,const char* a_zToken)

    {

    assert(o_zResult!=NULL);

    assert(a_zToken!=NULL);

    for( ; (*a_zToken) != '\0' ; ++o_zResult,++a_zToken)

    {

    (*o_zResult)=(*a_zToken);

    }

    (*o_zResult)=' ';

    ++o_zResult;

    return o_zResult;

    }

    bool ToPostFix(const char* a_zInput,char* o_zOutput)

    {

    assert( a_zInput != NULL);

    assert( o_zOutput != NULL);

    std::stack<const OP*> stOP;

    int nL=strlen(a_zInput);

    char *zBuffer=new char[nL+1];

    std::auto_ptr<char> ppp(zBuffer);

    strcpy(zBuffer,a_zInput);

    o_zOutput[0]='\0';

    char *zToken=strtok(zBuffer,d_zTokenDim);

    for( ; zToken != NULL ; zToken=strtok(NULL,d_zTokenDim) )

    {

    nL=strlen(zToken);

    if( nL > 1 && zToken[nL-1] == '(' )

    {

    zToken[nL-1]='\0';

    --nL;

    }

    if( zToken[0] == ')' ) // test is ')'

    {

    do{ // pop all OP until '(' or a function

    if( stOP.empty() ) return false; // 沒有 '('

    if( (stOP.top()->m_nPriority) < 0 )

    {// 找到 '(' 或是function

    if( stOP.top()->m_nOPNumber != 0 )

    {

    o_zOutput=Append(o_zOutput,stOP.top()->m_zOP);

    }

    stOP.pop();

    break;

    }

    else

    { // 輸出op

    o_zOutput=Append(o_zOutput,stOP.top()->m_zOP);

    stOP.pop();

    }

    }while(1);

    }

    else

    {

    const OP* pOP=FindOP(zToken);

    if( pOP != NULL ) // test 是否找到OP

    {// 找到了

    if( pOP->m_nPriority < 0 ) // <0 為 '(' 或是function 直接push 到OP stack

    {

    stOP.push(pOP);

    continue;

    }

    // 不是 '(' 或是 function

    while( (!stOP.empty()) && (stOP.top()->m_nPriority) >= (pOP->m_nPriority) )

    {

    // strck top 的 運算優先順序 比目前的大 .. pop stack top

    o_zOutput=Append(o_zOutput, stOP.top()->m_zOP);

    stOP.pop();

    }

    if( (pOP->m_nOPNumber) != 0 ) // 將目前的op 推到stack 中

    {

    stOP.push(pOP);

    }

    }

    else

    { // 沒有找到 當做數字處理

    o_zOutput=Append(o_zOutput,zToken);

    }

    }

    } // end of for zToken = ...

    // pop all stOP

    while( !stOP.empty() )

    {

    if( stOP.top()->m_nPriority == LeftC ) return false; // 為'(' 有問題

    o_zOutput=Append(o_zOutput, stOP.top()->m_zOP);

    stOP.pop();

    }

    *o_zOutput='\0';

    return true;

    }

    //T is a function or Pred change string to number

    template <class T> bool CalcPostfix(const char* a_zPostFix,int* o_pnResult,T toNumber)

    {

    assert( a_zPostFix != NULL );

    assert( o_pnResult != NULL );

    char *zBuffer = new char [strlen(a_zPostFix)+1];

    std::auto_ptr<char> pppp(zBuffer); //// pppp will auto delete zBuffer when function return

    strcpy(zBuffer,a_zPostFix);

    char *zToken=strtok(zBuffer,d_zTokenDim);

    DBStack stOPR; // 運算子stack

    for( ; zToken != NULL ; zToken =strtok(NULL,d_zTokenDim) )

    {

    const OP* pOP=FindOP(zToken); // 找尋OP

    if( pOP == NULL )

    {// 沒有找到把zToken 當做是數字, 推到stack 中

    stOPR.push(toNumber(zToken));

    }

    else

    { // 找到了

    if( pOP->m_nOPNumber == 0 || pOP->m_pOPFun == NULL ) return false; // 錯誤運算

    if( stOPR.size() < pOP->m_nOPNumber ) return false; // 運算子不夠多

    pOP->m_pOPFun(stOPR);

    }

    } // // end of for zToken = ...

    if( stOPR.size() != 1 ) return false;

    *o_pnResult=stOPR.top();

    return true;

    }

    //// Main Program

    #include <iostream>

    #include <stdlib.h>

    void main()

    {

    char zInFix[1000];

    char zPosFix[1000];

    std::cout << "Please input expression :";

    std::cin.getline(zInFix,1000);

    if( ToPostFix(zInFix,zPosFix) )

    {

    std::cout << "Postfix: ";

    std::cout << zPosFix << std::endl;

    }

    else

    {

    std::cout << "Have error";

    return;

    }

    int nResult;

    try{

    if( CalcPostfix(zPosFix,&nResult,atoi) )

    {

    std::cout << "Result : " << nResult;

    }

    else

    {

    std::cout << "Have some error";

    }

    }

    catch(OPRError& error)

    {

    std::cout << error.zErrorMsg;

    }

    }

    參考資料: MYSAFE
  • ?
    Lv 6
    2 0 年前

    # 中序式轉後序式(前序式)

    http://caterpillar.onlyfun.net/Gossip/AlgorithmGos...

    # 後序式的運算

    http://caterpillar.onlyfun.net/Gossip/AlgorithmGos...

    多看多瞭解。。。

還有問題?馬上發問,尋求解答。