Java经典算法问题2
二:经典算法问题?
2.1鸡兔同笼问题(穷举法)
已知:鸡兔共35只,共94只脚,那么鸡和兔各几只?
示例代码:
1 public class SameCage { 2 public static void main(String[] args) { 3 //循环变量j,控制小鸡的个数: 0到35递增 4 //循环变量t,控制兔子的个数: 35到0递减 5 for(int j=0,t=35; j<=35; j++,t--) {//如果有多个小条件,用逗号隔开 6 //保证脚的数量是94 7 if(j*2 + t*4 == 94) { 8 System.out.println("鸡:"+j+", 兔:"+t); 9 } 10 } 11 } 12 }
输出结果:
鸡:23, 兔:12
2.2斐波那契问题
已知:斐波那契数列的前几个数分别为0,1,1,2,3,5…从第三项开始,每一项都等于前两项的和.请接收用户输入的整数n,求出此数列的前n项.
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……
其规律很明显,从第3个数开始,每个数都等于它前两个数的和。
下面我们可以通过用户输入的数字n来输出斐波那契数列的前n项
示例代码:
1 public class Faibonacci { 2 public static void main(String[] args) { 3 System.out.println("请输入您要测试的数:"); 4 int n = new Scanner(System.in).nextInt(); 5 //判断n是否是不正常的范围 6 if(n<1){ 7 System.out.println("输入数据有误!!!"); 8 } 9 //n==1 10 if(n==1){ 11 System.out.println(0); 12 } 13 //n==2 14 if(n==2){ 15 System.out.println(0+"\t"+1); 16 } 17 //n==3 18 if(n==3){ 19 System.out.println(0+"\t"+1+"\t"+1); 20 } 21 //拼接前n项 22 if(n>3){ 23 System.out.print(0+"\t"+1+"\t"+1+"\t"); 24 } 25 //循环输出后面的数据 26 int f1=1; 27 int f2=1; 28 int next=0; 29 for(int i=4;i<=n;i++){ 30 next=f1+f2; 31 f1=f2; 32 f2=next; 33 System.out.print(next+"\t"); 34 } 35 } 36 }
如: 输入 10
结果为: 0 1 1 2 3 5 8 13 21 34
2.3打印100以内除了尾数为3,5,7的所有数
示例代码:
1 public class ForContinue { 2 public static void main(String[] args) { 3 System.out.println("结果为:"); 4 for(int i=1;i<=100;i++) { 5 int y = i%10;//100以内的数,通过取余求出尾数 6 if(y==3 || y==5 || y==7) { 7 continue;//如果尾数为3 5 7 ,则跳过后面的打印,进行下一轮循环 8 } 9 System.out.print(" "+i); 10 } 11 } 12 }
输出结果: 1 2 4 6 8 9 10 11 12 14 16 18 19 20 21 22 24 26 28 29 30 31 32 34 36 38 39 40 41 42 44 46 48 49 50 51 52 54 56 58 59 60 61
62 64 66 68 69 70 71 72 74 76 78 79 80 81 82 84 86 88 89 90 91 92 94 96 98 99 100
2.4求猴子大王
15个猴子围成一圈选大王,依次1-7循环报数,报到7的猴子被淘汰,直到最后一只猴子称为大王,问:哪只猴子会成为大王?
示例代码:
1 public class MonkeyKing { 2 public static void main(String[] args) { 3 //1.定义长度为15的数组保存猴子,boolean类型是为了判断猴子是否存活 4 boolean[] b=new boolean[15]; 5 6 //2.依次遍历每一只猴子 7 //true---未淘汰 false---已淘汰 8 for(int i=0;i<b.length;i++){ 9 b[i]=true;//先把所有猴子设置成存活 10 } 11 //3.定义变量保存猴子报的数 12 int num=0; 13 //4.定义变量保存剩余的猴子数 14 int monkeyLeft=15; 15 //5.定义数组下标 16 int index=0; 17 //6.循环,直到只剩最后一只猴子(猴子王) 18 while(monkeyLeft>1){//判断条件 19 //7.检测猴子是否已淘汰 20 if(b[index]){ 21 //8.报数 22 num++; 23 //9.判断报数是否为7 24 if(num==7){ 25 b[index]=false;//为7淘汰 26 monkeyLeft--;//猴子数减一 27 num=0;//报数归零 28 } 29 30 } 31 32 //10.下标移动 33 index++; 34 //11.围成一圈---最后一个置为0 35 if(index==15){ 36 index=0; 37 } 38 } 39 40 //遍历数组,找到最后活着的那个猴子王 41 for(int i=0;i<b.length;i++){ 42 if(b[i]){ 43 System.out.println(i+1); 44 } 45 } 46 } 47 }
输出结果: 5
2.5古典问题:生兔子问题
有一对兔子,从出生后第3个月起都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月兔子的对数为多少?
程序分析:前两个月兔子的对数为1
从第三个月开始,兔子的对数变成了 2 3 5 8 13 21 …
示例代码:
1 public class GetRabbitNum { 2 public static void main(String[] args) { 3 System.out.println("请输入要判断的月数:"); 4 int month = new Scanner(System.in).nextInt(); 5 System.out.println("第"+month+"月兔子的对数为:"+getSum(month)); 6 } 7 8 public static int getSum(int month) { 9 //如果是前两个月,还是1对兔子 10 if(month == 1 || month == 2) { 11 return 1; 12 }else { 13 //从第三个开始,兔子按照2 3 5 8 13 21变化 14 return getSum(month-1)+getSum(month-2); 15 } 16 }
请输入要判断的月数: 12
第12月兔子的对数为:144
2.6打印水仙花数
水仙花数:是指一个三位数,其各位数字立方和等于该数字本身
例如:153就是一个水仙花数,因为153 = 1³ + 5³ + 3³
示例代码:
1 public class GetDaffodilNum { 2 public static void main(String[] args) { 3 //1.遍历所有的三位数 4 for (int i = 100; i < 1000; i++) { 5 //2.调用自定义方法判断是不是水仙花数 6 if(isAim(i)) { 7 //3.如果是水仙花数,就打印 8 System.out.println(i); 9 } 10 } 11 } 12 13 //自定义判断水仙花数的方法 14 public static boolean isAim(int a) { 15 int x = a/100; 16 int y = a/10%10; 17 int z = a%10; 18 if(a == x*x*x+y*y*y+z*z*z) { 19 return true; 20 } 21 return false; 22 } 23 }
输出结果: 153 370 371 407
2.7回文问题
需求,如果一个用户输入的数据,从前到后或者从后到前读到的内容都是一样的,我们就称这种数据为"回文",比如123321 或者 12321 或者上海自来水来自海上等等
示例代码:
1 public class TestNumber { 2 public static void main(String[] args) { 3 System.out.println("请输入一个字符串:"); 4 String s = new Scanner(System.in).nextLine(); 5 6 if(!stringJudge(s)){ 7 System.out.println(s + "不是回文字符串"); 8 }else{ 9 System.out.println(s + "是回文字符串"); 10 } 11 12 } 13 14 //判断字符串是否回文 15 private static boolean stringJudge(String str) { 16 for (int i = 0; i < str.length() - i - 1; i++){ 17 if(str.charAt(i) == str.charAt(str.length() - i - 1)){ 18 continue; 19 }else{ 20 return false; 21 } 22 } 23 return true; 24 } 25 }
输出结果 : 请输入一个字符串: 12321 12321是回文字符串;
请输入一个字符串: 我是中国人 我是中国人不是回文字符串.
2.8二分法查找
二分法查找(Binary Search)也称折半查找,是指当每次查询时,将数据分为前后两部分,再用中值和待搜索的值进行比较,如果搜索的值大于中值,
则使用同样的方式(二分法)向后搜索,反之则向前搜索,直到搜索结束为止。
二分法使用的时候需要注意:二分法只适用于有序的数据,也就是说,数据必须是从小到大,或是从大到小排序的。
示例代码:
public class dichotomizingSearch { public static void main(String[] args) { // 二分法查找 int[] binaryNums = {1, 6, 15, 18, 27, 50}; int findValue = 27; int binaryResult = binarySearch(binaryNums, 0, binaryNums.length - 1, findValue); System.out.println("元素第一次出现的位置(从0开始):" + binaryResult); } /** * 二分查找,返回该值第一次出现的位置(下标从 0 开始) * @param nums 查询数组 * @param start 开始下标 * @param end 结束下标 * @param findValue 要查找的值 * @return int */ private static int binarySearch(int[] nums, int start, int end, int findValue) { if (start <= end) { // 中间位置 int middle = (start + end) / 2; // 中间的值 int middleValue = nums[middle]; if (findValue == middleValue) { // 等于中值直接返回 return middle; } else if (findValue < middleValue) { // 小于中值,在中值之前的数据中查找 return binarySearch(nums, start, middle - 1, findValue); } else { // 大于中值,在中值之后的数据中查找 return binarySearch(nums, middle + 1, end, findValue); } } return -1; } }
2.9完数问题
题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。
例如6=1+2+3.编程找出1000以内的所有完数。
程序分析:关键是找出数的所以因子,注意因子包含1!不包含本身,但是1不是完数。
示例代码:
public class PerfectNumber{ public static void main(String args[]){ int i,j; int sum=0; for(i=1;i<=1000;i++) { for(j=1;j<i;j++) { if(i%j==0) sum=sum+j; } if(sum==i) System.out.println(i); sum=0; } } }
输出结果: 6 28 496
2.10杨辉三角
他的两条斜边都是数字1组成,其余的数等于他肩上的两数之和
每行数字左右对称,由1开始,逐渐增大
第n行的数字个数为n
第n行的数字之和为2^n-1;
示例代码:
public class TriangleArray { public static void main(String[] args) { final int NMAX = 10; // allocate triangular array int[][] odds = new int[NMAX + 1][]; for (int n = 0; n <= NMAX; n++) odds[n] = new int[n + 1]; // fill triangular array for (int n = 0; n < odds.length; n++) for (int k = 0; k < odds[n].length; k++) { /* * compute binomial coefficient n*(n-1)*(n-2)*...*(n-k+1)/(1*2*3*...*k) */ int lotteryOdds = 1; for (int i = 1; i <= k; i++) lotteryOdds = lotteryOdds * (n - i + 1) / i; odds[n][k] = lotteryOdds; } for (int[] row : odds) { for (int odd : row) System.out.printf("%4d", odd); System.out.println(); } } }
输出结果:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具