表达式计算(EGE图形化,链表,大一C语言课设,自定义算法,含全部源码)

目录

1,概要设计

(1)函数介绍

(2)调用关系

2,效果展示

(1)整体效果

(2)详细功能

3,详细代码

(1)主程序(zhuchengxu1.cpp)

(2)画图1(huatu.cpp)

(3)画图2(huatu2.cpp)

(4)按键(anjian.cpp)

(5)记录(jilu.cpp)

(6)合理判断(biaodashihelipanduan.cpp)

(7)创建链表(chuanglianbiao.cpp)

(8)计算(jisuan_.cpp)

(9)计算-括号逻辑梳理(jisuan_1.cpp)

(10)计算-递归计算括号内数据(kuohao.cpp)

4,总结


1,概要设计

(1)函数介绍

void huatu1():绘制表达式计算主界面。

void huatu2():绘制背景图片。

int  anjian1(char c[]):用于实现鼠标点击操作。

void datexie(char c[],int i,float a):将字符串c[]中存储的表达式与a中存储的运算结果以恰当的形式存入文本文档。

int helipanduan(char *c,int i):用于判断表达式是否合理。

Linklist* createLink(Linklist *tou,char c[]):将字符串c[]中的表达式按一定的格式利用尾插法存入链表。

int jisuan_(Linklist *tou):用于计算链表中的表达式。

void jisuan_1(Linklist *tou,Linklist *wei):计算括号内的内容并去除括号,其中tou为左括号前的节点,wei是右括号后的节点。

void kuohao(Linklist *tou):读取左右括号前后两链表的地址并在函数内部利用void jisuan_1(Linklist *tou,Linklist *wei)链表有关括号的内容进行处理。

(2)调用关系

mainàhuatu2,huatu1,anjian1,datexie,helipanduan,createLink,jisuan_

anjian1àhuatu1,huatu2

jisuan_àkuohao

kuohaoàjisuan_1

2,效果展示

(1)整体效果

(2)详细功能

1)实现加减乘除和括号,鼠标点击输入,点击back可以删除删一个输入,输入delete可以归零重新计算

2)非法表达式判断

3,详细代码

(1)主程序(zhuchengxu1.cpp)

//               注意事项 
//  1 表达式的数字长度不超过  9 (包括小数点)  
//  2 完成一次运算后点击 delete 可以再次进行运算
 
#include <stdio.h>//库函数 

#include <graphics.h>//有关画图的库函数

#include<stdlib.h>//有关链表的库函数 

typedef struct biaodashi 
{
	float shuzi;
	char zifu;
	struct biaodashi *next;
}Linklist;

#include "huatu.cpp"//主界面绘制函数文件

#include "huatu2.cpp"//绘制背景 

#include "jilu.cpp"//记录表达式文本 

#include "biaodashihelipanduan.cpp"// 表达式合理判断返回 0 不合理;返回 1 合理 

#include "jisuan.cpp"//计算括号内的内容 

#include "kuohao.cpp"//有关括号的判断计算与‘jisuan.cpp’搭配 

#include "jisuan_.cpp"//计算表达式 

#include "anjian.cpp"//按键功能实现文件 

#include "chuanglianbiao.cpp"//将字符型的表达式转化成数字与操作符存入链表 

Linklist *tou;//链表头节点 

int main()
{
	//this.hide;
	initgraph(480, 640,0);//创建窗口 
	
	 

	setfont(18, 0, "宋体");//设置字体
	
	setcolor(BLACK);//设置字体颜色 
	
	huatu2();//绘制背景
	huatu1();//绘制主界面
	
	char c[6400];//存储鼠标点击的字符 
	int i;//记录表达式长度 
	
	
		
	for(;1;)
	{
		
		for(int z=0;z<6400;z++)c[z]=NULL; //c[i]的初始化
		i=0;//i的初始化 
		 
	
	    i=anjian1(c);//实现按键功能 
		
	    
	    datexie(c,i,0);//将按键输入的字符存入文本文档 
	    
	    
	    if(helipanduan(c,i)==0)//判断表达式是否合理 
		    continue;



	    tou=createLink(tou, c);//创建链表  将字符表达式存入链表 
		
	
	    jisuan_(tou);//计算表达式 
	    xyprintf(150,120,"计算结束,按delete再次计算表达式");
	    
	}	
	
	
	closegraph();//关闭图形界面 
	
	return 0;
}

