还剩下最后一个计算后则表达式的类。如果前面的类看明白了。那这个类的实现就是水到渠成了。它每次计算时根据对变量不同的真值指派而计算结果。下面给出接口:
这里关键是 Compute 方法的实现。前面说过。后则表达式会自动把普通的表达式转换成顺序执行的表达式。这样,Compute 方法只需要顺序计算表达式就可以了。变量的具体的值由此方法的参数来指明。唯一需要关心的就是如何判断操作符是一元还是二元的,从而调用不同的处理函数。下面是 Compute 方法的实现代码:
// omputer.h: interface for the Computer class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_OMPUTER_H__226BEEC7_8FDC_4FB3_90F2_7682D5B4BBB3__INCLUDED_)
#define AFX_OMPUTER_H__226BEEC7_8FDC_4FB3_90F2_7682D5B4BBB3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <vector>
#include <stack>
typedef int (*OptrFun)(int left, int right); // binary operator function type. default one.
typedef int (*UnaryOptrFun)(int value); // unary operator function type.
class Computer
{
public:
Computer(std::stack<char>& becExp, std::vector<char>& sortedValNames, char* szOptrTable, char* szUOptrTable, OptrFun* optrFuns, UnaryOptrFun* uoptrFuns);
virtual ~Computer();
public:
int Compute(std::vector<int>& line);
private:
std::stack<char> becExp;
std::vector<char> sortedValNames;
char* szOptrTable;
char* szUOptrTable;
OptrFun* optrFuns;
UnaryOptrFun* uoptrFuns;
private:
inline int GetIndex(char ch)
{
int i = 0;
while (szOptrTable[i] != 0)
{
if (szOptrTable[i] == ch)
{
return i;
}
i++;
}
return -1;
}
inline int GetUnaryOptrIndex(char ch)
{
int i = 0;
while (szUOptrTable[i] != 0)
{
if (szUOptrTable[i] == ch)
{
return i;
}
i++;
}
return -1;
}
inline int GetIndexOfVals(char ch)
{
int i = 0;
for (; i < sortedValNames.size(); i++)
{
if (ch == sortedValNames[i]) return i;
}
return -1;
}
};
#endif // !defined(AFX_OMPUTER_H__226BEEC7_8FDC_4FB3_90F2_7682D5B4BBB3__INCLUDED_)
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_OMPUTER_H__226BEEC7_8FDC_4FB3_90F2_7682D5B4BBB3__INCLUDED_)
#define AFX_OMPUTER_H__226BEEC7_8FDC_4FB3_90F2_7682D5B4BBB3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <vector>
#include <stack>
typedef int (*OptrFun)(int left, int right); // binary operator function type. default one.
typedef int (*UnaryOptrFun)(int value); // unary operator function type.
class Computer
{
public:
Computer(std::stack<char>& becExp, std::vector<char>& sortedValNames, char* szOptrTable, char* szUOptrTable, OptrFun* optrFuns, UnaryOptrFun* uoptrFuns);
virtual ~Computer();
public:
int Compute(std::vector<int>& line);
private:
std::stack<char> becExp;
std::vector<char> sortedValNames;
char* szOptrTable;
char* szUOptrTable;
OptrFun* optrFuns;
UnaryOptrFun* uoptrFuns;
private:
inline int GetIndex(char ch)
{
int i = 0;
while (szOptrTable[i] != 0)
{
if (szOptrTable[i] == ch)
{
return i;
}
i++;
}
return -1;
}
inline int GetUnaryOptrIndex(char ch)
{
int i = 0;
while (szUOptrTable[i] != 0)
{
if (szUOptrTable[i] == ch)
{
return i;
}
i++;
}
return -1;
}
inline int GetIndexOfVals(char ch)
{
int i = 0;
for (; i < sortedValNames.size(); i++)
{
if (ch == sortedValNames[i]) return i;
}
return -1;
}
};
#endif // !defined(AFX_OMPUTER_H__226BEEC7_8FDC_4FB3_90F2_7682D5B4BBB3__INCLUDED_)
这里关键是 Compute 方法的实现。前面说过。后则表达式会自动把普通的表达式转换成顺序执行的表达式。这样,Compute 方法只需要顺序计算表达式就可以了。变量的具体的值由此方法的参数来指明。唯一需要关心的就是如何判断操作符是一元还是二元的,从而调用不同的处理函数。下面是 Compute 方法的实现代码:
int Computer::Compute(vector<int>& line)
{
stack<char> tmpst;
while (!becExp.empty())
{
int ch = becExp.top();
int index = GetIndexOfVals(ch);
if (index != -1)
{
int val = line[index];
tmpst.push((char)(val + '0'));
becExp.pop();
continue;
}
tmpst.push(ch);
becExp.pop();
}
stack<int> retSt;
while (!tmpst.empty())
{
if (GetIndex(tmpst.top()) == -1)
{
retSt.push(tmpst.top() - '0');
tmpst.pop();
}
else
{
char opr = tmpst.top();
int uIndex = GetUnaryOptrIndex(opr);
if (uIndex != -1)
{
int val = retSt.top();
retSt.pop();
int ret = uoptrFuns[uIndex](val);
retSt.push(ret);
tmpst.pop();
}
else
{
int left = retSt.top();
retSt.pop();
int right = retSt.top();
retSt.pop();
int indexOfOptr = GetIndex(opr);
tmpst.pop();
int ret = optrFuns[indexOfOptr](left, right);
retSt.push(ret);
}
}
}
if (retSt.size() != 1) throw "Expression is not correct";
return retSt.top();
}
{
stack<char> tmpst;
while (!becExp.empty())
{
int ch = becExp.top();
int index = GetIndexOfVals(ch);
if (index != -1)
{
int val = line[index];
tmpst.push((char)(val + '0'));
becExp.pop();
continue;
}
tmpst.push(ch);
becExp.pop();
}
stack<int> retSt;
while (!tmpst.empty())
{
if (GetIndex(tmpst.top()) == -1)
{
retSt.push(tmpst.top() - '0');
tmpst.pop();
}
else
{
char opr = tmpst.top();
int uIndex = GetUnaryOptrIndex(opr);
if (uIndex != -1)
{
int val = retSt.top();
retSt.pop();
int ret = uoptrFuns[uIndex](val);
retSt.push(ret);
tmpst.pop();
}
else
{
int left = retSt.top();
retSt.pop();
int right = retSt.top();
retSt.pop();
int indexOfOptr = GetIndex(opr);
tmpst.pop();
int ret = optrFuns[indexOfOptr](left, right);
retSt.push(ret);
}
}
}
if (retSt.size() != 1) throw "Expression is not correct";
return retSt.top();
}