纯娱乐用的代码,效率很低!
Item类用来表示四则表达式的每个项,包括计算数和计算符;Expression类用来
表示整个四则表达式;Calculate类用来计算Expression。
四则表达式通过字符串形式输入,程序通过扫描字符串,分析表达式,然后计算出结果,并给出计算的每个步骤。
该程序是用来学习用,体会面向对象编程的思路,学习STL的使用,并无实际价值,有兴趣的朋友可将其继续完善。
Item.h
enum ItemType{UNKNOWN_ITEM_TYPE, OPERAND, ADDITION, SUBTRATION, MULTIPLICATION, DIVISION, LEFT_BRACKET, RIGHT_BRACKET};
bool IsNumeral(char c);
class Item
{
public:
Item();
virtual ~Item();
// 返回值:返回item的长度。0表示创建失败。
int CreateItem(const char* szExpression, int iIndex);
int GetType() const;
double ToDouble() const;
private:
char* m_pcItem;
int m_iSize;
ItemType m_Type;
};
Item.cpp
#include "Item.h"
#include <string>
//test
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
bool IsNumeral(char c)
{
if ((('0'<=c) && ('9' >= c)) || ('.' == c))
return true;
return false;
}
Item::Item()
{
m_pcItem = 0;
m_iSize = 0;
m_Type = UNKNOWN_ITEM_TYPE;
}
Item::~Item()
{
delete m_pcItem;
}
int Item::CreateItem(const char* szExpression, int iIndex)
{
int count = 0;
for (int i=0; ;++i)
{
char c = szExpression[iIndex+i];
if (c == '\0')
{
break;
}
if (IsNumeral(c))
{
if (m_Type == UNKNOWN_ITEM_TYPE)
{
m_Type = OPERAND;
}
else if (m_Type != OPERAND)
{
break;
}
++count;
}
else
{
if (m_Type == UNKNOWN_ITEM_TYPE)
{
switch(c)
{
case '+':
m_Type = ADDITION;
break;
case '-':
m_Type = SUBTRATION;
break;
case '*':
m_Type = MULTIPLICATION;
break;
case '/':
m_Type = DIVISION;
break;
case '(':
m_Type = LEFT_BRACKET;
break;
case ')':
m_Type = RIGHT_BRACKET;
break;
}
}
else
break;
++count;
break; // 默认操作符都只占一位
}
}
if (m_pcItem != 0)
{
delete m_pcItem;
m_pcItem = 0;
}
if (count > 0)
{
m_pcItem = new char[count+1];
memcpy(m_pcItem, &szExpression[iIndex], count);
m_pcItem[count] = '\0';
//test
cout << "createitem:" << m_pcItem << endl;
}
m_iSize = count;
return count;
}
int Item::GetType() const
{
return m_Type;
}
double Item::ToDouble() const
{
return atof(m_pcItem);
}
Expression.h
#include "Item.h"
#include <vector>
#include <stack>
using namespace std;
class Expression
{
public:
Expression(const char* szExpression, int size);
virtual ~Expression();
const vector<Item*>& GetItems();
private:
bool Scan();
void TrimSpace();
char* m_szExpression;
int m_iSize;
vector<Item*> m_pItems;
};
Expression.cpp
#include "Expression.h"
#include <stack>
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Expression::Expression(const char* szExpression, int size)
{
// m_szExpression = const_cast<char*>(szExpression);
m_szExpression = new char[size];
memcpy(m_szExpression, szExpression, size);
m_iSize = size;
TrimSpace();
Scan();
}
Expression::~Expression()
{
int count = m_pItems.size();
for (int i=0; i<count; ++i)
{
delete m_pItems[i];
}
delete [] m_szExpression;
}
void Expression::TrimSpace()
{
for (int i=0; i<m_iSize; ++i)
{
if (m_szExpression[i] == ' ')
{
for (int j=i+1; j<m_iSize; ++j)
{
m_szExpression[j-1] = m_szExpression[j];
if (m_szExpression[j] == '\0')
{
break;
}
}
}
}
}
bool Expression::Scan()
{
int iIndex = 0;
int iCount = 0;
for (;iIndex<m_iSize;)
{
Item* pItem = new Item();
iCount = pItem->CreateItem(m_szExpression, iIndex);
if (iCount > 0)
{
m_pItems.push_back(pItem);
iIndex += iCount;
}
else
return false;
}
return true;
}
const vector<Item*>& Expression::GetItems()
{
return m_pItems;
}
Calculate.h
#include "Item.h"
#include <vector>
#include <stack>
using namespace std;
class Calculate
{
class Process
{
public:
Process();
virtual ~Process();
void Push(const Item* item);
void Push(double operand);
double Result();
protected:
private:
void Compute(int type);
void Flush(int prior);
stack<double> m_Operands;
stack<int> m_Operations;
};
public:
Calculate();
virtual ~Calculate();
double Compute(const vector<Item*>& items);
};
Calculate.cpp
#include "alculate.h"
//test
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
int Priority[] = {0, 0, 1, 1, 2, 2, 0, 0};
Calculate::Calculate()
{
}
Calculate::~Calculate()
{
}
double Calculate::Compute(const vector<Item*>& items)
{
int ItemCount = items.size();
int type = 0;
double Result = 0;
stack<Process> processStack;
processStack.push(Process());
for (int i=0; i<ItemCount; ++i)
{
type = items[i]->GetType();
if (type == LEFT_BRACKET)
{
processStack.push(Process());
continue;
}
else if (type == RIGHT_BRACKET)
{
Result = processStack.top().Result();
processStack.pop();
processStack.top().Push(Result);
continue;
}
processStack.top().Push(items[i]);
}
Result = processStack.top().Result();
return Result;
}
//////////////////////////////////////////////////////////////////////////
// implement of class Process
//////////////////////////////////////////////////////////////////////////
Calculate::Process::Process()
{
}
Calculate::Process::~Process()
{
}
void Calculate::Process::Push(const Item* item)
{
int type = item->GetType();
if (type == OPERAND)
{
m_Operands.push(item->ToDouble());
}
else
{
if (!m_Operations.empty())
{
if (Priority[type] <= Priority[m_Operations.top()])
{
Flush(Priority[type]);
}
}
m_Operations.push(type);
}
}
void Calculate::Process::Push(double operand)
{
m_Operands.push(operand);
}
void Calculate::Process::Flush(int prior)
{
int type = 0;
while (!m_Operations.empty())
{
type = m_Operations.top();
if (prior <= Priority[type])
{
Compute(type);
m_Operations.pop();
}
else
{
break;
}
}
}
void Calculate::Process::Compute(int type)
{
double operand1 = 0;
double operand2 = 0;
if (!m_Operands.empty())
{
operand2 = m_Operands.top();
m_Operands.pop();
}
else
{
//异常
}
if (!m_Operands.empty())
{
operand1 = m_Operands.top();
m_Operands.pop();
}
else
{
//异常
}
double result;
switch(type)
{
case ADDITION:
result = operand1 + operand2;
//test
cout << operand1 << "+" << operand2 << "=" << result << endl;
break;
case SUBTRATION:
result = operand1 - operand2;
//test
cout << operand1 << "-" << operand2 << "=" << result << endl;
break;
case MULTIPLICATION:
result = operand1 * operand2;
//test
cout << operand1 << "*" << operand2 << "=" << result << endl;
break;
case DIVISION:
result = operand1 / operand2;
//test
cout << operand1 << "/" << operand2 << "=" << result << endl;
break;
default:
//异常
break;
}
m_Operands.push(result);
}
double Calculate::Process::Result()
{
Flush(0);
return m_Operands.top();
}
main.cpp
#include <iostream>
#include <string>
#include "Expression.h"
#include "alculate.h"
using namespace std;
void main()
{
cout << "hellow world" << endl;
char pBuffer[4096];
cin.getline(pBuffer, 4096);
Expression expres(pBuffer, 4096);
Calculate computor;
cout << computor.Compute(expres.GetItems()) << endl;
}