最近看了《Java编程那些事》博客专栏,在讲到Java流程控制那块,提到了很多自己当初学习过程中涉及到的小算法,都很经典,以后会不断的将接触到的算法更新到本博文中,供自己以后查看,也可以作为大家学习的一个小资料。
1. 最大公约数
问题:求两个自然数的最大公约数。
这两个都是基础的数学问题,最大公约数指两个数字公共的约数中最大的,例如数字6的约数有1、2、3、6,数字9的约数有1、3、9,则数字6和数字9的公共约数有1和3,其中3是最大的公约数。
第一种思路:从1开始循环,每次把符合要求(即同时是两个数字的约数)的值都存储起来,那么最后一个存储起来的就是最大的约数。
则实现的代码如下:
int n = 6; int m = 9; int result = 1; for(int i = 1;i <= n;i++){ if((n % i == 0) && (m % i == 0)){ result = i; } } System.out.println(result);
int n = 6; int m = 9; int result = n > m ?m : n; for(int i = result;i >= 1;i--){ if((n % i == 0) && (m % i == 0)){ result = i; break; //结束循环 } } System.out.println(result);
for(int i = 0;i <= 100;i++){ //母鸡数量 for(int j = 0;j <= 100;j++){ //公鸡数量 for(int k = 0;k <= 100;k++){ //小鸡数量 //判断数量是否为100,以及金额是否为100 if((i +j + k == 100) && (i * 3 + j * 4 + k * 0.5 == 100)){ System.out.println(“母鸡数量:” + i + “ 公鸡数量:” + j + “ 小鸡数量” + k); } } } }
for(int i = 0;i <= 33;i++){ //母鸡数量 for(int j = 0;j <= 25;j++){ //公鸡数量 int k = 100 –i – j; //小鸡数量 //判断金额是否为100 if (i * 3 + j * 4 + k * 0.5 == 100){ System.out.println(“母鸡数量:” + i + “ 公鸡数量:” + j + “ 小鸡数量” + k); } } }
int num = 1000; //汽水数量 int drinkNum = 0; //喝掉的汽水数量 int emptyNum = 0; //空瓶子的数量 while(num > 0){ //有汽水可以喝 num--; //喝掉一瓶 emptyNum++; //空瓶子数量增加1 drinkNum++; //喝掉的汽水数量增加1 if(emptyNum == 3){ //有3个空瓶子,则去换 num++; //汽水数量增加1 emptyNum = 0; //空瓶子数量清零 } } System.out.println(“总共喝掉瓶数:” + drinkNum); System.out.println(“剩余空瓶子数:” + emptyNum);
int num = 1000; //汽水数量 int drinkNum = 0; //喝掉的汽水数量 int emptyNum = 0; //空瓶子的数量 while(num > 0){ //有汽水可以喝 drinkNum += num; //喝掉所有的汽水 emptyNum += num; //空瓶子数量等于上次剩余的加上这次喝掉的数量 num = emptyNum / 3; //兑换的汽水数量 emptyNum -= num * 3; //本次兑换剩余的空瓶子数量 } System.out.println(“总共喝掉瓶数:” + drinkNum); System.out.println(“剩余空瓶子数:” + emptyNum);
int num = 1000; //汽水数量 int drinkNum = 0; //喝掉的汽水数量 int emptyNum = 2; //空瓶子的数量 drinkNum = num + num/2 - 1; System.out.println(“总共喝掉瓶数:” + drinkNum); System.out.println(“剩余空瓶子数:” + emptyNum);
for(int i = 100;i < 1000;i++){ //循环所有三位数 int a = i % 10; //个位数字 int b = (i / 10) % 10; //十位数字 int c = i / 100; //百位数字 //判断立方和等于自身 if(a * a * a + b * b * b + c * c * c == i){ System.out.println(i); } }
for(int i = 2; i <= 1000; i++) { boolean isPrime = true; for(int j = 2; j < i; j++) { if(i != j && i % j == 0) { isPrime = false; break; } } if(isPrime) { System.out.println(i); } }
这样算是想到的最直接的方式,当然也是最笨的方式,因为每次判断的时候都会从2检查到i,聪明一点的方式是把i变成i/2,因为2/i以上的数肯定不会被i整除。
则实现的代码如下所示:
for(int i = 2; i <= 1000; i++) { boolean isPrime = true; for(int j = 2; j < i/2; j++) { if(i != j && i % j == 0) { isPrime = false; break; } } if(isPrime) { System.out.println(i); } }那么再聪明的方式就是把i/2变成根号i,因为根号i以上的数肯定不会被i整除。
for(int i = 2; i <= 1000; i++) { boolean isPrime = true; // Math.sqrt(i):开平方方法 for(int j = 2; j < Math.sqrt(i); j++) { if(i != j && i % j == 0) { isPrime = false; break; } } if(isPrime) { System.out.println(i); } }当然还有效率更高的方式,筛选法,在本文基础算法中不作介绍。
int[] num = new int[20]; num[0] = 1; num[1] = 1; //循环初始化 for(int i = 2;i < num.length;i++){ num[i] = num[i – 1] + num[i – 2]; } //循环输出 for(int i = 0;i < num.length;i++){ System.out.print(num[i] + " "); } System.out.println(); //换行在该代码中,初始化一个长度为20的数组,首先将数组中的前两个元素赋值成1,然后循环对后续的元素的赋值,如果当前元素的下标是i,则它前一个元素的下标是i-1,再前面一个元素的下标是i-2,只需要将这2个元素的值相加,然后赋值给当前元素即可。后面使用一个循环,输出数组中所有的元素,元素和元素之间有一个间隔的空格,在输出所有的元素以后换行。
int[] score = {90,78,90,96,67,86,78,92,79,85}; //评委打分 int sum = score[0]; //存储和 int max = score[0]; //存储最大值 int min = score[0]; //存储最小值 for(int i = 1;i < score.length;i++) { sum += score[i]; //求和 //获得最大值 if(max < score[i]) { max = score[i]; } //获得最小值 if(min > score[i]) { min = score[i]; } } //计算平均分 double avg = (sum – max – min) / 8.0; System.out.println(avg);下一篇: 基础算法(二)