(2)画图1(huatu.cpp)

画出线条,字符,绘制基本界面




void huatu1()//绘制表达式计算主界面 
{ 
    

	
	setbkmode(TRANSPARENT);//将背景调至半透明  便于字符的绘制  不破坏背景 
	
	
	//画线条
	 
	    line(120,640,120,160);
		line(240,640,240,160);
		line(360,640,360,160);
		line(0,160,480,160);
		line(0,280,480,280);
		line(0,400,480,400);
		
		line(120,580,240,580);
		
		line(0,520,480,520);
		line(240,580,360,580);
		line(300,580,300,640);
		
		line(180,640,180,580);
	
	//写字符	
	
		xyprintf(60,220,"7 ");
		xyprintf(60,340,"4 ");
		xyprintf(60,460,"1 ");
		xyprintf(60,580,"= ");
		xyprintf(180,220,"8 ");
		xyprintf(180,340,"5 ");
		xyprintf(180,460,"2 ");
		xyprintf(180,540,"0 ");
		xyprintf(300,220,"9 ");
		xyprintf(300,340,"6 ");
		xyprintf(300,460,"3 ");
		xyprintf(300,540,". ");
		xyprintf(270,605,"( ");
		xyprintf(330,605,") ");
		xyprintf(420,220,"/ ");
		xyprintf(420,340,"* ");
		xyprintf(420,460,"+ ");
		xyprintf(420,580,"- ");
		xyprintf(123,605,"delete");
		xyprintf(190,605,"back");
		
		
}

(3)画图2(huatu2.cpp)

导入图片作为图形化界面的背景,更美观

需要自定义图片路径

void huatu2()//画背景
{
	PIMAGE pimg = newimage();//创建图片对象
	
	
	
	//图片 1 
	getimage(pimg, "D:\\常用\\图片\\Saved Pictures\\9b9b589bc8a7fb4988576bd8493bdd21.jpeg");//从文件中获取图像(和原图一样大小) 
	setbkcolor(EGERGB(0xF6, 0xE6, 0xE4));//设置背景颜色   粉色
	/*
	
	//图片 2 
	getimage(pimg, "D:\\常用\\图片\\Saved Pictures\\E]UTA49PJZ_WQ)LUI$3FW1X.png");//从文件中获取图像(和原图一样大小)
	setbkcolor(EGERGB(0xB2, 0xEA, 0xED));//设置背景颜色   碧蓝 
	*/
	/*
	//图片 3 
	getimage(pimg, "D:\\常用\\图片\\Saved Pictures\\QQ图片20220303090531.gif");//从文件中获取图像(和原图一样大小)
	setbkcolor(EGERGB(0xB2, 0xEA, 0xED));//设置背景颜色   淡蓝 
	*/
	
	putimage(0, 0, pimg);//绘制图像,(0, 0)是图片绘制区域的左上角
	
    
	
 } 

(4)按键(anjian.cpp)

检测到鼠标点击后,基于鼠标位置判断输入,实现按键化操作



int  anjian1(char c[])//用于实现鼠标点击操作  ; 


