運算元支援:多位元,小數
運算子支援:+ - * / ( )
#include<iostream.h>
#include<string.h>
#include<stdlib.h>
/*棧*/
template <class T>
class CStack
{
public:
int m_count;
T * m_arr;
int m_curposition;
CStack(int count)
{
m_arr = new T [count];
m_count = count;
m_curposition = -1;
}
bool push(T val)
{
if(m_curposition == m_count-1)
return false;
m_arr[++m_curposition] = val;
}
T pop()
{
if(IsEmpty())
return 0;
return m_arr[m_curposition--];
}
T GetElement()
{
if(IsEmpty())
return 0;
return m_arr[m_curposition];
}
bool IsEmpty()
{
if(m_curposition < 0)
return true;
return false;
}
~CStack()
{
delete [] m_arr;
}
};
/* 操作函數定義 */
bool ExpressionIsRight(char * pExpression); // 運算式是否正確
bool ProcessExpression(char * pExpression); // 處理運算式
int GetIndex(char ch); // 擷取操作符在數組中的下標
void Calculate(); // 計算
double GetResult(); // 得到結果
bool IsEnd(char ch); // 運算式是否結束
double GetNum(char *pStr, int & i); // 擷取運算元
CStack<char> stack_sign(100); // 運算子棧
CStack<double> stack_num(100); // 運算元棧
//運算子號優先順序表
int PriTbl[7][7]={
{1,1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,1,1},
{1,1,1,1,-1,1,1},
{1,1,1,1,-1,1,1},
{-1,-1,-1,-1,-1,0,2},
{1,1,1,1,2,1,1},
{-1,-1,-1,-1,-1,2,0}
};
void main()
{
char strExpression[100];
cout << "請輸入算術運算式:";
cin >> strExpression; // 輸入運算式
if(!ProcessExpression(strExpression)) // 處理運算式
{
cout << "運算式錯誤!" << endl;
}
else
cout << "計算結果:" << GetResult() << endl; // 輸出結果
}
bool ExpressionIsRight(char * pExpression)
{
int len = strlen(pExpression);
char arr[7] = {'+','-','*','/','(',')','.'};
for(int i=0; i<len; i++)
{
if(!(pExpression[i]>='0' && pExpression[i]<='9'))
{
if(pExpression[0] == '.' || pExpression[len-1] == '.')
return false;
int flag = 0;
for(int j=0; j<sizeof(arr); j++)
{
if(pExpression[i] == arr[j])
{
flag = 1;
break;
}
}
if(flag == 0)
return false;
}
}
return true;
}
bool ProcessExpression(char * pExpression)
{
if(!ExpressionIsRight(pExpression))
return false;
int len = strlen(pExpression);
pExpression[len++] = '#';
stack_sign.push('#');
if(len == 1)
return false;
for(int i=0; i<len; i++)
{
if(pExpression[i] >= '0' && pExpression[i] <= '9') // 運算元
{
double val = GetNum(pExpression, i);
stack_num.push(val);
}
else // 操作符
{
int pre = GetIndex(stack_sign.GetElement());
int next = GetIndex(pExpression[i]);
switch(PriTbl[pre][next])
{
case -1: // next > pre
stack_sign.push(pExpression[i]);
break;
case 0: // next = pre
if(IsEnd(pExpression[i]))
return true;
stack_sign.pop();
break;
case 1: // next < pre
Calculate();
i--; // back
break;
}
}
}
return true;
}
double GetNum(char *pStr, int & i)
{
char Nums[100];
int j = 0;
while((pStr[i] >= '0' && pStr[i] <= '9') || pStr[i]=='.')
Nums[j++] = pStr[i++];
i--;
Nums[j] = '\0';
return atof(Nums);
}
int GetIndex(char ch)
{
switch(ch)
{
case '+': return 0;
case '-': return 1;
case '*': return 2;
case '/': return 3;
case '(': return 4;
case ')': return 5;
case '#': return 6;
}
}
void Calculate()
{
double num1, num2;
num2 = stack_num.pop();
if(stack_num.IsEmpty())
{
cout << "運算式錯誤!" << endl;
exit(0);
}
num1 = stack_num.pop();
switch(stack_sign.pop())
{
case '+': stack_num.push(num1+num2);return;
case '-': stack_num.push(num1-num2);return;
case '*': stack_num.push(num1*num2);return;
case '/':
{
if(num2 == 0)
{
cout << "除數不能為0!程式終止!" << endl;
exit(0);
}
stack_num.push(num1/num2);
return;
}
}
}
bool IsEnd(char ch)
{
if(ch == '#')
if(stack_sign.GetElement() == ch)
return true;
return false;
}
double GetResult()
{
if(stack_sign.GetElement() != '#')
{
cout << "運算式錯誤!" << endl;
exit(0);
}
return stack_num.GetElement();
}