ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构课程设计(一)---24点

2020-06-23 14:41:16  阅读:139  来源: 互联网

标签:24 输出 课程设计 12 运算 相同 int 数据结构


一、计算24点
1、任务简述:
一副扑克牌的每张牌表示一个数(J、Q、K分别表示11、12、13,两个司令不用)。任取4张牌,即得到1-13的数,请添加运算符(规定为加、减、乘、除四种)使之成为运算式。每个数只能参与一次运算,4个数顺序可以任意组合,4个运算符任意取3个且可以重复取。运算遵从一定有限级别,可加括号控制,最终使运算结果为24.请输出一种解决方案的表达式,用括号表示运算优先。如果没有解决方案,则输出-1表示无解。

要求:
(1)输入说明:输入采用随机生成4个整数,每个整数取值范围是[1, 13].
(2)输出说明:输出一种解决方案的表达式,用括号表示运算优先,如果没有解决方案,则输出-1。
(3)测试用例: 输入 2 3 12 12 输出 ((3-2)*12)+12
(4)可选要求:输出要求输出该4个整数所有可能的解决方案。

2、算法描述:
采用思维上最简单的方法,就是遍历所有可能性,如果可以算出24就输出,并且让变量flag++来记录算法个数,如果flag是0,则输出-1,表示这四个数字无法算出24点。我的代码中必要有优势的去重的方法为check函数,这个函数是针对输入的数据a,b,c,d进行处理,找出他们之中相同的个数,一共有五种情况:1.都不相同,那么不做调整;2.有且仅有两个相同,那么把相应的相同的元素放在c和d 的位置;3.有两组数字分别相同(比如a=c,b=d,但是a,b不等),那么把相同的放在一起;4.有三个相同,那么把他们发在b,c,d的位置;5.全部相同,那么不做调整。根据不同的情况,去遍历所有的可能性,一来成功去重,二来减少了运算的次数(就是比如:2,3,12,12可以认为第一个12只会在第二个之前)。
在这里插入图片描述
3、源代码

#include <iostream>  
using namespace std; 
int flag=0;
int Calculate(float x,float y,float z,float w);//a b c d的所有排列组合情况 
int check(int *a,int *b,int *c,int *d);

int main()  
{ 
	int a,b,c,d;  
	m_ret: //做标记  
	cout<<"请输入4个数据"<<endl;  
	cout<<" 第一个数:";  
	cin>>a;  
	cout<<" 第二个数:";  
	cin>>b;  
	cout<<" 第三个数:";  
	cin>>c;  
	cout<<" 第四个数:";  
	cin>>d;  
	cout<<"输出所有算法如下:"<<endl;  
	if ((a<0)||(a>13)||(b<0)||(b>13)||(c<0)||(c>13)||(d<0)||(d>13))  
	{ 
		cout<<"你输入的输入不对,重新输入"<<endl;  
		goto m_ret; 
	} // 返回标记,重复输入 
	if(check(&a,&b,&c,&d)==0)//分成五种情况,都不想等,有两个相等(两种),有三个相等,有四个相等 ,并且把相等的往后放 
	{
		Calculate(a,b,c,d); Calculate(a,b,d,c); Calculate(a,c,d,b);  
		Calculate(a,c,b,d); Calculate(a,d,b,c); Calculate(a,d,c,b);  
		Calculate(b,a,c,d); Calculate(b,a,d,c); Calculate(b,c,a,d);  
		Calculate(b,c,d,a); Calculate(b,d,c,a); Calculate(b,d,a,c);  
		Calculate(c,a,b,d); Calculate(c,a,d,b); Calculate(c,b,d,a);  
		Calculate(c,b,a,d); Calculate(c,d,a,b); Calculate(c,d,b,a);  
		Calculate(d,a,b,c); Calculate(d,a,c,b); Calculate(d,b,c,a);  
		Calculate(d,b,a,c); Calculate(d,c,a,b); Calculate(d,c,b,a); 
	}
	else if(check(&a,&b,&c,&d)==1)  //只有一组一样的,即交换后的c和d 
	{
		Calculate(a,b,c,d);
		Calculate(a,c,d,b);  
		Calculate(a,c,b,d); Calculate(a,d,c,b);
		Calculate(b,a,c,d); Calculate(b,c,a,d);  
		Calculate(b,c,d,a);   
		Calculate(c,a,b,d); Calculate(c,a,d,b); Calculate(c,b,d,a);  
		Calculate(c,b,a,d); Calculate(c,d,a,b); Calculate(c,d,b,a);  
	}
	else if(check(&a,&b,&c,&d)==2)  //有两组一样的,即交换后的a和b    c和d
	{
		Calculate(a,b,c,d); Calculate(a,c,d,b); Calculate(a,c,b,d);
		Calculate(c,a,b,d); Calculate(c,a,d,b); Calculate(c,d,a,b);
	}
	else if(check(&a,&b,&c,&d)==3)
	{
		Calculate(a,b,c,d);Calculate(b,a,c,d);
		Calculate(c,b,a,d);Calculate(d,b,c,a);
	}
	else
		Calculate(a,b,c,d);
	if(flag==0)
		cout<<"-1"<<endl;
	else
		cout<<"一共有"<<flag<<"种算法"<<endl;
	return 0;
}  

