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





















Item.cpp























































































































Expression.h






















Expression.cpp









































































Calculate.h


































Calculate.cpp











































































































































































main.cpp



















