思路:
1.分为两步计算,第一步先计算括号里面的数据!没计算完一个括号以后,判断是否括号已经消除完毕,消除完毕结束循环
2.消除完,先计算乘除后计算加减,(在处理括号理同时含有乘除和加减时,调用此过程)
3.存储过程采用双向链表存储
总结:
1.要画出循环图来,保证思路清晰!每个细节要注意到并以适当的方式改正过来!
漏洞:
由于采用的是字符数组的形式存储数字,但是不会把负数和小数点以数组的形式存储进去,所以整个过程当中,每步骤运算不能出现负数,和小数点,才能正常运行下来~
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<stdio.h>
#include<iostream>
using namespace std;
//---------------------------------------------------存储每个符号的单元-----------------------------------------
class node
{
public:
char x; //存储输入的符号!
node *prior; //前驱结点,记录上一个字符;
node *next; //后继结点,记录下一个节点的存储的字符;
};
//--------------------------------------------------计算器M类------------------------------------------------------------
class M
{
public:
M ();
void create (); //创建并存储表达式
int pankong (); //是否括号已经消除完毕
void xiaokuo (); //消除括号过程,
void Fleftright (); //确定第一个含有右括号的节点地址与其对应的含有左括号的节点地址
void jiSUM1 (); //用于 * /,计算两边的乘或者除过程
void jiSUM2 (); //用于 + -,计算两边的乘或者除过程
void GetLeftsum1 (); //用于 * /,左边字符转化成整数型
void GetRightsum1 (); //用于 * /,右边的字符转化成整数型
void GetLeftsum2 (); //用于 + - ,左边字符转化成整数型
void GetRightsum2 (); //用于+ - ,右边的字符转化成整数型
void xiSUM (); //用于把计算得到的结果从整数型转化成字符型添加进去
void tianjia (); //删除原来字符添加新的字符进去(包含在xiSUM())中
int ok1 (); //判断括号里是否所有的 * 和 / 消除完毕!
int ok2 (); //判断括号里是否所有的 + 和 - 消除完毕!
void show (); //输出各个节点(数据),最后不含括号和运算符!
void XXX1 (); //消除括号过程
void XXX2 (); //括号消除完,计算不含括号的式子过程!
private:
node *Head;
node *New;
node *Tail;
node *Fleft; //记录第一个右括号节点对应的含有左括号的节点地址
node *Fright; //记录第一个含有右括号的节点地址
node *fleft; //记录算式最左边的位置
node *fright; //记录算式最右边的位置
int count; //总的个数节点个数
int Leftsum; //左边的数
int Rightsum; //右边的数
int SUM; //左右两个数运算得到的数
char a[10]; //存储数值转化成字符的数组
int T; //记录计算结果SUM的位数
};
M:: M ()
{
Head = 0;
Tail = 0;
count = 0;
Leftsum = 0;
Rightsum = 0;
T = 0;
SUM = 0;
a[10] = '0';
}
//--------------------------------------------------void create ()---------------------------------------------------
void M:: create()
{
while (1)
{
New = new node;
count++;
cin>>New->x;
if (count == 1)
{
Head = Tail = New;
}
else
{
Tail->next = New;
New->prior = Tail;
Tail = New;
}
if (New->x == '=')
{
New->next = 0;
node *HHead = new node;
HHead->x = '=';
HHead->next = Head;
Head->prior = HHead;
break;
}
}
}
//--------------------------------------------------int M:: pankong () 是否含有括号-------------------------
int M:: pankong ()
{
node *p = Head;
for (p ; p != 0 ;p = p->next) //记住以后的循环要有终止条件!!!
{
if (p->x == ')' )
{
return 1;
}
//若还含有括号返回1
}
return 0; //不含有括号返回0
}
//--------------------------------------------------void Fleftright ()每次取得第一个右括号和对应左括号的地址!-------------------------
void M:: Fleftright ()
{
node *p = Head;
for (p ; p != 0 ; p = p->next )
{
if ( p->x == ')' )
{ Fright = p; break; } //取得第一个右括号的地址!
}
if (p == 0)
{
Fright = Fleft = Head; //找完了,没括号了都指向头指针
}
p = Fright;
for ( p ; p != 0 && p ->x != '=' ; p = p->prior )
{
if (p->x == '(')
{ Fleft = p; break; } //取得第一个左括号的地址!
}
}
//-----------------------------------------------void GetLeftsum1 ()取得符号左边的int数值-------------------------------
void M:: GetLeftsum1 ()
{
node *p = Fleft; //假如消除完括号,那么 Fleft = Fright = Head;
for (p ; p ->x != ')'&& p != 0 ; p = p->next)
{
if (p->x == '*' || p->x == '/')
{
int c = 1;
node *q = p->prior;
for (q ; ( q->x != '+'&&q->x != '-'&&q->x != '(' &&q->x != '=' ) ; q = q->prior) //????????
{
Leftsum = Leftsum + c * ( (q->x)-'0' );
c = c * 10;
}
fleft = q;
break;
}
}
}
//-----------------------------------------------void GetRightsum1 ()---取得右边的int数值----------------------------
void M :: GetRightsum1 ()
{
node *p = Fleft;
int i = 0, c = 1;
for (p ; p->x != ')' && p != 0; p = p->next)
{
if (p->x == '*' || p->x == '/')
{
node *q = p->next;
for (q ; (q->x != '+'&&q->x != '-'&&q->x != ')'&&q->x != '*'&&q->x != '/'&&q->x != '=') ; q = q->next)
{
i++;
} fright = q;
for (q = q->prior; i >=1 ; q = q->prior)
{
Rightsum = Rightsum + c * ( (q->x)-'0' );
c = c * 10;
i--;
}
break;
}
}
}
//-----------------------------------------------void GetLeftsum2 ()取得符号左边的int数值-------------------------------
void M:: GetLeftsum2 ()
{
node *p = Fleft;
for (p ; p ->x != ')'&& p != 0; p = p->next)
{
if (p->x == '+' || p->x == '-')
{
int c = 1;
node *q = p->prior;
for (q ; q->x != '(' && q->x != '=' ; q = q->prior)
{
Leftsum = Leftsum + c * ( (q->x)-'0' );
c = c * 10;
// if (q == Head)
// break;
} fleft = q;
break;
}
}
}
//-----------------------------------------------void GetRightsum2 ()---取得右边的int数值----------------------------
void M :: GetRightsum2 ()
{
node *p = Fleft;
int i = 0, c = 1;
for (p ; p->x != ')' && p != 0; p = p->next)
{
if (p->x == '+' || p->x == '-')
{
node *q = p->next;
for (q ; ( q->x != '+'&&q->x != '-'&&q->x != ')' &&q->x != '=') ; q = q->next)
{
i++;
} fright = q;
for (q = q->prior; i >= 1 ; q = q->prior)
{
Rightsum = Rightsum + c * ( (q->x)-'0' );
c = c * 10;
i--;
}
break;
}
}
}
//------------------------------------------------------void M:: jiSUM1 () 计算乘除左右括号结果SUM用于******和 ------------------------------------------
void M:: jiSUM1 ()
{
node *p = Fleft; //第一个右括号对应的左括号,如果没括号了,都指向头指针
for (p ; p->x != ')' && p != 0; p = p->next)
{
if (p->x == '*' )
{
SUM = Rightsum * Leftsum;
Leftsum = 0;
Rightsum = 0;
break;
}
if (p->x == '/')
{
SUM = Leftsum / Rightsum;
Leftsum = 0;
Rightsum = 0;
break;
}
}
}
//------------------------------------------------------void M:: jiSUM2 () 计算乘除左右括号结果SUM用于+++和---- ------------------------------------------
void M:: jiSUM2 ()
{
node *p = Fleft; //第一个右括号对应的左括号
for (p ; p->x != ')' && p != 0; p = p->next)
{
if (p->x == '+' )
{
SUM = Rightsum + Leftsum;
Leftsum = 0;
Rightsum = 0;
break;
}
if (p->x == '-')
{
SUM = Leftsum - Rightsum;
Leftsum = 0;
Rightsum = 0;
break;
}
}
}
//-----------------------------------------------void M:: xiSUM ()整数型转化成字符型,并删除原来字符添加新的字符进去------------------------------
void M:: xiSUM ()
{
if (SUM >=0 && SUM < 10)
{
a[1] = SUM + '0'; T = 1;
tianjia ();
}
else if (SUM >=10 && SUM < 100)
{
a[2] = (SUM % 10) + '0';
a[1] = (SUM / 10) + '0';
T = 2;
tianjia ();
}
else if (SUM >=100 && SUM <1000)
{
a[3] = (SUM %10) + '0';
a[2] = (SUM % 100) /10 + '0';
a[1] = (SUM /100) + '0';
T = 3;
tianjia ();
}
else if (SUM >=1000 && SUM <10000)
{
a[4] = (SUM %10) + '0';
a[3] = (SUM % 1000 % 100) /10 + '0';
a[2] = (SUM % 1000 ) / 100 + '0';
a[1] = (SUM / 1000) + '0';
T = 4;
tianjia ();
}
else if (SUM >=10000 && SUM <100000)
{
a[5] = (SUM %10) + '0';
a[4] = (SUM % 10000 % 1000 %100) /10 + '0';
a[3] = (SUM % 10000 % 1000) / 100 + '0';
a[2] = (SUM % 10000) / 1000 + '0';
a[1] = (SUM / 10000) + '0';
T = 5;
tianjia ();
}
else if (SUM >=100000 && SUM <1000000)
{
a[6] = (SUM %10) + '0';
a[5] = (SUM % 100000 % 10000 % 1000 % 100) /10 + '0';
a[4] = (SUM % 100000 % 10000 % 1000) / 100 + '0';
a[3] = (SUM % 100000 % 10000) / 1000 + '0';
a[2] = (SUM % 100000) / 10000+ '0';
a[1] = (SUM / 100000) + '0';
T = 6;
tianjia ();
}
}
//-----------------------------------------------void tianjia ()新的字符进去------------------------------
void M::tianjia ()
{
node *head = 0 ,*tail = 0,*newi = 0 ;
for (int i = 1; i <= T ; i++)
{
newi = new node;
newi->x = a[i] ;
if (i == 1)
{
head = tail = newi;
}
else
{
tail->next = newi;
newi->prior = tail;
tail = newi;
}
if (i == T)
{
fleft->next = head;
head->prior = fleft;
tail->next = fright;
fright->prior = tail;
if (fleft->x == '=')
{
Head = head;
}
break;
}
}
}
//--------------------------------------------------void xiaokuo ()消除 (2115)形式的括号或不含括号的-------------------------
void M:: xiaokuo ()
{
node *p = Fleft ,*q = Fright;
if (p != q) //消除(3213)这种形式的
{
p->prior->next = p->next;
p->next->prior = p->prior;
q->prior->next = q->next;
q->next->prior = q->prior;
}
}
//----------------------------------------------void ok1 ()-用于 *** 和///-----------------------------
int M:: ok1()
{
Fleftright ();
node *p = Fleft; //判断乘除是否消解完全
for (p ; p ->x != ')' && p!= 0 ; p = p->next)
{
if (p->x == '*' ||p->x == '/' )
{
return 1;
}
if (p->x == '=')
{
return 0;
}
}
return 0;
}
//----------------------------------------------void ok2 ()-用于 +++ 和--- ----------------------------
int M:: ok2()
{
Fleftright ();
node *p = Fleft;
for (p ; p ->x != ')' && p!= 0 ; p = p->next)
{
if (p->x == '+' ||p->x == '-' )
{
return 1;
}
if (p->x == '=')
{
return 0;
}
}
return 0;
}
//-----------------------------------------------void show ()输出数组的内容-------------------------------
void M:: show ()
{
node *p = Head;
cout<<"结果:";
for (p ;p != 0 && p ->x != '='; p = p->next)
{
cout<<p->x;
}
cout<<endl;
}
//------------------------------------------------------void xxx1 ()--------------------------
void M::XXX1 ()
{
int x , y , z ;
while (x = pankong()) //循环处理括号(括号消除完?)
{
while (y = ok1()) //循环处理括号里的乘除
{
Fleftright (); //找到第一个含有右括号的节点地址与其对应的含有左括号的节点地址
y = ok1 (); //确定是否含有乘除??
if ( y == 0 )
break;
GetLeftsum1 (); //用于 * /,左边字符转化成整数型 找到第一个乘除左边的数值
GetRightsum1 (); //用于 * /,右边的字符转化成整数型 找到第一个乘除右边的数值
jiSUM1 (); //用于 * /,计算两边的乘或者除过程
xiSUM (); //用于 * /,整数型转化成字符型 添加到链中,含有tianjia(); 乘或除减少一个
y = ok1 (); //确定消除后是否还含有乘除
}
while ( z= ok2 () ) //循环处理括号里的加减(加减消除完?)
{
Fleftright (); //找到第一个含有右括号的节点地址与其对应的含有左括号的节点地址
y = ok2 (); //确定是否含有+ -
if ( y == 0 )
break;
GetLeftsum2 (); //用于 + -,左边字符转化成整数型 找到第一个+ -左边的数值
GetRightsum2 (); //用于+ -,右边的字符转化成整数型 找到第一个+ -右边的数值
jiSUM2 (); //用于 + -,计算两边的乘或者除过程
xiSUM (); //用于 + -,整数型转化成字符型 添加到链中,含有tianjia(); + - 减少一个
z = ok2 (); //确定消除后是否还含有 + -
}
xiaokuo (); //消除括号(15315),一组括号!!!
x = pankong (); //括号是否消除完毕
}
}
//------------------------------------------------------void xxx2 ()--------------------------
void M::XXX2 ()
{
Fleft = Fright = Head;
int y = ok1 (); //确定是否含有乘除??
while ( y != 0 )
{
GetLeftsum1 (); //用于 * /,左边字符转化成整数型 找到第一个乘除左边的数值
GetRightsum1 (); //用于 * /,右边的字符转化成整数型 找到第一个乘除右边的数值
jiSUM1 (); //用于 * /,计算两边的乘或者除过程
xiSUM (); //用于 * /,整数型转化成字符型 添加到链中,含有tianjia(); 乘或除减少一个
y = ok1 (); //确定消除后是否还含有乘除
}
int z = ok2 ();
while (z != 0)
{
GetLeftsum2 (); //用于+ , -左边字符转化成整数型 找到第一个乘除左边的数值
GetRightsum2 (); //用于 + , -右边的字符转化成整数型 找到第一个乘除右边的数值
jiSUM2 (); //用于+ , -计算两边的乘或者除过程
xiSUM (); //用于+ , -整数型转化成字符型 添加到链中,含有tianjia(); 乘或除减少一个
z = ok2 (); //确定消除后是否还含有乘除
}
show ();
}
//------------------------------------------------主函数--------------------------------------------------------
int main()
{
while (1)
{
cout<<"输入计算式子:";
M m;
m.create ();
if ( m.pankong () )
{
m.XXX1 ();
m.XXX2 ();
}
else
{
m.XXX2 ();
}
}
system("pause");
}