int Calculate(float x,float y,float z,float w) //运算表达式的所有情况,里面的x,y,z,w位置相对固定,所以所有情况,靠主函数里面对他们进行排序 
{   
    if (x+y+z+w==24) {cout<<x<<"+"<<y<<"+"<<z<<"+"<<w<<"=24"<<endl;flag++;} 
    else if (x+y+z-w==24) {cout<<x<<"+"<<y<<"+"<<z<<"-"<<w<<"=24"<<endl;flag++;}  
    else if ((x+y)*(z+w)==24) {cout<<"("<<x<<"+"<<y<<")*("<<z<<"+"<<w<<")=24"<<endl;flag++;}   
    else if ((x-y)*(z+w)==24) {cout<<"("<<x<<"-"<<y<<")*("<<z<<"+"<<w<<")=24"<<endl;flag++;}   
    else if ((x-y)*(z-w)==24) {cout<<"("<<x<<"-"<<y<<")*("<<z<<"-"<<w<<")=24"<<endl;flag++;}   
    else if ((x+y+z)*w==24) {cout<<"("<<x<<"+"<<y<<"+"<<z<<")*"<<w<<"=24"<<endl;flag++;}   
    else if ((x-y-z)*w==24) {cout<<"("<<x<<"-"<<y<<"-"<<z<<")*"<<w<<"=24"<<endl;flag++;}   
    else if ((x+y-z)*w==24) {cout<<"("<<x<<"+"<<y<<"-"<<z<<")*"<<w<<"=24"<<endl;flag++;}  
	else if ((x-y+z)*w==24) {cout<<"("<<x<<"-"<<y<<"+"<<z<<")*"<<w<<"=24"<<endl;flag++;} 
    else if ((x*y*z)/w==24) {cout<<"("<<x<<"*"<<y<<"*"<<z<<")/"<<w<<"=24"<<endl;flag++;}   
    else if ((x*y)*(z+w)==24) {cout<<"("<<x<<"*"<<y<<")*("<<z<<"+"<<w<<")=24"<<endl;flag++;}   
    else if ((x*y)*(z-w)==24) {cout<<"("<<x<<"*"<<y<<")*("<<z<<"-"<<w<<")=24"<<endl;flag++;}  
    else if ((x*y)*z-w==24) {cout<<"("<<x<<"*"<<y<<")*("<<z<<")-"<<w<<"=24"<<endl;flag++;}   
    else if ((x*y)*z+w==24) {cout<<"("<<x<<"*"<<y<<")*("<<z<<")+"<<w<<"=24"<<endl;flag++;}  
    else if (x*y*z*w==24) {cout<<x<<"*"<<y<<"*"<<z<<"*"<<w<<"=24"<<endl;flag++;} 
    else if ((x+y)+(z/w)==24) {cout<<"("<<x<<"+"<<y<<")+("<<z<<"/"<<w<<")"<<"=24"<<endl;flag++;}  
    else if ((x+y)*(z/w)==24) {cout<<"("<<x<<"+"<<y<<")*("<<z<<"/"<<w<<")"<<"=24"<<endl;flag++;}   
    else if ((x*y)+z+w==24) {cout<<"("<<x<<"*"<<y<<")+"<<z<<"+"<<w<<"=24"<<endl;flag++;}  
    else if ((x*y)+z-w==24) {cout<<"("<<x<<"*"<<y<<")+"<<z<<"-"<<w<<"=24"<<endl;flag++;}   
    else if ((x*y)-(z/w)==24) {cout<<"("<<x<<"*"<<y<<")-("<<z<<"/"<<w<<")"<<"=24"<<endl;flag++;}   
    else if ((x*y)+(z/w)==24) {cout<<"("<<x<<"*"<<y<<")-("<<z<<"/"<<w<<")"<<"=24"<<endl;flag++;}   
    else if ((x*y)-z-w==24) {cout<<"("<<x<<"*"<<y<<")-"<<z<<"-"<<w<<"=24"<<endl;flag++;}   
    else if ((x*y)+(z*w)==24) {cout<<"("<<x<<"*"<<y<<")+("<<z<<"*"<<w<<")"<<"=24"<<endl;flag++;}   
    else if ((x*y)-(z*w)==24) {cout<<"("<<x<<"*"<<y<<")-("<<z<<"*"<<w<<")"<<"=24"<<endl;flag++;}   
    else if ((x*y)/(z*w)==24) {cout<<"("<<x<<"*"<<y<<")/("<<z<<"*"<<w<<")"<<"=24"<<endl;flag++;}   
    else if ((x*y)/(z-w)==24) {cout<<"("<<x<<"*"<<y<<")/("<<z<<"-"<<w<<")"<<"=24"<<endl;flag++;}   
    else if ((x*y)/(z+w)==24) {cout<<"("<<x<<"*"<<y<<")/("<<z<<"+"<<w<<")"<<"=24"<<endl;flag++;}
    else if ((x*y+z)/w==24) {cout<<"("<<x<<"*"<<y<<"+"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x*y-z)/w==24) {cout<<"("<<x<<"*"<<y<<"-"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x/y+z)/w==24) {cout<<"("<<x<<"/"<<y<<"+"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x/y-z)/w==24) {cout<<"("<<x<<"/"<<y<<"-"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x+y*z)/w==24) {cout<<"("<<x<<"+"<<y<<"*"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x+y/z)/w==24) {cout<<"("<<x<<"+"<<y<<"/"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x-y*z)/w==24) {cout<<"("<<x<<"-"<<y<<"*"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x-y/z)/w==24) {cout<<"("<<x<<"-"<<y<<"/"<<z<<")/"<<w<<"=24"<<endl;flag++;}
    else if ((x-y)*z+w==24) {cout<<"("<<x<<"-"<<y<<")"<<"*"<<z<<"+"<<w<<endl;flag++;}
    else if ((x-y)*z-w==24) {cout<<"("<<x<<"-"<<y<<")"<<"*"<<z<<"-"<<w<<endl;flag++;}
    else if ((x+y)*z+w==24) {cout<<"("<<x<<"+"<<y<<")"<<"*"<<z<<"+"<<w<<endl;flag++;}
    else if ((x+y)*z-w==24) {cout<<"("<<x<<"+"<<y<<")"<<"*"<<z<<"-"<<w<<endl;flag++;}
    else if ((x-y)/z-w==24) {cout<<"("<<x<<"-"<<y<<")"<<"/"<<z<<"-"<<w<<endl;flag++;}
    else if ((x+y)/z-w==24) {cout<<"("<<x<<"+"<<y<<")"<<"/"<<z<<"-"<<w<<endl;flag++;}
    else if ((x-y)/z+w==24) {cout<<"("<<x<<"-"<<y<<")"<<"/"<<z<<"+"<<w<<endl;flag++;}
    else if ((x+y)/z+w==24) {cout<<"("<<x<<"+"<<y<<")"<<"/"<<z<<"-"<<w<<endl;flag++;}
	else if ((x/y-z)*w==24) {cout<<"("<<x<<"/"<<y<<"-"<<z<<")*"<<w<<"=24"<<endl;flag++;}
	else if ((x/y+z)*w==24) {cout<<"("<<x<<"/"<<y<<"+"<<z<<")*"<<w<<"=24"<<endl;flag++;}
	else if ((x*y-z)*w==24) {cout<<"("<<x<<"*"<<y<<"-"<<z<<")*"<<w<<"=24"<<endl;flag++;}
	else if ((x*y-z)*w==24) {cout<<"("<<x<<"*"<<y<<"-"<<z<<")*"<<w<<"=24"<<endl;flag++;}
	return 0;   
}  

