纯娱乐用的代码,效率很低!
Item类用来表示四则表达式的每个项,包括计算数和计算符;Expression类用来
表示整个四则表达式;Calculate类用来计算Expression。
四则表达式通过字符串形式输入,程序通过扫描字符串,分析表达式,然后计算出结果,并给出计算的每个步骤。
该程序是用来学习用,体会面向对象编程的思路,学习STL的使用,并无实际价值,有兴趣的朋友可将其继续完善。
Item.h
Item.cpp
Expression.h
Expression.cpp
Calculate.h
Calculate.cpp
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;
}
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;
};
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);
}
#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;
};
#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;
}
#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);
};
#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();
}
// 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;
}