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

 

posted @ 2022-10-29 16:12  zsq_fengchen  阅读(300)  评论(0编辑  收藏  举报