int check(int *a,int *b,int *c,int *d)//把相同的放一起,往后放 
{
	int temp;
	if((*a)!=(*b)&&(*a)!=(*c)&&(*a)!=(*d)&&(*b)!=(*c)&&(*b)!=(*d)&&(*c)!=(*d))//都不相等,则不做调整 
		return 0;
	else if((*a)==(*b)&&(*a)==(*c)&&(*a)==(*d))//都相等,也不做调整 
		return 4;
	else if((*a)==(*b)&&(*a)==(*c)&&(*a)!=(*d)) //其中三个相等 
	{
		temp=(*d);
		(*d)=(*a);
		(*a)=temp;
		return 3;
	}
	else if((*a)==(*b)&&(*a)==(*d)&&(*a)!=(*c)) //其中三个相等 
	{
		temp=(*c);
		(*c)=(*a);
		(*a)=temp;
		return 3;
	}
	else if((*a)==(*c)&&(*a)==(*d)&&(*a)!=(*b)) //其中三个相等 
	{
		temp=(*b);
		(*b)=(*a);
		(*a)=temp;
		return 3;
	}
	else if((*b)==(*c)&&(*b)==(*d)&&(*b)!=(*a)) //其中三个相等 
		return 3;
	else if((*a)==(*b)&&(*a)!=(*c)&&(*a)!=(*d)&&(*c)!=(*d)) //其中两个相等 
	{
		temp=(*c);
		(*c)=(*a);
		(*a)=temp;
		temp=(*d);
		(*d)=(*b);
		(*b)=temp;
		return 1;
	}
	else if((*a)==(*c)&&(*a)!=(*b)&&(*a)!=(*d)&&(*b)!=(*d))//其中两个相等
	{
		temp=(*d);
		(*d)=(*a);
		(*a)=temp;
		return 1;
	}
	else if((*a)==(*d)&&(*a)!=(*b)&&(*a)!=(*c)&&(*b)!=(*c))//其中两个相等
	{
		temp=(*c);
		(*c)=(*a);
		(*a)=temp;
		return 1;
	}
	else if((*b)==(*c)&&(*b)!=(*a)&&(*b)!=(*d)&&(*a)!=(*d))//其中两个相等
	{
		temp=(*d);
		(*d)=(*b);
		(*b)=temp;
		return 1;
	}
	else if((*b)==(*d)&&(*b)!=(*a)&&(*b)!=(*c)&&(*a)!=(*c))//其中两个相等
	{
		temp=(*c);
		(*c)=(*b);
		(*b)=temp;
		return 1;
	}
	else if((*c)==(*d)&&(*c)!=(*a)&&(*c)!=(*b)&&(*a)!=(*b))//其中两个相等
		return 1;
	else if((*a)==(*b)&&(*c)==(*d)&&(*a)!=(*c))//其中两组两个相等
		return 2;
	else if((*a)==(*c)&&(*b)==(*d)&&(*a)!=(*b))//其中两组两个相等
	{
		temp=(*b);
		(*b)=(*c);
		(*c)=temp;
		return 2;
	}
	else   //其中两组两个相等
	{
		temp=(*b);
		(*b)=(*d);
		(*d)=temp;
		return 2;
	}
}//204行 

