一、 实验内容及要求
假设游戏者共有十人,且有10个不同的姓:张、王、李、赵、刘、于、许、金、钱、孙,魔术师将十个姓写在四张纸牌上,游戏者只需指出那几张纸上有自己的姓,魔术师就能准确的说出游戏者的姓,如图所示。
请编程实现:
(1) 分组输出姓氏,让用户选择姓氏所在的组。
(2) 给出你猜的姓氏。
二、 涉及的主要知识点
- JAVA语言的基础知识:变量定义,选择语句,循环语句,数组。
- 计算机基础中的进制转换。
三、 提示及预备知识
实际上是把这10个不同的姓依次编为1、2、3、4、5、6、7、8、9、10,再把这10个数用二进制表示为二进制1、10、11、100、110、111、1000、1001、1010,通过二制数据的规律将之后放在不同的组中,在用户指定的组后,根据相应的规律寻找到相应的姓氏。
实现示例图:
解法一:
思路讲解:
将这十个姓氏按顺序编号为1~10,它们对应的的二进制数值:
1 张 1
2 王 10
3 李 11
4 赵 100
5 刘 101
6 于 110
7 许 111
8 金 1000
9 钱 1001
10 孙 1010
分成四组之后:
(1)张 1 李 11 刘 101 许 111 钱 1001
(2)王 10李 11 于 110 许 111 孙 1010
(3)赵 100 刘 101 于 110 许 111
(4)金 1000 钱 1001 孙 1010
通过观察我们可以发现:
第一组从右往左数第一位都是1
第二组从右往左数第二位都是1
第三组从右往左数第三位都是1
第四组从右往左数第四位都是1
由于数组的索引是从左往右的,所以我们最好将组别进行逆序一下,变为第一组表示4四位二进制数字从右往左数第一位为1…这样做理解起来更清晰,当然不变也可以,但是代码相应的要改变
变换组别之后:
(1)金 1000 钱 1001 孙 1010
(2)赵 100 刘 101 于 110 许 111
(3)王 10李 11 于 110 许 111 孙 1010
(4)张 1 李 11 刘 101 许 111 钱 1001
定义一个长度为4的数组,接收二进制数字的每一位上的数字.
输入你的姓名在第几组之后,将数组的第几个位置处变为1(注意数组的索引=输入的位置-1)
将这个数组里面的元素依次输出来就是所选姓氏对应的二进制,可以直接输出,也可以通过将各位看做是千位,百位,十位,个位,再用元素乘以对应的十进制权值输出这个数字
根据存放所选姓氏对应的二进制的长度为4的数组中的元素,计算它对应的十进制数字,也就是计算出来我们给姓氏编的1~10的号码
**最后,**通过(位置-1)得到存放十个姓氏的数组索引,找到对应的姓氏.
分析完之后,我们可以发现,猜心术的奇妙之处在于分组的巧妙,分组有它的规律😎
解法一代码如下:
import java.util.Scanner; public class Guess2 { public static void main(String[] args) { char[] Name={'张','王','李','赵','刘','于','许','金','钱','孙'}; System.out.println("1.金钱孙\n2.赵刘于许\n3.王李于许孙\n4.张李刘许钱"); int[] num=new int[4]; for (int i = 0; i < 4; ) { System.out.println("请输入您所想的姓氏所在位置:(以-1结束):"); Scanner sc=new Scanner(System.in); int firstName=sc.nextInt(); if(firstName==1){ num[0]=1; } else if (firstName==2) { num[1]=1; }else if (firstName==3){ num[2]=1; } else if (firstName==4) { num[3]=1; } else if (firstName==-1) { break; } else{ System.out.println("输入错误,请重新输入"); continue; } i++; } //二进制表示 int Num=num[0]*1000+num[1]*100+num[2]*10+num[3]*1; System.out.println(Num); System.out.println("您的姓氏为:"); //转换为10进制 int Num2=(int)(num[0]*Math.pow(2,3)+num[1]*Math.pow(2,2)+num[2]* Math.pow(2,1)+num[3]*Math.pow(2,0)); //由于姓氏是从1开始编号的,所以在数组中的下标要记得-1 System.out.println(Name[Num2-1]); } }
解法一的注意点:
循环次数是数组num的长度4,注意输入相应的第几组将数组里面对应位置处改为1,如果输入的不合法,提示重新输入,索引不++,要用到continue,continue的作用是跳过后面的代码再次进入循环.
解法二:
解法更简单,思路一样,但是其中利用了一些Java的语法知识,可以达到省略一些代码的目的,更直接
import java.util.HashMap; import java.util.Scanner; public class mindGuessing { public static void main(String[] args) { HashMap Name=new HashMap(); Name.put(1,'张'); Name.put(10,'王'); Name.put(11,'李'); Name.put(100,'赵'); Name.put(101,'刘'); Name.put(110,'于'); Name.put(111,'许'); Name.put(1000,'金'); Name.put(1001,'钱'); Name.put(1010,'孙'); System.out.println("1:金钱孙\n2:赵刘于许\n3:王李于许孙\n4:张李刘许钱"); System.out.println("请输入所想的姓氏所在的位置:(以-1表示结束)"); int get, temp= 0; int[] group = new int[4]; Scanner in = new Scanner(System.in); while ((get = in.nextInt()) != -1) { group[temp] = get; temp++; } int num= 0; for (int j = 0; j < group.length; j++) { if (group[j] == 1) { num = num + 1000; } else if (group[j] == 2) { num = num + 100; } else if (group[j] == 3) { num = num + 10; } else if (group[j] == 4) { num = num + 1; } } System.out.println(num); System.out.println(Name.get(num)); } }
你学会了吗小伙伴们🥰记得点赞收藏博客,关注后续更多的java内容o~💕