解决这个程序有100分给你 用 VC++编写程序,实现表达式的求值运算,程序实现适应采用堆栈数据结构。表达式的输入必须以字符串的形式输入;表达式包括基本的运算符号,+,-,*,\,表达式中包括括号的处理,括号可以嵌套。有没有人能帮我完成这个程序啊?救命的啊!!!那位大哥帮个忙啊谢谢 阿保证给你100分 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 头文件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_) // Formula.cpp: implementation of the CFormula class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "Formula.h"#include <math.h>#ifdef _DEBUG#undef THIS_FILEstatic 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;} 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;} 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); } 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;} 还是指针的问题 MFC窗体最大化后怎么挡住了开始菜单?如何显示下面的开始菜单? 请教!关于视图切割问题。手头一个项目,有意共同开发者请进。 为什么用HtmlHelp函数调出Context Help窗口,再点击对话框其它部分,使弹出的窗口消失,只要一点击就会报错?? 在VC++中ado 连接mysql用ODBC的出错问题?(高手请进) 这是什么码? MSMQ初学者问题 声卡使用??? .ini文件的写问题。 请问那里可以下载最新的Linux内核源码?谢谢! VC5下使用EnumWindows的问题 关于tagVARIANT的问题
// 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_)
//
//////////////////////////////////////////////////////////////////////#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;}
{
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;
}
{
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); }
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;
}