4、运行结果
1.测试1:2,3,12,12:
在这里插入图片描述
2.测试2:1,2,2,3
在这里插入图片描述
我们发现是没有相应的运算式的,可以验证:
在这里插入图片描述
3.测试3:1,2,3,4
在这里插入图片描述
4.输入非法数据
在这里插入图片描述
并且由于我加了一个m_ret: 来做标记,可以返回重新输入。
5、总结
性能分析:
时间复杂度:因为最坏情况下随机序列(此时四个数字完全不同)的全排列个数是有限的,为4!3!种排列结果,因此时间复杂度O©
空间复杂度:O©
遇到的问题与解决方法:
容易出现表达式重复的现象,所以为了在一定程度上减少重复输出,所以我采用了对原始数据进行了一个简单的预处理,具体方法思路如上,这里就不做赘述了。
心得体会:
从结果上来看,程序代码是正确的,但是虽然长得完全一样的表达式是不会出现了,但是也只能做到这个最基本的判重,对于比如:2+3和3+2,我写的代码还是认为他们是不一样的,但在实际中,他们应该是一样的,即应该去重,不过这个实现较为困难,虽然有思路——可以采用排序和字符串比较来实现,但是那样代码长度会太长,所以只实现到了这样。
我感觉我对于数据的原始处理是写的不错的,可以根据数据的不同特征,做出不同的处理方式,一旦相同的原始,那么处理步数就会减少,那么效率就提高了。并且我可以统计出算24点的方法的数量并给出。
存在问题和改进方法:
即使我对数据进行了预处理,保证不可能出现完全一样的表达式,但是由于+和
具有交换性,所以,其实2+1和1+2应该认为是等价的,即是相同的表达式,但是由于篇幅问题,我没有展开来处理,但是我有以下思路来进行处理:思路①:用二叉树的结构,叶子节点放带计算的数字,然后他们的父节点先放运算符,然后用计算后的值替换,所以当某两个数字共同的父节点是+或者**时,我们可以交换左右孩子的值,看此时父节点算出来的值是否一样,如果一样就可以只输出其中某一个。思路①:和上面大致相同,但是对左右孩子的值做一个要求,即对于父节点是+或者*的,右孩子的值要大于等于左孩子的值,这样也可以做到去重。

标签:24,输出,课程设计,12,运算,相同,int,数据结构
来源: https://blog.csdn.net/zhulinhao/article/details/106898305

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有