#include<iostream>
#include<string>
#include"exam-4h.h"
using namespace std;
Calculation::Calculation(const string& exp)
{
expression=exp;
length=exp.length();
turnToTag();
firstExpPtr=NULL;
lastExpPtr=NULL;
}
Calculation::~Calculation()
{
delete []tag;
if(firstExpPtr!=NULL)
{
while(firstExpPtr->next!=NULL)
{
NODE* temptr;
temptr=firstExpPtr;
firstExpPtr=firstExpPtr->next;
delete temptr;
}
}
delete firstExpPtr;
lastExpPtr=NULL;
delete lastExpPtr;
}
bool Calculation::examExpression() //表达式是否合法;
{
int i=0;
if(!examBraches() || !examDot()) //当小数点位置合法且括号不匹配时
return false;
while(i<length) //循环直到表达式中最后一个字符
{
if(!nextWord(i)) //当当前字符与其后的字符不匹配时
break; //跳出循环
i++; //指针指向下一个字符位置
}
if(i<length) //当指针不是指向最后字符的后一个位置时
return false;
else
return true;
}
void Calculation::setExpression(const string& exp) //重新设置表达式
{
expression=exp;
length=exp.length();
if(tag) //如果tag指针指向数组时
{
int *t;
t=tag;
delete t; //释放tag所指的数组
}
turnToTag(); //将新表达式中字符转换成数值标志
}
//当前字符是数字时则下一个字符必须是:‘.’或运算符,或数字或右括号
//当前字符是运算符时则下一个字符必须是:表示负号的‘-’或数字或左括号
//当前字符是左括号时则下一个字符必须是:表示负号的‘-’或数字
//当前字符是右括号则下一个字符必须是:运算符
//当前字符是'.'号且不是最后一个字符时则下一个字符必须是:数字或运算符或右括号
bool Calculation::nextWord(int place) //下一个字符与当前字符是否关系是否正确
{
int word;
word=tag[place];
switch (word)
{
case 1: //当前字符是数字时
{
if(place==length-1) //最后的字符是数字时
return true;
else if(tag[place+1]==1||tag[place+1]==2||tag[place+1]==4||tag[place+1]==5)
return true;
return false;
}
case 2: //当前字符是运算符时
{
if(tag[place+1]==1||tag[place+1]==3)
return true;
else if(expression[place+1]=='-' && tag[place+2]==1)
return true;
return false;
}
case 3: //当前字符是左括号时
{
if(tag[place+1]==1 ||tag[place+1]==3)
return true;
else if(expression[place+1]=='-' && tag[place+2]==1)
return true;
return false;
}
case 4: //当前字符是右括号
{
if(place==length-1) //当前是最后一个字符时
return true;
if(tag[place+1]==2 || tag[place+1]==4)
return true;
return false;
}
case 5: //当前字符是'.'号时
{
if(place==length-1)
return true;
else if(tag[place+1]==2||tag[place+1]==1 ||tag[place+1]==4) //运算符,数字,右括号
return true;
return false;
}
default:
return false;
}//end switch
}
bool Calculation::examBraches() //检查括号是否匹配
{
int leftBracket=0,rightBracket=0; //leftBracket记录左括号的数量,rightBracket记录右括号的数量;
int i=0;
while(i<length) //循环直到表达式中最后一个字符
{
if(rightBracket>leftBracket) //当右括号数目多于左括号
return false;
if(tag[i]==3) //当前字符是左括号时
{
leftBracket++;
}
else if(tag[i]==4) //当前字符是右括号时
{
rightBracket++;
}
i++;
}
if(rightBracket==leftBracket) //左右括号数量一样时
return true;
return false;
}
bool Calculation::examDot() //检查小数点位置是否合法
{
string str=expression;
int current=0,prev,later; //prev指向小数点以前的字符位置,later指向小数点以后的字符位置
// bool dot=0;
while(current<length) //循环直到表达式中最后一个字符
{
if(tag[current]==6)
return false;
else if(tag[current]==5) //当前字符是'.'时
{
// dot=1;
prev=current-1; //初始化prev,later分别为当前小数点位置的前一字符和后一字符
later=current+1;
if(tag[prev]!=1) //当小数点前后都没有数字时--说明只有小数点不是数
return false;
while(prev>=0 && later<length) //循环直到指针指向表达式最前与最后的位置
{
if(tag[prev]==1 && tag[later]==1) //当prev,later所指的字符都是数字时
{
prev--; //prev指针前移,
later++; //later指针后移
continue;
}
else if(tag[prev]==5 || tag[later]==5) //当prev,later所指的字符其中之一是小数点时--说明一数字里含有两个以上小数点
return false;
else if(tag[prev]==1) //当prev所指的字符是数字,later所指的字符不是数字
{
prev--; //prev指针前移
continue;
}
else if(tag[later]==1) //当prev所指的字符不是数字,later所指的字符是数字
{
later++; //later指针后移
continue;
}
else if((tag[prev]==2 && tag[later]==2)||(tag[prev]==2 && tag[later]==4)||(tag[prev]==3 && tag[later]==2)) //当prev,later所指的字符都是是运算符时--说明该数字中只含有一个小数点
{ //
return true;
}
}//end while
}//end if
current++;
}//end while
return true;
}
void Calculation::turnToTag() //将算术表达式中字符分类并储存
{
tag=new int[expression.length()];
for(int i=0;i<length;i++)
{
if(expression[i]>='0' && expression[i]<='9')
tag[i]=1;
else if(expression[i]=='*' || expression[i]=='+'|| expression[i]=='-' || expression[i]=='/')
tag[i]=2;
else if(expression[i]=='(')
tag[i]=3;
else if(expression[i]==')')
tag[i]=4;
else if(expression[i]=='.')
tag[i]=5;
else
tag[i]=6; //illeger character;
}
}
void Calculation::show()
{
cout<<expression<<" ";
cout<<"的长度是:"<<length<<endl;
cout<<"各字符的所属类别是:";
for(int i=0;i<length;i++)
{
cout<<tag[i]<<" ";
}
cout<<endl;
if(firstExpPtr!=NULL) //如果表达式链表的头指针不为空时
{
NODE* temptr=firstExpPtr;
while(temptr!=NULL) //循环直到指针所指为空
{
if(temptr->t==NUM)
cout<<temptr->num<<endl;
else
cout<<temptr->sign<<endl;
temptr=temptr->next;
}
cout<<endl;
temptr=NULL;
delete temptr;
}
else
cout<<"您尚未输入表达式。"<<endl;
double result;
if(CalExpressionResult(&result)) //如果表达式计算未出错
{
cout<<expression<<"="<<result<<endl;
}
else
cout<<"计算出错!"<<endl;
}
void Calculation::extraction()
{
char numStr[20]; //用于存储从运算表达式中提取的数字字符串
int n_str_p=0; //同一数字字符串中的某一位
int dotplace=0; //小数点在数字字符串中的位置
int i;
int len=0; //当前数字字符串的长度
double result; //当前所提取的数字串的值
for(i=0;i<length;i++)
{
if(tag[i]==1 || tag[i]==5) //如果当前字符是数字则直接存入数字字符串中
{
numStr[n_str_p]=expression[i];
len++;
if(tag[i]==5) //如果当前字符是小数点
{
dotplace=n_str_p; //纪录小数点位置
}
n_str_p++;
if(i==length-1
- 1
- 2
前往页