{
	int x=0,y=0;
	
	int i=0,l=0;
	
	mouse_msg msg = {0};//定义鼠标结构体msg 
	
	for ( ; is_run(); delay_fps(13))//fps = 13 时,更加稳定 
	{
		
		//获取鼠标消息,此函数将等待至获取到鼠标消息为止 
		while (mousemsg())
		{
			msg = getmouse();
		}
		
		//表达式的输入    存储获取的鼠标消息 
		
		if((int)msg.is_down()==1&&(msg.x>0&&msg.x<120)&&(msg.y>160&&msg.y<280))//按键 7  
		{
			 
			xyprintf(x,y,"7 ");//显示字符  
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			 c[i]='7';
			 i++;
			
			
		}
		else if((int)msg.is_down()==1&&(msg.x>0&&msg.x<120)&&(msg.y>280&&msg.y<400))//按键 4  
		{
			xyprintf(x,y,"4 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='4';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>0&&msg.x<120)&&(msg.y>400&&msg.y<520))//按键 1   
		{
			xyprintf(x,y,"1 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='1';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>0&&msg.x<120)&&(msg.y>520&&msg.y<640))//按键 =  
		{
			
			if(c[0]==NULL&&i<9)continue;
			break;	//结束此函数 
					
		}
		else if((int)msg.is_down()==1&&(msg.x>120&&msg.x<240)&&(msg.y>160&&msg.y<280))//按键 8  
		{
			xyprintf(x,y,"8 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='8';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>120&&msg.x<240)&&(msg.y>280&&msg.y<400))//按键 5  
		{
			xyprintf(x,y,"5 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='5';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>120&&msg.x<240)&&(msg.y>400&&msg.y<520))//按键 2  
		{
			xyprintf(x,y,"2 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='2';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>120&&msg.x<240)&&(msg.y>520&&msg.y<580))//按键 0 
		{
			xyprintf(x,y,"0 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='0';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>240&&msg.x<360)&&(msg.y>160&&msg.y<280))//按键 9  
		{
			xyprintf(x,y,"9 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='9';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>240&&msg.x<360)&&(msg.y>280&&msg.y<400))//按键 6  
		{
			xyprintf(x,y,"6 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='6';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>240&&msg.x<360)&&(msg.y>400&&msg.y<520))//按键 3  
		{
			xyprintf(x,y,"3 ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='3';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>240&&msg.x<360)&&(msg.y>520&&msg.y<580))//按键 .  
		{
			xyprintf(x,y,". ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			c[i]='.';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>360&&msg.x<480)&&(msg.y>160&&msg.y<280))//按键 /  
		{
			xyprintf(x,y,"/ ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			i=(i+1)-(i+1)%10+10-1;//调整符号存储位置
			c[i]='/';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>360&&msg.x<480)&&(msg.y>280&&msg.y<400))//按键 *  
		{
			xyprintf(x,y,"* ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			i=(i+1)-(i+1)%10+10-1;//调整符号存储位置
			c[i]='*';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>360&&msg.x<480)&&(msg.y>400&&msg.y<520))//按键 +  
		{
			xyprintf(x,y,"+ ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			i=(i+1)-(i+1)%10+10-1;//调整符号存储位置
			c[i]='+';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>360&&msg.x<480)&&(msg.y>520&&msg.y<640))//按键 -  
		{
			xyprintf(x,y,"- ");//显示字符
			
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			i=(i+1)-(i+1)%10+10-1;//调整符号存储位置
			c[i]='-';
			 i++;
		}
		else if((int)msg.is_down()==1&&(msg.x>120&&msg.x<180)&&(msg.y>580&&msg.y<640))//按键 delete  
		{
			cleardevice();//清屏后再次画图 
			huatu2();
			huatu1();
			
			
			x=0;//将数据初始化 
			y=0;
			
			for(l=0;l<i;l++)
			    c[l]=NULL;
			
			i=0;
		
		}
		else if((int)msg.is_down()==1&&(msg.x>180&&msg.x<240)&&(msg.y>580&&msg.y<640))//按键 back  
		{
			setbkmode(OPAQUE);//将背景调为透明的     实现ege界面上的消除 
			
			
			if(x>=10)//操作位置在一行内 可直接消除 
			{
				x-=10;
				xyprintf(x,y,"  ");//利用空格达到界面的消除效果 
				
				//字符数据的消除 
				i--;
			    c[i]=NULL;
			    for(;c[i]==NULL;i--);
			    i++;
			
			}
			else if(x==0&&y!=0)//操作位置在行列的开头 需要返回上一行再消除 
			{
				x=460;
				y-=20;
				xyprintf(x,y,"  ");
				
				//字符数据的消除 
				i--;
			    c[i]=NULL;
			    for(;c[i]==NULL;i--);
			    i++;
			
			}
			else if(x==0&&y==0)i=0;//操作位置在第一行开头 无事发生 
			else if(x<0||y<0)//防止意外发生 若操作位置不在界面内 将操作位置调整至第一行开头 
			{
				x=0;y=0;
			}
			setbkmode(TRANSPARENT);//将背景用当前背景色填充   不破坏背景图片 
			
			
		}
		else if((int)msg.is_down()==1&&(msg.x>240&&msg.x<300)&&(msg.y>580&&msg.y<640))//按键 (  
		{
			i=(i+1)-(i+1)%10+10-1;//调整符号存储位置 
			if(c[i-10]==NULL&&c[i-9]!=NULL)//自动填充 * 号 
			{
				xyprintf(x,y,"* ");//显示字符
				
				// 调整下次显示位置 
			    if(x>450)
			    {
				    x=0;y+=20;
			    }
			    else
			    {
				    x+=10;
			    }
			
			    
			    c[i]='*';
			    i+=2;
			    
			    xyprintf(x,y,"( ");//显示字符
			    
			    // 调整下次显示位置 
			    if(x>450)
			    {
				    x=0;y+=20;
			    }
			    else
			    {
				    x+=10;
			    }
			    
			    
			    i=(i+1)-(i+1)%10+10-1;//调整符号存储位置
			    c[i]='(';
			    i++;
			}
			
			else//无需自动填充 
			{
				xyprintf(x,y,"( ");//显示字符
			    if(x>450)
			    {
				    x=0;y+=20;
			    }
			    else
			    {
				    x+=10;
			    }
			    c[i]='(';
			    i++;
			}
		}
		else if((int)msg.is_down()==1&&(msg.x>300&&msg.x<360)&&(msg.y>580&&msg.y<640))//按键 )  
		{
			xyprintf(x,y,") ");//显示字符
			 
			// 调整下次显示位置 
			if(x>450)
			{
				x=0;y+=20;
			}
			else
			{
				x+=10;
			}
			
			
			
			if(c[i-1]!=')')//调整符号存储位置
			{
				i+=9;
			    i=(i+1)-(i+1)%10+10-1;
			    c[i]=')';
			}
			else
			{
				i=(i+1)-(i+1)%10+10-1;
			    c[i]=')';
			}
			
			 i+=1;
		}
		else ;
	    if(y==140&&x==450)//表达式过长 
		{
			cleardevice();//初始化操作 
			x=0;y=0;
			for(l=0;l<i;l++)c[l]=NULL;
			i=0;l=0;
			huatu2();
			setbkmode(TRANSPARENT);//将背景调至半透明  便于字符的绘制  不破坏背景
			
			xyprintf(160,310,"表达式长度超出限制!");
			xyprintf(220,580,"按任意数字键重新输入表达式。");
			
			getch();
			cleardevice();
			huatu2();
			huatu1();
			
		}
	}
	
	return i;
	
}

(5)记录(jilu.cpp)

将所有表达式计算的历史记录存入txt文本文档中,回溯

void datexie(char c[],int i,float a)//将字符串c中存储的表达式与a中存储的运算结果以恰当的形式存入文本文档 
{
	
	if(i==-1)
	{
		int l;
	
        FILE *fp;//文件指针
    
        /*文件的打开*/
        fp=fopen("jisuanjilu.txt","a");
        if(fp==NULL) //判断如果文件指针为空
        {
            printf("File cannot open! " );
            exit(0); //在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件
        }

        //写入东西
            
        fprintf(fp,"=%.4f\n",a);//!!!!!尤其注意这里要用逗号隔开,因为excel表里面就默认识别逗号隔开的才能分类fprintf(文件指针,格式字符串,列表)
	    
        fclose(fp);
	}
	else if(i==-2)
	{
		int l;
	
        FILE *fp;//文件指针
    
        /*文件的打开*/
        fp=fopen("jisuanjilu.txt","a");
        if(fp==NULL) //判断如果文件指针为空
        {
            printf("File cannot open! " );
            exit(0); //在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件
        }

        //写入东西
            
        fprintf(fp,"                       此次输入的表达式有误!\n");//!!!!!尤其注意这里要用逗号隔开,因为excel表里面就默认识别逗号隔开的才能分类fprintf(文件指针,格式字符串,列表)
	    
        fclose(fp);
	}
	else
	{
		int l;
	
        FILE *fp;//文件指针
    
        /*文件的打开*/
        fp=fopen("jisuanjilu.txt","a");
        if(fp==NULL) //判断如果文件指针为空
        {
            printf("File cannot open! " );
            exit(0); //在以0的形式退出,必须在文件开头有#include <stdlib.h>,stdlib 头文件即standard library标准库头文件
        }

        //写入东西
        for(l=0;l<i;l++)
        {    
            if(c[l]!=NULL)fprintf(fp,"%c",c[l]);//!!!!!尤其注意这里要用逗号隔开,因为excel表里面就默认识别逗号隔开的才能分类fprintf(文件指针,格式字符串,列表)
	    }
        fclose(fp);
	}
}

(6)合理判断(biaodashihelipanduan.cpp)

对表达式的输入进行合理判断



int helipanduan(char *c,int i)//用于计算以字符存储的表达式 ; 

{
	//判断表达式是否合理
	
	
	//不合理重新输入表达式 
	int l;
	int zk=0,yk=0;
	int ys;
	for(l=9;l<i;l+=10)
	{
		if(c[l]=='(')zk++;
		if(c[l]==')')yk++;
		
		
		if(c[l]=='+'||c[l]=='-'||c[l]=='*'||c[l]=='/')
		{
			
			if((c[l+10]=='+'||c[l+10]=='-'||c[l+10]=='*'||c[l+10]=='/')&&(atof(&c[l+1])==NULL||atof(&c[l+11])==NULL)&&c[l+20]!='(')
			{
				
				datexie(0,-2,0);
				
				cleardevice();
				xyprintf(110,310,"表达式运算符输入有误!请重新输入!");
			    xyprintf(200,580,"按任意数字键重新输入表达式。");
			    getch();
			    cleardevice();//判断完成后的界面切换 
			    huatu2();
			    huatu1();
			    return 0;
			}
		}
		
		
		if(yk>zk)
		{
			datexie(0,-2,0);
		
			cleardevice();
			xyprintf(110,310,"表达式缺少左括号!请重新输入!");
			xyprintf(200,580,"按任意数字键重新输入表达式。");
			getch();
			cleardevice();//判断完成后的界面切换 
			huatu2();
			huatu1();
			return 0;
			
		}
		
		
	}
	
	if(yk!=zk)
	{
		datexie(0,-2,0);
		
		cleardevice();
		xyprintf(110,310,"表达式缺少右括号!请重新输入!");
		xyprintf(200,580,"按任意数字键重新输入表达式。");
		getch();
		cleardevice();//判断完成后的界面切换 
		huatu2();
		huatu1();
		return 0;
	}
	
	
	return 1;//返回 1 表达式无结构上的错误 
	
}

(7)创建链表(chuanglianbiao.cpp)

将字符串表达式分割存入链表(因为作业要求要用链表)



Linklist* createLink(Linklist *tou,char c[])//尾插法创建链表 
{
    Linklist *wei;
	
	tou=(Linklist*)malloc(sizeof(Linklist));
	wei=(Linklist*)malloc(sizeof(Linklist));
	
	tou=wei;
	 
	int cunl;
	
	for(cunl=0;c[cunl]!=NULL||c[cunl+1]!=NULL||c[cunl+2]!=NULL||c[cunl+3]!=NULL||c[cunl+4]!=NULL||c[cunl+5]!=NULL||c[cunl+6]!=NULL||c[cunl+7]!=NULL||c[cunl+8]!=NULL||c[cunl+9]!=NULL;cunl+=10)
	{
		
		Linklist *zhen;
		zhen=(Linklist*)malloc(sizeof(Linklist));
		
		zhen->shuzi=atof(&c[cunl]);// 链表内容输入 
		zhen->zifu=c[cunl+9];
		
		wei->next=zhen;
		wei=zhen;
		
		
	}
	
	wei->next=NULL;
	

	
	return tou;
}

(8)计算(jisuan_.cpp)

计算部分整体


int jisuan_(Linklist *tou)//用于计算以字符存储的表达式  

{
	Linklist *jisuan1=(Linklist*)malloc(sizeof(Linklist)),*jisuan2=(Linklist*)malloc(sizeof(Linklist));
	//有关括号的优先级运算
	
	
	kuohao(tou);//将括号内的表达式进行运算  

	
	
		
	
	//乘除法运算
	
	jisuan1=tou->next;
	jisuan2=tou;
	
	for(;jisuan1->next!=NULL;)
	{
		if(jisuan1->zifu=='*')
		{
			jisuan1->next->shuzi=jisuan1->shuzi*jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
		    
			continue;
		}
		else if(jisuan1->zifu=='/')
		{
			jisuan1->next->shuzi=jisuan1->shuzi/jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
			continue;
		}
		
	
		else 
		{
			jisuan1=jisuan1->next;
		    jisuan2=jisuan2->next;
		}
	} 
	
	
	//加减法运算
	jisuan1=tou->next;
	jisuan2=tou;
	
	for(;jisuan1->next!=NULL;)
	{
		if(jisuan1->zifu=='+')
		{
			jisuan1->next->shuzi=jisuan1->shuzi+jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
		    
			continue;
		}
		else if(jisuan1->zifu=='-')
		{
			jisuan1->next->shuzi=jisuan1->shuzi-jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
			continue;
		}
		else 
		{
			jisuan1=jisuan1->next;
		    jisuan2=jisuan2->next;
		}
	}  
	
	xyprintf(0,20,"=%.4f",jisuan1->shuzi);//输出最后的结果 
	datexie(0,-1,jisuan1->shuzi);//将最后的结果输入文本 
	return 0;
	
}

(9)计算-括号逻辑梳理(jisuan_1.cpp)

void jisuan_1(Linklist *tou,Linklist *wei)//计算括号内的内容并去除括号
{
	
	Linklist *jisuan1=(Linklist*)malloc(sizeof(Linklist)),*jisuan2=(Linklist*)malloc(sizeof(Linklist));
	
	
	//去括号

	
	//去左括号 
	jisuan1=tou->next;
	jisuan2=tou;
	jisuan2->next=jisuan1->next;
	free(jisuan1);
	

	
	//去右括号 
	jisuan1=tou->next;
	jisuan2=tou;
	for(;;jisuan1=jisuan1->next,jisuan2=jisuan2->next)
	{
		if(jisuan1->zifu==')'&&jisuan1->next==NULL)
		{
			wei=jisuan1->next;
			jisuan2->next=jisuan1->next;
			free(jisuan1);
			break;
		}
		else if(jisuan1->zifu==')'&&jisuan1->next->zifu!=')')
		{
			jisuan2->next=jisuan1->next->next;
			jisuan2->zifu=jisuan1->next->zifu;
			wei=jisuan2->next;
			free(jisuan1->next);
		    free(jisuan1);
		    break;
		}
		else if(jisuan1->zifu==')'&&jisuan1->next->zifu==')')
		{
			jisuan2->next=jisuan1->next;
			wei=jisuan1->next;
			free(jisuan1);
			break;
			
		}
	 } 

	
	
	//乘除法运算
	
	jisuan1=tou->next;
	jisuan2=tou;
	
	for(;jisuan1->next!=wei;)
	{
		if(jisuan1->zifu=='*')
		{
			jisuan1->next->shuzi=jisuan1->shuzi*jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
		    
			continue;
		}
		else if(jisuan1->zifu=='/')
		{
			jisuan1->next->shuzi=jisuan1->shuzi/jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
			continue;
		}
		
	
		else 
		{
			jisuan1=jisuan1->next;
		    jisuan2=jisuan2->next;
		}
	} 
	
	//getch();
	//加减法运算
	jisuan1=tou->next;
	jisuan2=tou;
	
	for(;jisuan1->next!=wei;)
	{
		if(jisuan1->zifu=='+')
		{
			jisuan1->next->shuzi=jisuan1->shuzi+jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
		    
			continue;
		}
		else if(jisuan1->zifu=='-')
		{
			jisuan1->next->shuzi=jisuan1->shuzi-jisuan1->next->shuzi;
			
		    jisuan2->next=jisuan1->next;
		    free(jisuan1);
		    jisuan1=jisuan2->next;
			continue;
		}
		else 
		{
			jisuan1=jisuan1->next;
		    jisuan2=jisuan2->next;
		}
	}
	
}

(10)计算-递归计算括号内数据(kuohao.cpp)


void kuohao(Linklist *tou)//读取左右括号前后两链表的地址并传给void jisuan_1(Linklist *tou,Linklist *wei)
{
	
	Linklist *tou1=NULL,*wei1=NULL,*jisuan=tou;
	
	
	
	jisuan=(Linklist*)malloc(sizeof(Linklist));
	jisuan=tou;
	
	
	for(;jisuan->next!=NULL;jisuan=jisuan->next)
	{
		
		if(jisuan->next->zifu=='(')
		{
			tou1=jisuan;//括号左 
			kuohao(jisuan->next);
		}
		else if(jisuan->next->zifu==')'&&tou1!=NULL)
		{
			wei1=jisuan->next->next;//括号右 
			jisuan_1(tou1,wei1);//计算括号内的内容并去除括号 
			break;
			
		}
		else continue;
	}
	
}

4,总结

        回头看,不得不说之前写的真是答辩,看着这个.cpp文件里面封装的函数名字都跟cpp文件的名字不一样是真的蚌埠住。不过有一说一,这个没用堆栈,手搓出了一个算法流程,把括号的逻辑梳理清楚了,现在看了还是很自豪 (:D)。

        后续可能会重构更新,调试出错可以评论,看到会回复。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值