C++ 四则运算
严格照搬了严蔚敏的<数据结构>
代码逻辑未作任何修改…使用正则做公式有效性判断…
CParse::CParse()
{
/*********************************************************************/
// 符号定义
/*********************************************************************/
m_vecSign.push_back(std::make_pair(_T("("), 0));
m_vecSign.push_back(std::make_pair(_T(")"), 1));
m_vecSign.push_back(std::make_pair(_T("*"), 2));
m_vecSign.push_back(std::make_pair(_T("/"), 2));
m_vecSign.push_back(std::make_pair(_T("+"), 3));
m_vecSign.push_back(std::make_pair(_T("-"), 3));
m_vecSign.push_back(std::make_pair(_T("#"), 4));
/*********************************************************************/
// 符号优先级定义
// -1 < // 0 = // 1 >
// 2 error
/*********************************************************************/
m_vecPriority.resize(5);
m_vecPriority[0].resize(5);
m_vecPriority[0][0] = -1;
m_vecPriority[0][1] = 0;
m_vecPriority[0][2] = -1;
m_vecPriority[0][3] = -1;
m_vecPriority[0][4] = 2;
m_vecPriority[1].resize(5);
m_vecPriority[1][0] = 2;
m_vecPriority[1][1] = 1;
m_vecPriority[1][2] = 1;
m_vecPriority[1][3] = 1;
m_vecPriority[1][4] = 1;
m_vecPriority[2].resize(5);
m_vecPriority[2][0] = -1;
m_vecPriority[2][1] = 1;
m_vecPriority[2][2] = 1;
m_vecPriority[2][3] = 1;
m_vecPriority[2][4] = 1;
m_vecPriority[3].resize(5);
m_vecPriority[3][0] = -1;
m_vecPriority[3][1] = 1;
m_vecPriority[3][2] = -1;
m_vecPriority[3][3] = 1;
m_vecPriority[3][4] = 1;
m_vecPriority[4].resize(5);
m_vecPriority[4][0] = -1;
m_vecPriority[4][1] = 2;
m_vecPriority[4][2] = -1;
m_vecPriority[4][3] = -1;
m_vecPriority[4][4] = 0;
}
CParse::~CParse()
{
}
BOOL CParse::ParseString( const CString &strOld, const std::map &data, double &fResultValue )
{
// 此处为了性能不做有效性判断
CString strNew = _T("");
strNew.Format(_T("#%s#"), strOld);
/*********************************************************************/
// 解析堆栈
/*********************************************************************/
std::stack OPTR; // 运算符栈
std::stack OPND; // 操作数栈
/*********************************************************************/
// 分割
/*********************************************************************/
int nFind = -1;
while (0 < strNew.GetLength()) {
// 找从解析起始位置开始,最近的操作符
pair_SIGN pairSign;
nFind = strNew.GetLength();
BOOST_FOREACH(pair_SIGN tmp, m_vecSign)
{
int nTmp = strNew.Find(tmp.first);
if(-1 == nTmp) continue;
if(nFind > nTmp)
{
pairSign = tmp;
nFind = nTmp;
}
}
// 操作数进栈
CString strOperand = strNew.Left(nFind);
if(!strOperand.IsEmpty())
{
double fValue = atof(strOperand.Trim());
OPND.push(fValue);
}
strNew = strNew.Right(strNew.GetLength() - strOperand.GetLength());
if(0 < strNew.GetLength()) {
// 操作符判断
label:
if(OPTR.empty())
{
// 如果操作符栈为空,则直接入栈
OPTR.push(pairSign);
}
else
{
ASSERT(OPTR.size() > 0);
if(OPTR.size() == 0) return FALSE;
// 不为空,则判断当前取到的操作符与栈顶的操作符的优先级
switch(m_vecPriority[OPTR.top().second][pairSign.second])
{
case -1 :
{
// 栈顶元素优先级比较低
// 继续压栈
OPTR.push(pairSign);
break;
}
case 0 :
{
// 碰到匹配的括号或者字符串首尾相遇
OPTR.pop();
break;
}
case 1 :
{
ASSERT(OPND.size() > 1);
if(OPND.size() < 2) return FALSE;
// 栈顶操作符优先级高于当前获取的操作符
// 进行栈顶元素的计算
double fLeft, fRight;
fRight = OPND.top();
OPND.pop();
fLeft = OPND.top();
OPND.pop();
double fValue = 0.0f;
if(!Calc(fLeft, fRight, OPTR.top().first, fValue)) return FALSE;
OPND.push(fValue);
OPTR.pop();
goto label;
}
case 2 :
default:
{
ASSERT(FALSE);
break;
}
}
}
}
strNew = strNew.Right(strNew.GetLength() - pairSign.first.GetLength());
}
if(0 == OPTR.size() && 1 == OPND.size())
{
return TRUE;
}
return FALSE;
}
BOOL CParse::Calc( double fLeft, double fRight, CString strSign, double &fValue )
{
if(0 == strSign.CompareNoCase(_T("+")))
{
fValue = fLeft + fRight;
}
else if(0 == strSign.CompareNoCase(_T("-")))
{
fValue = fLeft - fRight;
}
else if(0 == strSign.CompareNoCase(_T("*")))
{
fValue = fLeft * fRight;
}
else if(0 == strSign.CompareNoCase(_T("/")))
{
fValue = fLeft / fRight;
}
else
{
return FALSE;
}
return TRUE;
}
BOOL CParse::IsValidID( const CString &strOld )
{
CString sCheck = _T("([+-*/]{2,})|([+-*/]\))|(^[+-*/])|([+-*/]$)");
CRegexpT regexp(sCheck);
MatchResult result = regexp.MatchExact(strOld);
if(result.IsMatched()) return FALSE;
return TRUE;
}
使用正则做公式有效性判断…