用 VC++编写程序,实现表达式的求值运算,程序实现适应采用堆栈数据结构。表达式的输入必须以字符串的形式输入;表达式包括基本的运算符号,+,-,*,\,表达式中包括括号的处理,括号可以嵌套。
有没有人能帮我完成这个程序啊?救命的啊!!!
那位大哥帮个忙啊
谢谢 阿
保证给你100分

解决方案 »

  1.   

    头文件Formula.h// Formula.h: interface for the CFormula class.
    // Write by Jony.huang 2003-11-10
    //////////////////////////////////////////////////////////////////////#if !defined(AFX_FORMULA_H__3244B7D0_9846_4028_8D74_F6D8F2010AF4__INCLUDED_)
    #define AFX_FORMULA_H__3244B7D0_9846_4028_8D74_F6D8F2010AF4__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000#include <Afxtempl.h>class CStackItem  
    {
    public:
    BOOL IsOperator();
    TCHAR chValue; // 作为运算符时的值,运算符:+ - * / ( )
    double fValue; // 作为数值时的值
    CStackItem(CStackItem &item);
    CStackItem(TCHAR _chValue);
    CStackItem(double _fValue);
    CStackItem();
    virtual ~CStackItem();
    CStackItem &operator =(CStackItem &item);
    CStackItem &operator =(TCHAR _chValue);
    CStackItem &operator =(double _fValue);
    BOOL operator ==(double _fValue);
    BOOL operator !=(double _fValue);
    BOOL operator ==(TCHAR _chValue);
    BOOL operator !=(TCHAR _chValue);
    BOOL operator >(TCHAR _chValue);
    BOOL operator <(TCHAR _chValue);
    BOOL operator >=(TCHAR _chValue);
    BOOL operator <=(TCHAR _chValue);protected:
    BOOL m_bIsOperator; // 判断是否为运算符, 默认值: FALSE
    };class CStack : public CList<CStackItem, CStackItem&>  
    {
    public:
    void Push(double fValue);
    void Push(TCHAR ch);
    BOOL Peek(CStackItem &item);
    BOOL Pop(CStackItem &item);
    void Push(CStackItem&item);
    CStack();
    virtual ~CStack();};class CFormula  
    {
    public:
    BOOL Execute(const CString &strVarName, double nVarName[], const CString &strForm, double &_fValue);
    CFormula(const CString &strVarName, double nVarName[],  const CString &strForm);
    CFormula();
    virtual ~CFormula();
    BOOL GetResult(double &_Value);

    protected:
    CString m_strVarName; // 变量名
    BOOL IsParam(TCHAR ch);
    BOOL ValidNumber(LPCTSTR szNumber);
    double m_fValue; // 计算结果
    BOOL m_bError; // 公式是否出错 void Clear();
    BOOL IsNumber(TCHAR ch);
    BOOL ValidChar(TCHAR ch);
    };#endif // !defined(AFX_FORMULA_H__3244B7D0_9846_4028_8D74_F6D8F2010AF4__INCLUDED_)
      

  2.   

    // Formula.cpp: implementation of the CFormula class.
    //
    //////////////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "Formula.h"
    #include <math.h>#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // CStackItem Class
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CStackItem::CStackItem()
    {
    chValue = '\x0';
    fValue = 0;
    m_bIsOperator = FALSE;}CStackItem::~CStackItem()
    {}CStackItem::CStackItem(double _fValue)
    {
    chValue = '\x0';
    fValue = _fValue;
    m_bIsOperator = FALSE;
    }CStackItem::CStackItem(TCHAR _chValue)
    {
    #ifdef _DEBUG
    // 判断_chValue是否合法
    LPCTSTR szScrope = _T("+-*/()");
    int i, nLen;
    nLen = ::lstrlen(szScrope);
    for(i = 0; i < nLen; i++)
    {
    if(_chValue == szScrope[i])
    break;
    } ASSERT(i != nLen);
    #endif
    fValue = 0;
    chValue = _chValue;
    m_bIsOperator = TRUE;
    }CStackItem::CStackItem(CStackItem &item)
    {
    chValue = item.chValue;
    fValue = item.fValue;
    m_bIsOperator = item.m_bIsOperator;
    }CStackItem &CStackItem::operator =(CStackItem &item)
    {
    chValue = item.chValue;
    fValue = item.fValue;
    m_bIsOperator = item.m_bIsOperator;
    return *this;
    }CStackItem &CStackItem::operator =(double _fValue)
    {
    fValue = _fValue;
    chValue = '\x0';
    m_bIsOperator = FALSE;
    return *this;
    }CStackItem &CStackItem::operator =(TCHAR _chValue)
    {
    chValue = _chValue;
    fValue = 0;
    m_bIsOperator = TRUE;
    return *this;
    }BOOL CStackItem::operator ==(double _fValue)
    {
    #ifdef _DEBUG
    ASSERT(!m_bIsOperator);
    #endif
    if(m_bIsOperator)
    return FALSE; return fValue == _fValue;
    }BOOL CStackItem::operator !=(double _fValue)
    {
    #ifdef _DEBUG
    ASSERT(!m_bIsOperator);
    #endif if(m_bIsOperator)
    return FALSE; return fValue != _fValue;}BOOL CStackItem::operator ==(TCHAR _chValue)
    {
    #ifdef _DEBUG
    ASSERT(m_bIsOperator);
    #endif if(!m_bIsOperator)
    return FALSE; return chValue == _chValue;
    }BOOL CStackItem::operator !=(TCHAR _chValue)
    {
    #ifdef _DEBUG
    ASSERT(m_bIsOperator);
    #endif if(!m_bIsOperator)
    return FALSE; return chValue != _chValue;}BOOL CStackItem::operator >(TCHAR _chValue)
    {
    #ifdef _DEBUG
    ASSERT(m_bIsOperator);
    #endif if(!m_bIsOperator)
    return FALSE; /* 
    只有chValue和_chValue其中一个为'('则不等式成立,
    因为'('没有比任何一个优先级高或低
    */
    if(chValue == '(' || _chValue =='(')
    return TRUE; if((chValue == '*' || chValue == '/') &&
    (_chValue == '+' || _chValue == '-'))
    return TRUE; return FALSE;}BOOL CStackItem::operator >=(TCHAR _chValue)
    {
    #ifdef _DEBUG
    ASSERT(m_bIsOperator);
    #endif if(!m_bIsOperator)
    return FALSE; /* 
    只有chValue和_chValue其中一个为'('则不等式成立,
    因为'('没有比任何一个优先级高或低
    */
    if(chValue == '(' || _chValue =='(')
    return TRUE; if((chValue == '*' || chValue == '/') &&
    (_chValue == '+' || _chValue == '-'))
    return TRUE;
    else
    if((chValue == '+' || chValue == '-') &&
    (_chValue == '+' || _chValue == '-'))
    return TRUE;
    if((chValue == '*' || chValue == '/') &&
    (_chValue == '*' || _chValue == '/'))
    return TRUE;
    return FALSE;}BOOL CStackItem::operator <(TCHAR _chValue)
    {
    #ifdef _DEBUG
    ASSERT(m_bIsOperator);
    #endif if(!m_bIsOperator)
    return FALSE; /* 
    只有chValue和_chValue其中一个为'('则不等式成立,
    因为'('没有比任何一个优先级高或低
    */
    if(chValue == '(' || _chValue =='(')
    return TRUE; if((_chValue == '*' || _chValue == '/') &&
    (chValue == '+' || chValue == '-'))
    return TRUE; return FALSE;}BOOL CStackItem::operator <=(TCHAR _chValue)
    {
    #ifdef _DEBUG
    ASSERT(m_bIsOperator);
    #endif if(!m_bIsOperator)
    return FALSE; /* 
    只有chValue和_chValue其中一个为'('则不等式成立,
    因为'('没有比任何一个优先级高或低
    */
    if(chValue == '(' || _chValue =='(')
    return TRUE; if((_chValue == '*' || _chValue == '/') &&
    (chValue == '+' || chValue == '-'))
    return TRUE;
    else
    if((_chValue == '*' || _chValue == '/') &&
    (chValue == '*' || chValue == '/'))
    return TRUE;
    else
    if((_chValue == '+' || _chValue == '-') &&
    (chValue == '+' || chValue == '-'))
    return TRUE; return FALSE;}
      

  3.   

    BOOL CStackItem::IsOperator()
    {
    return m_bIsOperator;
    }//////////////////////////////////////////////////////////////////////
    // CStack Class
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CStack::CStack()
    {
    }CStack::~CStack()
    {}void CStack::Push(CStackItem &item)
    {
    AddHead(item);
    }void CStack::Push(TCHAR ch)
    {
    CStackItem item(ch);
    Push(item);
    }void CStack::Push(double fValue)
    {
    CStackItem item(fValue);
    Push(item);
    }BOOL CStack::Pop(CStackItem &item)
    {
    #ifdef _DEBUG
    ASSERT(this->GetCount() > 0);
    #endif
    if(GetCount() == 0)
    return FALSE; item = this->RemoveHead();
    return TRUE;}BOOL CStack::Peek(CStackItem &item)
    {
    #ifdef _DEBUG
    ASSERT(this->GetCount() > 0);
    #endif
    if(GetCount() == 0)
    return FALSE; item = this->GetHead();
    return TRUE;}//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////CFormula::CFormula()
    {
    Clear();
    }CFormula::~CFormula()
    {}/*
    判断输入的字符是否为有效字符
    */
    BOOL CFormula::ValidChar(TCHAR ch)
    {
    // LWH分别代表长、宽、高
    CString szValidStr = _T("1234567890.+-*/()");
    int i, nLen;
    szValidStr += m_strVarName;
    nLen = szValidStr.GetLength();
    for(i = 0; i < nLen;i ++)
    if(ch == szValidStr[i])
    break; return i != nLen;}/*
    判断输入的字符是否为数字包括"."
    */
    BOOL CFormula::IsNumber(TCHAR ch)
    {
    LPCTSTR szValidStr = _T("1234567890.");
    int i, nLen;
    nLen = lstrlen(szValidStr);
    for(i = 0; i < nLen;i ++)
    if(ch == szValidStr[i])
    break; return i != nLen;}/*
    判断输入的字符是否为参数代号,L、W、H
    */
    BOOL CFormula::IsParam(TCHAR ch)
    {
    int i, nLen;
    nLen = m_strVarName.GetLength();
    for(i = 0; i < nLen;i ++)
    if(ch == m_strVarName[i])
    break; return i != nLen;}/*
    判断字符串是否为数值
    */
    BOOL CFormula::ValidNumber(LPCTSTR szNumber)
    {
    CString str;
    int i, j;
    str = szNumber;
    i = str.Find('.', 0);
    j = str.ReverseFind('.');
    return i == j;
    }CFormula::CFormula(const CString &strVarName, double nVarName[],  const CString &strForm)
    {
    m_strVarName = strVarName;
    Execute(strVarName, nVarName, strForm, m_fValue);}BOOL CFormula::GetResult(double &_Value)
    {
    _Value = m_fValue;
    return !m_bError;
    }
      

  4.   

    BOOL CFormula::Execute(const CString &strVarName, double nVarName[], const CString &strForm, double &_fValue)
    {
    int nBracket = 0; // 括号数数量
    int i, nLen; // strForm的指针当前位置和strForm的长度
    TCHAR ch;
    TCHAR prevch;
    CStack stack; // 堆栈
    CStack stack2;
    CStackItem curTopOperator; // 最近的一个运算符, 初始化为不是运算符即还没有运算符在Stack中
    CStackItem tmpItem;
    CMap<TCHAR, TCHAR, CStackItem, CStackItem&> map;
    double fValueInForm = 0; // 表达式中的由字符组成的数值
    double fValue;
    CString strValueInForm;
    BOOL bEnd = FALSE; // 完成 map.RemoveAll();
    m_strVarName = strVarName;
    for(i = 0; i < strVarName.GetLength(); i++)
    {
    map.SetAt(strVarName[i], CStackItem(nVarName[i]));
    } Clear();
    _fValue = 0;
    nLen = strForm.GetLength();
    i = 0;
    if(nLen == 0)
    {
    _fValue = 0;
    return TRUE;
    } prevch = '+'; // 初始化前一个字符不是数字
    do
    {
    if(i < nLen)
    {
    ch = strForm[i++];
    if(!this->ValidChar(ch))
    { // 无效字符,表达式出错
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    } if(IsNumber(ch))
    {
    strValueInForm += ch;
    prevch = ch;
    continue;
    }
    else
    if(IsParam(ch))
    {
    if(stack.GetCount() > 0)
    {
    stack.Peek(tmpItem);
    if(!tmpItem.IsOperator())
    { // 变量之前不是运算符则出错
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    } map.Lookup(ch, tmpItem);
    stack.Push(tmpItem);
    prevch = ch;
    continue;
    }
    else
    if(ch == '(')
    {
    if(stack.GetCount() > 0)
    {
    stack.Peek(tmpItem);
    if(!tmpItem.IsOperator())
    { // 括号之前不是运算符则出错
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    }
    stack.Push(ch);
    curTopOperator = ch;
    nBracket ++;
    continue;
    }
    else
    if(ch == ')')
    { // 对应最近一层的'('内的表达式进行计算并Push入Stack
    if(nBracket-- < 1)
    { // 没有对应的'('表达式错误
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    } if(IsNumber(prevch))
    {
    if(!ValidNumber(strValueInForm))
    {
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValueInForm = atof(strValueInForm);
    strValueInForm = _T("");
    stack.Push(fValueInForm);
    }
    else
    if(!(IsParam(prevch) || prevch == 'z'/* 'z'为中间变量 */))
    {
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    } // 同优先级的运算符就以表达式顺序计算
    // 存在高价运算符时就先计算高价
    CStackItem item;
    stack2.RemoveAll();
    while(1)
    {
    stack.Pop(item);
    if(item.IsOperator())
    {
    if(item == '(')
    {
    break;
    } if(item < curTopOperator.chValue)
    { // 存在高价运算符时就先计算高价
    CStackItem items[3];
    int k = 0;

    fValue = 0;
    while(1)
    {
    if(k == 3)
    {
    switch(items[1].chValue)
    {
    case '+':
    fValue = items[0].fValue + items[2].fValue;
    break;
    case '-':
    fValue = items[0].fValue - items[2].fValue;
    break;
    case '*':
    fValue = items[0].fValue * items[2].fValue;
    break;
    case '/':
    if(fabs(items[2].fValue) < 0.0000000000000001)
    { // 除数为零
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValue = items[0].fValue / items[2].fValue;
    }
    k = 0;
    stack2.Push(CStackItem(fValue));
    if(stack2.GetCount() == 1)
    { // 计算直到只得一个结果值为止
    // stack2.Pop(tmpItem);
    break;
    }
    }
    else
    {
    stack2.Pop(tmpItem);
    items[k++] = tmpItem;
    }
    } }
    curTopOperator = item.chValue;

    } stack2.Push(item); }
      

  5.   


    CStackItem items[3];
    int k = 0;

    fValue = 0;
    while(1)
    {
    if(k == 3)
    {
    switch(items[1].chValue)
    {
    case '+':
    fValue = items[0].fValue + items[2].fValue;
    break;
    case '-':
    fValue = items[0].fValue - items[2].fValue;
    break;
    case '*':
    fValue = items[0].fValue * items[2].fValue;
    break;
    case '/':
    if(fabs(items[2].fValue) < 0.0000000000000001)
    { // 除数为零
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValue = items[0].fValue / items[2].fValue;
    }
    k = 0;
    stack2.Push(CStackItem(fValue));
    if(stack2.GetCount() == 1)
    {
    stack2.Pop(tmpItem);
    break;
    }
    }
    else
    {
    if(stack2.GetCount())
    {
    stack2.Pop(tmpItem);
    items[k++] = tmpItem;
    }
    else
    break;
    }
    } if(stack.GetCount())
    stack.Peek(curTopOperator); // 取得'('之前的运算符:+-*/(
    else
    curTopOperator = 0.0;
    stack.Push(tmpItem);
    prevch = 'z'; // 代表中间变量
    continue;
    }
    else
    { // ch = +-*/ 运算符
    if(IsNumber(prevch))
    {
    if(!ValidNumber(strValueInForm))
    {
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValueInForm = atof(strValueInForm);
    strValueInForm = _T("");
    stack.Push(fValueInForm);
    }
    else
    if(!(IsParam(prevch) || prevch == 'z'/* 'z'为中间变量 */))
    {
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    } if(curTopOperator.IsOperator())
    { // stack 顶存在运算符
    tmpItem = ch;
    if(tmpItem >= curTopOperator.chValue)
    { // 说明当前运算符的优先级比stack顶的运算符要高或相等
    // 则只需Push入Stack即可
    stack.Push(tmpItem);
    curTopOperator = tmpItem;
    prevch = ch;
    }
    else
    { // 说明当前运算符的优先级stack顶的低,所要先对stack中高优先级的运算符
    // (这个过程直到遇到第一个"("运算符或到了stack空为止)放入一个对列中并进行计算,
    // 最后把计算结果累积后Push入stack,
    stack2.RemoveAll();
    CStackItem item;
    while(tmpItem < curTopOperator.chValue &&
    curTopOperator != '(' &&
    stack.GetCount() > 0)
    {
    stack.Pop(item);
    if(item.IsOperator())
    {
    curTopOperator = item.chValue;
    if(item == '(' || tmpItem >= curTopOperator.chValue)
    {
    stack.Push(item);
    continue;
    }
    } stack2.Push(item); } CStackItem items[3];
    int k = 0;

    fValue = 0;
    while(1)
    {
    if(k == 3)
    {
    switch(items[1].chValue)
    {
    case '+':
    fValue = items[0].fValue + items[2].fValue;
    break;
    case '-':
    fValue = items[0].fValue - items[2].fValue;
    break;
    case '*':
    fValue = items[0].fValue * items[2].fValue;
    break;
    case '/':
    if(fabs(items[2].fValue) < 0.0000000000000001)
    { // 除数为零
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValue = items[0].fValue / items[2].fValue;
    }
    k = 0;
    stack2.Push(CStackItem(fValue));
    if(stack2.GetCount() == 1)
    {
    stack2.Pop(tmpItem);
    break;
    }

    }
    else
    {
    if(stack2.GetCount())
    {
    stack2.Pop(tmpItem);
    items[k++] = tmpItem;
    }
    else
    break;
    }
    }
    stack.Push(tmpItem);
    stack.Push(ch);
    curTopOperator = ch;
    prevch = ch;
    }
    }
    else // if(curTopOperator.IsOperator())
    {
    stack.Push(ch);
    curTopOperator = ch;
    prevch = ch;
    }
    }
    }
    else
    { // 对stack进行Pop处理
    if(nBracket > 0)
    { // 有括号没有处理,说明表达式出错
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    } if(IsNumber(prevch))
    {
    if(!ValidNumber(strValueInForm))
    {
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValueInForm = atof(strValueInForm);
    strValueInForm = _T("");
    stack.Push(fValueInForm);
    }
    else
    if(!(IsParam(prevch) || prevch == 'z'/* 'z'为中间变量 */))
    {
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    } _fValue = 0;
    stack2.RemoveAll();
    while(stack.GetCount() > 0)
    {
    CStackItem item;
    stack.Pop(item);
    if(item.IsOperator())
    {
    if(item < curTopOperator.chValue)
    { // 存在高价运算符时就先计算高价
    CStackItem items[3];
    int k = 0;

    fValue = 0;
    while(1)
    {
    if(k == 3)
    {
    switch(items[1].chValue)
    {
    case '*':
    fValue = items[0].fValue * items[2].fValue;
    break;
    case '/':
    if(fabs(items[2].fValue) < 0.0000000000000001)
    { // 除数为零
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValue = items[0].fValue / items[2].fValue;
    }
    k = 0;
    stack2.Push(CStackItem(fValue));
    if(stack2.GetCount() == 1)
    { // 计算直到只得一个结果值为止
    break;
    }
    }
    else
    {
    stack2.Pop(tmpItem);
    items[k++] = tmpItem;
    }
    } } curTopOperator = item.chValue;
    } stack2.Push(item); } CStackItem items[3];
    int k = 0;

    fValue = 0;
    while(1)
    {
    if(k == 3)
    {
    switch(items[1].chValue)
    {
    case '+':
    fValue = items[0].fValue + items[2].fValue;
    break;
    case '-':
    fValue = items[0].fValue - items[2].fValue;
    break;
    case '*':
    fValue = items[0].fValue * items[2].fValue;
    break;
    case '/':
    if(fabs(items[2].fValue) < 0.0000000000000001)
    { // 除数为零
    m_bError = TRUE;
    _fValue = 0;
    return FALSE;
    }
    fValue = items[0].fValue / items[2].fValue;
    }
    k = 0;
    stack2.Push(CStackItem(fValue));
    if(stack2.GetCount() == 1)
    {
    stack2.Pop(tmpItem);
    break;
    }
    }
    else
    {
    if(stack2.GetCount())
    {
    stack2.Pop(tmpItem);
    items[k++] = tmpItem;
    }
    else
    break;
    }
    } _fValue = tmpItem.fValue; // 完成!
    bEnd = TRUE;
    } }while(!bEnd);
    return TRUE;
    }void CFormula::Clear()
    {
    m_fValue = 0;
    m_bError = FALSE;
    }