大数据预科班1~4天习题

第1~4天作业

1.(标识符命名)下面几个变量中,那些是对的?那些是错的?错的请说明理由

A. ILoveJava
B. $20
C. learn@java
D. antony.lee
E. Hello_World
F. 2tige

正确的:A B E 
错误的:C(@符号不满足) D(.符号不满足) F(数字不能开头)

2.假设有如下程序:

package com.corejava.chp1;
public class HelloWorld{
public static void main(String args[]){
System.out.println("Hello World");
}
}
1)假设这个代码存在hello.java 文件中,那这个程序能够编译通过?为什么?如果编译不通过,应该如何改进?

不可以编译通过:因为文件名不和public修饰的类名一致(在java中java文件名和公共类名必须一致)

2)假设这个.java 文件放在C:\javafile\目录下,CLASSPATH=.,则生成的.class文件应该放在什么目录下?如何运行?

生成的class文件在当前文件下的com/corejava/chp1下 
运行 java com.corejava.chp1.HelloWorld 
java -cp . com.corejava.chp1.HelloWorld(-cp代表目录) 
注:可以使用javac -d 路径 java文件名(.java) eg:javac -d . HelloWorld.java快速建包,并在最后一层文件下存放class文件。

3.(if 语句)读入一个整数,判断其是奇数还是偶数

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    int x = (new Scanner(System.in)).nextInt();
    if (x % 2 == 0) {
        System.out.println(x + "是偶数!");
    } else {
        System.out.println(x + "是奇数!");
    }
    }
    }

4.(操作符)有如下代码:int a = 5;int b = (a++) + (--a) +(++a);问执行完之后,b 的结果是多少?

(5)+(5)+(6)=16

5.(基本类型的运算)一家商场在举行打折促销,所有商品都进行8 折优惠。一位程序员把这个逻辑写成:

short price = ...; // 先计算出原价
short realPrice = price * 8 / 10; //再计算出打折之后的价格
问:这段代码是否正确?如果正确,假设price 为100,那计算之后的
realPrice值为多少?如果不正确,应该怎么改正?

不正确,因为整数计算打折有可能丢失精度; 
改正:货币金额的计算用BigDecimal(这里可以用double),并double realPrice=price*0.8; 
注:float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal,而且使用BigDecimal类也可以进行大数的操作。

6.(操作符)请说明>>与>>>之间的区别。

>>右移运算符:
    如果该数为正,则高位补0,若为负数,则高位补1;
>>>无符号右移运算符:
    也称逻辑右移,即若该数不论正负,高位都补0;
补充:
    <<是与>>对应的左移运算符,低位补0,;其实向左移动n位,就相当于乘以2的n次方,左移没有<<<运算符!

7.a = (a>b)?a:b;请问这段代码完成了什么功能?

求最大值

8.(if 语句)读入一个整数,表示一个人的年龄。如果小于6 岁,则输出“童”,6 岁到13 岁,输出“少儿”;14 岁到18 岁,输出“青少年”;18 岁到35 岁,输出“青年”;35 岁到50 岁,输出“中年”;50 岁以上输出“中老年”。

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    int x=new Scanner(System.in).nextInt();
    if(x<1&&x>200){
        System.out.println("输入年龄范围有误!");
    }else if(x<=6){
        System.out.println("童");
    }else if(x<=12){
        System.out.println("少儿");
    } else if(x<=18){
        System.out.println("青少年");
    }else if(x<=36){
        System.out.println("青年");
    }else if(x<=50){
        System.out.println("中年");
    }else{
        System.out.println("中老年");
    }
    }   
    }

9.(switch 语句)读入一个整数,如果是1~5 之间,则分别输出5 个福娃的名字,否则输出“北京欢迎你”

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    int x = new Scanner(System.in).nextInt();
    switch (x) {
    case 1: {
        System.out.println("贝贝");
        break;
    }
    case 2: {
        System.out.println("晶晶");
        break;
    }
    case 3: {
        System.out.println("欢欢");
        break;
    }
    case 4: {
        System.out.println("迎迎");
        break;
    }
    case 5: {
        System.out.println("妮妮");
        break;
    }
    default: {
        System.out.println("北京欢迎您!");
    }
    }
    }

10. (if 语句,赋值操作)*读入三个整数,输出这三个整数中最大的一个。

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
        System.out.println("请输入第一个整数:");
        int a1=new Scanner(System.in).nextInt();
        System.out.println("请输入第二个整数:");
        int a2=new Scanner(System.in).nextInt();
        System.out.println("请输入第三个整数:");
        int a3=new Scanner(System.in).nextInt();
        int max=a1;
        if((max>a2)&&(max>a3)){
            max=max;
        }else{
            if(a2>a3){
                max=a2;
            }else{
                max=a3;
            }
        }
        //注意扩展:最大值有多个时,且把key-value记住时需要=也加入
        System.out.println("最大值:"+max);
    }

    }   

11. (if 语句)*读入一个表示年份的整数,判断这一年是否是闰年。如何判断一个年份是否是闰年:1. 如果这个年份能够被4 整除,且不能被100 整除,则这一年是闰年。例如,1996 年是闰年,而相应的,1993 年就不是闰年。2. 如果这个年份能够被100 整除,则这个数必须要能被400 整除,才是闰年。例如,2000 年是闰年,1900 年不是闰年。

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    int x = new Scanner(System.in).nextInt();
    if ((x % 400 == 0) || (x % 4 == 0 && x % 100 != 0)) {
        System.out.println(x + "是闰年");
    } else {
        System.out.println(x + "是平年");
    }
    }
    }

12. (switch 语句)*完成一个简单的计算器程序。程序要求如下:1. 读入两个整数2. 提示用户选择对这两个整数的操作,即输出1 : +2 : -3 : *4 : /请输入您的选择:读入用户的选择,输出运算结果。

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    System.out.println("请输入第一个整数:");
    int x1=new Scanner(System.in).nextInt();
    System.out.println("请输入第二个整数:");
    int x2=new Scanner(System.in).nextInt();
    System.out.println("请选择操作+-*/:");
    String op=new Scanner(System.in).nextLine();
    switch(op){
    case "+" :{
        System.out.println(x1+x2);
        break;
    }
    case "-" :{
        System.out.println(x1-x2);
        break;
    }
    case "*" :{
        System.out.println(x1*x2);
        break;
    }
    case "/" :{
        System.out.println(x1/x2);
        break;
    }
    default :{
        System.out.println("输入操作有误!");
    }
    }
    }
    }

13. (if 语句)*托运计费问题:当货物重量小于20 公斤的时候,收费5 元,大于20 公斤小于100 公斤的时候超出20 公斤的部分按每0.2 元每公斤计费,如果超出100 公斤的时候,超的部分按照每公斤0.15 元计算。读入货物的重量,输出计算之后货物的运费。

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    double x=new Scanner(System.in).nextDouble();
    double sum=0;
    if(x<=20){
        sum=5;
    }else if(x<=100){
        sum=5+(x-20)*0.2;
    }else{
        sum=5+80*0.2+(x-100)*0.15;
    }
    System.out.println(sum);
    }
    }

14. (if 语句)中国的个税计算方法:应税所得为税前收入扣除2000 元(起征点),然后超出部分,按照以下税率收税:500 5%500-2000 10%2000-5000 15%5000-20000 20%20000-40000 25%40000-60000 30%60000-80000 35%80000-100000 40%100000 - ? 45%例:若月收入15000,则应税所得为15000-2000=13000;总的个人所得税为(13000-5000)20% + (5000-2000)*15% + (2000-500)10% + 5005%= 2225要求:读入一个整数,表示税前收入,输出应当缴纳的个人所得税和税后实际收入。

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    double x=new Scanner(System.in).nextDouble();
    x-=2000;
    double div=0;
    if(x<=500){
        div=x*0.05;
    }else if(x<=2000){
        sum=500*0.05+x(x-500)*0.1;
    }else if(x<=5000){
        sum=500*0.05+(2000-500)*0.1+(x-5000)*0.15;
    }else if(x<=2000){
        sum=500*0.05+(2000-500)*0.1+(5000-2000)*0.15+(x-5000)*0.2;
    }else if(x<=40000){
        sum=500*0.05+(2000-500)*0.1+(5000-2000)*0.15+(20000-5000)*0.2+(x-20000)*0.25;
    }else if(x<=60000){
        sum=500*0.05+(2000-500)*0.1+(5000-2000)*0.15+(20000-5000)*0.2+(40000-20000)*0.25+(x-40000)*0.3;
    }else if(x<=80000){
        sum=500*0.05+(2000-500)*0.1+(5000-2000)*0.15+(20000-5000)*0.2+(40000-20000)*0.25+(60000-40000)*0.3+(x-60000)*0.35;
    }else if(x<=100000){
        sum=500*0.05+(2000-500)*0.1+(5000-2000)*0.15+(20000-5000)*0.2+(40000-20000)*0.25+(60000-40000)*0.3+(80000-60000)*0.35+(x-80000)*0.4;
    }else{
        sum=500*0.05+(2000-500)*0.1+(5000-2000)*0.15+(20000-5000)*0.2+(40000-20000)*0.25+(60000-40000)*0.3+(80000-60000)*0.35+(100000-80000)*0.4+(x-100000)*0.45;
    }
    System.out.println("应缴纳"+num+"元,实际收入:"+(x+2000-sum)+"元!");
    }
    }

15. (if 语句,操作符)**读入一个三位数,计算其各位数字之和。例如:123各位数字之和为6

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    int x=new Scanner(System.in).nextInt();
    int sum=0;
    while(x!=0){
        sum+=(x%10);
        x=x/10;
    }
    System.out.println(sum);
    }
    }

16. (if 语句)**读入三个整数,把这三个整数按照由大到小的顺序输

    package com.tedu.study._day01;

    import java.util.Scanner;

    public class Demo01 {
    public static void main(String[] args) {
    int max = 0, mid = 0, min = 0;
    System.out.println("请输入第一个数:");
    int a = new Scanner(System.in).nextInt();
    System.out.println("请输入第二个数:");
    int b = new Scanner(System.in).nextInt();
    System.out.println("请输入第三个数:");
    int c = new Scanner(System.in).nextInt();
    if (a > b && a > c) {
        max = a;
        if (b > c) {
            mid = b;
            min = c;
        } else {
            mid = c;
            min = b;
        }
    } else {
        if (b > a && b > c) {
            max = b;
            if (a > c) {
                mid = a;
                min = c;
            } else {
                mid = c;
                min = a;
            }
        } else {
            max = c;
            if (a > b) {
                mid = a;
                min = b;
            } else {
                mid = b;
                min = a;
            }
        }
    }
    }
    }

第三天作业

1.计算1+2+3+...+100的和

package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        System.out.println(sum);
    }
}

2.计算1+3+5+...+99的和

package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if (i % 2 != 0) {
                sum += i;
            }
        }
        System.out.println(sum);
    }
}

3.用while和do-while重写第1题和第2题

//第一题while写法
package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum = 0;
        int i = 100;
        while (i > 0) {
            sum += i;
            i--;
        }
        System.out.println(sum);
    }
}


//第二题do-while写法
package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum = 0;
        int i = 100;
        do{
                sum += i;
            i--;
        }while(i>0);
        System.out.println(sum);
    }
}

//第二题while写法
package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum = 0;
        int i = 100;
        while (i > 0) {
            if (i % 2 != 0) {
                sum += i;
            }
            i--;
        }
        System.out.println(sum);
    }
}

//第二题do-while写法
package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum = 0;
        int i = 100;
        do{
            if (i % 2 != 0) {
                sum += i;
            }
            i--;
        }while(i>0);
        System.out.println(sum);
    }
}

4.(for)读入一个小于10的整数,并计算其阶乘

package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int x = new Scanner(System.in).nextInt();
        int sum = 1;
        for (int i = x; i > 1; i--) {
            sum *= i;
        }
        System.out.println(sum);
    }
}

//递归写法
package com.peng.demo;

public class Demo01 {
    public static void main(String args[]) {
        System.out.println(getJieCheng(5));
    }

    // 递归函数求阶乘
    public static int getJieCheng(int x) {
        if (x == 1) {
            return 1;
        }
        return x * getJieCheng(x - 1);
    }

}

5.(for)求100以内所有能被3整除,但不能被5整除的数字之和

package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum =0;
        for (int i = 1; i <=100; i++) {
            if(i%3==0&&i%5!=0){
                sum+=i;
            }
        }
        System.out.println(sum);
    }
}

6.(for)“百钱买百鸡”:3文钱可以买一只公鸡;2文钱可以买一只母鸡;1文钱可以买3只小鸡;用100文买100只鸡,问公鸡、母鸡、小鸡各有多少只?

设公鸡a只,母鸡b只,小鸡c只:
则:a+b+c=100
    3a+2b+c/3=100

100文最多可买公鸡(100/3=33),100文最多可买母鸡(100/2=50只),小鸡便宜,但最多只能99只(按100只算)即:
for(int x=0;x<=33;x++){
    for(int y=0;y<=50;y++){
        for(int z=0;z<=100){
            if((x+y+z==100)&&(3*x+2*y+z/3==100)){
                System.out.pri:nntln("公鸡:"+x+",母鸡:"+y+",小鸡"+z);
            }
        }
    }
}
//6种情况

7.搬砖问题:36块砖,36人搬砖,男搬4,女搬3,两个小孩抬一块砖;要求一次性全部把砖搬完,问:男人、女人、小孩各若干?

设男人a人,女人b人,小孩c人
则:a+b+c=36
    4a+3b+c/2=36
男生最多搬(4*9=36),女生最多搬(3*12=36),小孩最多搬(36/2=18)
则:
for(int x=0;x<=36;x++ ){
    for(int y=0;y<=36;y++){
        for(int z=0;z<=18){
            if((x+y+z==36)&&(x/4+y/3+z*2=36)){
                System.out.print("男人:"+(x/4)+",女人:"+(y/3)+",小孩:"+(2*z));
            }
        }
    }
}

8.(for)编程找出四位整数abcd中满足下述关系的数:(ab+cd)(ab+cd)=abcd

package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {

        for (int i = 1000; i < 9999; i++) {
            if (i == getSS(i)) {
                System.out.println(getSS(i));
            }
        }

    }

    public static int getSS(int x) {
        int a1 = x % 10;
        x = x / 10;
        int a2 = x % 10;
        x = x / 10;
        int a3 = x % 10;
        x = x / 10;
        int a4 = x % 1000;
        return (((10 * a2 + a1) + (10 * a4 + a3)) * ((10 * a2 + a1) + (10 * a4 + a3)));
    }
}

9.(循环)读入一个整数n, 输出如下图形

n=3时:
   *
  ***
 *****

n=4时:
   *
  ***
 *****
*******

每一行星数:(2*行数-1)

每一行前空格数:(2*n-1-行数)/2
每一行后空格数:(2*n-1-行数)/2
//代码
package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        /*
         * *
         * ***
         * *****
         * *******
         */
        int n = 4;
        // 遍历行
        for (int i = 0; i < n; i++) {
            // 遍历列
            for (int j = 0; j < (2 * n - 1); j++) {
                // 打印空格
                if ((j < (n - (i + 1))) || (j > (n + i - 1))) {
                    System.out.print(" ");
                } else {// 打印*
                    System.out.print("*");
                }
            }
            // 换行
            System.out.println();
        }

    }

}

10.(循环)输出99乘法表

package com.tedu.study._day01;

public class Demo01 {
    public static void main(String[] args) {
        for (int i = 1, j = 1; i <= 9; j++) {
            System.out.print(i + "*" + j + "=" + (i * j) + "\t");
            if (i == j) {
                j = 0;
                i++;
                System.out.println();
            }
        }
    }

}

11.(循环)水仙花数:一个三位数abc,如果满足a3+b3+c3=abc,则abc是水仙数

package com.peng.demo;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {

        for (int i = 100; i <= 999; i++) {
            if (i == getSS(i)) {
                System.out.println(getSS(i));
            }
        }

    }

    public static int getSS(int x) {
        int a1 = x % 10;
        x = x / 10;
        int a2 = x % 10;
        x = x / 10;
        int a3 = x % 10;
        return (int)(Math.pow(a1,3)+Math.pow(a2,3)+Math.pow(a3,3));
    }
}

12. (循环)**输入一个整数,计算它各位上数字的和。(注意:是任意位的整数)

package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int x = new Scanner(System.in).nextInt();
        int num = 0;
        while (x != 0) {
            num += x % 10;
            x /= 10;
        }
        System.out.println(num);
    }
}

13.输入一个整数,判断是否是质数(提示2~Math.sqrt(x))

package com.tedu.study._day01;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        boolean isok = true;
        int x = new Scanner(System.in).nextInt();
        for (int i = 2; i < (int) Math.sqrt(x); i++) {
            if (x % i == 0) {
                System.out.println(x + "不是质数");
                isok = false;
                break;
            }
        }
        if (isok) {
            System.out.println(x + "是质数");
        }
    }
}

14.完数:如果一个数等于它所有因子之和,eg:6=1+2+3,求1000以内的完数(和亲密数相似)

package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        for (int i = 3; i <= 1000; i++) {
            if (i == getXSum(i)) {
                System.out.println("完数:" + i);
            }
        }

    }

    public static int getXSum(int x) {
        int sum = 1;
        for (int i = 2; i <= x / 2; i++) {
            if (x % i == 0) {
                sum += i;
            }
        }

        return sum;
    }
}

15.计算圆周率:PI=4/1-4/3+4/5-4/7+4/9-4/11+...,圆周率在3.1415926和3.1415927之间,求要得到这样的结果,经过多少次加减运算可以得到

package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        /*
         * ###15.计算圆周率:PI=4/1-4/3+4/5-4/7+4/9-4/11+...,
         * 圆周率在3.1415926和3.1415927之间,求要得到这样的结果,经过多少次加减运算可以得到
         */
        double PI = 0;
        int i = 1;
        int num = 0;
        while (PI < 3.1415926 || PI > 3.1415927) {
            if ((num + 1) % 2 == 0) {
                PI = PI - (4.0 / i);
            } else {
                PI = PI + (4.0 / i);
            }
            i += 2;
            num++;
        }
        System.out.println(num);
    }

}

16.faibonacci(斐波那契数列):0,1,1,2,3,5,8...输入n,求前n项

//递归(函数自己调用自己)
package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        // 前10项斐波那契数
        for (int i = 1; i <= 10; i++) {
            System.out.println(faibonacci(i));
        }
    }

    // 0,1,1,2,3,5...
    public static int faibonacci(int n) {
        if (n == 1) {
            return 0;
        }
        if (n == 2) {
            return 1;
        }
        return faibonacci(n - 1) + faibonacci(n - 2);
    }
}

//简单方法:设置三个变量first,second,third
    ...
    for(){
        third=first+second;
        first=second;
        second=third;
    }
    ...

17.(循环)一个int是由32的二进制位组成,每个二进制数要么0,要么1。要求读入一个int类型的数n,计算它的32个二进制中共有多少位1

//倒取模将10进制数转化为二进制数并在其中计算1的数量(正整数)
//注意负整数
//方法1.取反(01相转)eg:-5 -> 4;  4有一个1,则-5有32-1=31个1
//方法2.&1并且右移
        eg:
            1110 0001 1110 1010 0010 0010 0001 0101
            &
            0000 0000 0000 0000 0000 0000 0000 0001
            =
            0000 0000 0000 0000 0000 0000 0000 0001即1
            然后右移继续判断

package com.peng.demo;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        int sum = 0;
        int x = new Scanner(System.in).nextInt();
        // 正数直接求,负数先取反,在求
        if (x < 0) {
            x = ~x;
            for (int i = 0; i < get32Array(5).length; i++) {
                sum += get32Array(5)[i];
            }
            System.out.println("该数组1的个数为" + (32 - sum));
        } else {
            for (int i = 0; i < get32Array(5).length; i++) {
                sum += get32Array(5)[i];
            }
            System.out.println("该数组1的个数为" + sum);
        }

    }

    public static int[] get32Array(int n) {
        int[] temp = new int[32];
        int i = 31;
        while (n != 0) {
            temp[i] = n % 2;
            n /= 2;
            i--;
        }
        return temp;
    }
}

18.三天打鱼两天晒网:假设有一个人从2000,1,1开始,输入三个整数,分别代表年月日,问当前日期是在打鱼还是晒网

/*算出当日距2000,1,1的天数,取模5,如果为1,2,3位打鱼;4,5为晒网。
注意平年和闰年的2月*/
//代码
package com.peng.demo;

import javax.swing.JOptionPane;

public class Demo01 {
    public static void main(String[] args) {
        switch (1 + (getDays(2000, 1, 6) % 5)) {
        // 1,2,3打鱼
        case 1:
        case 2:
        case 3: {
            System.out.println("打鱼!");
            break;
        }
        // 4,5晒网
        case 4:
        case 5: {
            System.out.println("晒网!");
            break;
        }
        }
    }

    public static int getDays(int year, int month, int day) {
        // 一:数据校验:
        // 1、年份>=2000;
        // 2、1<=月份<=12;
        // 3、日子数(1,3,5,7,8,10,12月)1~31天、(4,6,9,11)1~30天、(2)平年1~28,闰年1~29
        if (year < 2000) {
            JOptionPane.showMessageDialog(null, "年份为2000以后!");
            return -1;
        }
        if (month < 1 || month > 12) {
            JOptionPane.showMessageDialog(null, "月份为1~12月!");
            return -1;
        }
        switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12: {
            if (day < 1 || day > 31) {
                JOptionPane.showMessageDialog(null, "此月为大月,范围为1~31");
                return -1;
            }
            break;
        }

        case 4:
        case 6:
        case 9:
        case 11: {
            if (day < 1 || day > 30) {
                JOptionPane.showMessageDialog(null, "此月为小月,范围为1~30");
                return -1;
            }
            break;
        }
        case 2: {
            if ((!isRunNian(year)) && (day < 1 || day > 28)) {// 平年
                JOptionPane.showMessageDialog(null, "此月为平年2月,范围为1~29");
                return -1;
            }
            if ((isRunNian(year)) && (day < 1 || day > 29)) {// 闰年
                JOptionPane.showMessageDialog(null, "此月为闰年2月,范围为1~29");
                return -1;
            }
            break;
        }
        }
        // 二:计算天数
        return getAllDays(year, month, day);
    }

    // 是否是闰年
    public static boolean isRunNian(int year) {
        if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))) {
            return true;
        } else {
            return false;
        }

    }

    // 计算所有天数
    public static int getAllDays(int year, int month, int day) {
        int all_days = 0;
        int num_RunNian = 0;//
        int num_PingNian = 0;// 平年个数

        for (int i = 2000; i < year; i++) {
            if (isRunNian(year)) {
                num_RunNian++;// 计算闰年个数
            } else {
                num_PingNian++;
            }
        }

        all_days += (366 * num_RunNian + 365 * num_PingNian);
        // 计算当年的天数
        if (isRunNian(year)) {// 闰年
            switch (month) {
            case 1: {
                all_days += day;
                break;
            }
            case 2: {
                all_days += (31) + day;
                break;
            }
            case 3: {
                all_days += (31 + 29) + day;
                break;
            }
            case 4: {
                all_days += (31 + 29 + 31) + day;
                break;
            }
            case 5: {
                all_days += (31 + 29 + 31 + 30) + day;
                break;
            }
            case 6: {
                all_days += (31 + 29 + 31 + 30 + 31) + day;
                break;
            }
            case 7: {
                all_days += (31 + 29 + 31 + 30 + 31 + 30) + day;
                break;
            }
            case 8: {
                all_days += (31 + 29 + 31 + 30 + 31 + 30 + 31) + day;
                break;
            }
            case 9: {
                all_days += (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31) + day;
                break;
            }
            case 10: {
                all_days += (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30) + day;
                break;
            }
            case 11: {
                all_days += (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31)
                        + day;
                break;
            }
            case 12: {
                all_days += (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)
                        + day;
                break;
            }
            }
        } else {
            switch (month) {
            case 1: {
                all_days += day;
                break;
            }
            case 2: {
                all_days += (31) + day;
                break;
            }
            case 3: {
                all_days += (31 + 28) + day;
                break;
            }
            case 4: {
                all_days += (31 + 28 + 31) + day;
                break;
            }
            case 5: {
                all_days += (31 + 28 + 31 + 30) + day;
                break;
            }
            case 6: {
                all_days += (31 + 28 + 31 + 30 + 31) + day;
                break;
            }
            case 7: {
                all_days += (31 + 28 + 31 + 30 + 31 + 30) + day;
                break;
            }
            case 8: {
                all_days += (31 + 28 + 31 + 30 + 31 + 30 + 31) + day;
                break;
            }
            case 9: {
                all_days += (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31) + day;
                break;
            }
            case 10: {
                all_days += (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30) + day;
                break;
            }
            case 11: {
                all_days += (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31)
                        + day;
                break;
            }
            case 12: {
                all_days += (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30)
                        + day;
                break;
            }
            }

        }
        return all_days - 1;
    }
}

19.分解质因数并打印出来

package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        int n = 99;
        System.out.println("1");
        for (int i = 2; i <= n / 2; i++) {
            if (n % i == 0) {
                System.out.println(i);
            }
        }
    }
}

第四天作业

练习1. 下列数组的声明有哪些是对的?错的应该怎么修改?

  • A. int[] a;
  • B. int a[] = new int[3];
  • C. int[] a;a = {1,2,3,4,5};
  • D. int[] a = new int[3]{1,2,3};

正确的:A、B 
int[] a={1,2,3,4,5}; 
int[] a=new int[3]; 
//1.长度不同 2、不知道如何存、如何放 
int[] a = new int[5]{1,2,3};

2. 看下面的代码,写出输出的结果

public class Ex2 {public static void main(String[] args) {
int[] a = {1,2,3,4,5};
expand(a);
changeArray(a);
printArray(a);
}
public static void expand(int[] a){
int[] newArray = new int[a.length * 2];
System.arraycopy(a, 0, newArray, 0, a.lena = newArray;
}
public static void changeArray(int[] a){
a[0] = 10;
}   
public static void printArray(int[] a){
for(int i = 0; i<a.length; i++){
System.out.print(a[i] + "\t");
}   
System.out.println();
}
}   
请选择输出结果:
A. 10 2 3 4 5
B. 1 2 3 4 5
C. 10 2 3 4 5 0 0 0 0 0
D. 1 2 3 4 5 0 0 0 0 0


同一块内存与不同内存的改变

3. 写一个函数,计算一个整数数组的平均值

package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6 };
        System.out.println(getAvg(arr));
    }

    // 数组求平均值
    public strictfp static double getAvg(int[] arr) {
        double sum = 0;
        for (int i : arr) {
            sum += i;
        }
        return sum / arr.length;
    }

}

4. 自定义一个整数数组a,读入一个整数n,如果n 在数组中存在,则输出n 的下标;如果不存在,则输出-1。

//简单方法
package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6 };
        System.out.println(getIndex(arr, 3));
    }

    // 从整数数组中元素的下标:存在返回最后一个相同数据的下标,不存在返回-1
    public static int getIndex(int[] arr, int x) {
        for (int i = 0; i < arr.length; i++) {
            if (x == arr[i]) {
                return i;
            }
        }
        return -1;
    }

}

5. 给定一个数组,输出数组中的最大值和最小值

//简单方法
package com.peng.demo;

import java.util.Arrays;

public class Demo01 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 0 };
        System.out.println(getIndex(arr)[0]);
        System.out.println(getIndex(arr)[1]);
    }

    // 求一个数组中的最大值和最小值
    public static int[] getIndex(int[] arr) {
        int[] maxAndMin = new int[2];
        Arrays.sort(arr);
        maxAndMin[0] = arr[arr.length - 1];
        maxAndMin[1] = arr[0];
        return maxAndMin;
    }
}

6. 已知一个二维数组A 表示一个矩阵,求AT。其中,AT 表示矩阵的转置。矩阵转置的含义:表示把一个矩阵行列互换。例如,有下面的矩阵M 以及其转置M

package com.peng.demo;

import java.util.Arrays;

public class Demo01 {
    public static void main(String[] args) {
        int[][] a = { { 2, 3 }, { 4, 5 }, { 6, 7 } };
        int[][] b = new int[a[0].length][a.length];
        for (int i = 0; i < a[0].length; i++) {
            for (int j = 0; j < a.length; j++) {
                b[i][j] = a[j][i];
                System.out.print(a[j][i]);
            }
            System.out.println();
        }
    }

}

7. *给定一个数组,把这个数组中所有元素顺序进行颠倒。

//思路:用一个循环,两个条件进行约束
//代码    
package com.peng.demo;

import java.util.Arrays;

public class Demo01 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 0 };
        arr = getBackArray(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    //反转数组
    public static int[] getBackArray(int[] arr) {
        for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }
        return arr;
    }
}

8. *数组的扩容。给定一个数组,要求写一个expand 函数,把原有数组的长度扩容一倍,并保留原有数组原有的内容。例如,给定一个数组int[] a = {1,2,3},则扩容之后,a 数组为:{1,2,3,0,0,0}

//关键代码
package com.peng.demo;

import java.util.Arrays;

public class Demo01 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5, 6, 0 };
        arr = getExtendsArray(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    // 扩展数组
    public static int[] getExtendsArray(int[] arr) {
        int[] temp=new int[arr.length*2];
        System.arraycopy(arr,0,temp,0,arr.length);
        arr=temp;
        return arr;
    }
}

9. *数组的插入和删除写两个函数,一个函数为delete 函数,声明如下:public static void delete(int pos)该函数表示删除数组pos 位置上的元素。第二个函数为insert 函数,声明如下:public static void insert(int pos, int value)该函数表示在数组pos 位置上插入value 值。为了能在多个函数中使用同一个数组,需要把这个数组写在函数的外面,类的里面,并使用static 修饰。为了方便,还应该定义一个index 变量,用来保存数组的有效元素的个数。例如下面的代码

public class TestInsertDelete{
    static int[] a = {1,3,2,5,7}; //多个函数可以直接操作该数组
    static int index = 5;
    public static void main(String args[]){
        delete(2); //1 3 5 7
        insert(1, 4); //1 4 3 5 7
        insert(0, 6); //6 1 4 3 5 7
    }
    public static void delete(int pos){…}
    public static void insert(int pos, int value){…}
}

实现方式:1. delete 方法:把数组pos 位后的所有元素向前移动1 位2. insert 方法:把数组pos 位以及之后的元素向后移动1 位,然后设置value。要注意的是,insert 时有可能需要数组扩容。有效元素的个数的含义:对于a 数组,调用一次delete 之后,a 数组的长度不变,长度依然为5,然而有效元素的个数为4 个。Tips:insert 方法中,如何判断是否需要扩容:比较有效元素的个数和数组的长度,如果这两者一致,则需要扩容。

//题目的正确写法
/*
增加时:控制数组下标(index)+防止数组越界
if(index>=arr.length-1){
    //数组扩容两倍
}
1. 判断下标是否越界 是的话reture掉
2. 判断数组大小是否已满(是否需要扩容)
3. 放元素:方法一:从后往前遍历,前一位覆盖后一位+插入要插入的值;方法二:System.arraycopy();
*/

/*
删除时:控制数组下标(index)
1. 判断下标是否越界(pos>index)
2. 移动pos之后的数到前一位,直到index也覆盖了index-1的内容【方法:for循环或者用System.arraycope();】
3. index--
4. 注意数组有效数小于等于数组长度,可以缩容(缩小为原数组的一半)
*/
//上述增加、删除
package com.peng.demo;

import java.util.Arrays;

/*
 * 数组的插入与删除
 */
public class ArraysOP {
    static int[] arr = new int[5];
    // 定义一个变量,标识要操作的数组下标
    static int index = 0;

    // 向数组中添加元素
    public static void add(int i) {
        // 判断数组是否需要扩容
        if (index >= arr.length) {
            arr = Arrays.copyOf(arr, arr.length * 2);
        }
        // 存放元素
        arr[index] = i;
        // 下标后移
        index++;
    }

    // 删除元素
    public static void delete(int pos) {
        if (pos >= index) {
            System.out.println("超出数据范围");
            return;

        }
        /*
         * //后一位覆盖前一位 for(int i=pos;i<index-1;i++){ arr[i]=arr[i+1]; }
         */
        System.arraycopy(arr, pos + 1, arr, pos, index - pos - 1);
        // 下标前移
        index--;
        // 将当前位置的数据置为0
        arr[index] = 0;
        // 判断是否可以进行缩容
        if (index <= arr.length / 2) {
            arr = Arrays.copyOf(arr, arr.length / 2);
        }
    }

    // 向数组插入元素
    public static void insert(int pos, int value) {
        // 判断下标
        if (pos > index || pos < 0) {
            System.out.println("插入失败!");
            return;
        }
        // 判断数组是否需要进行扩容
        if (index >= arr.length) {
            arr = Arrays.copyOf(arr, arr.length * 2);
        }
        // 插入数据,后一位覆盖前一位
        /*
         * for(int i=index;i>pos;i--){ arr[i]=arr[i-1;] }
         */
        System.arraycopy(arr, pos, arr, pos + 1, index - pos);
        arr[pos] = value;
        // 向前移动一位
        index++;
    }

    public static void main(String[] args) {
        add(1);
        add(5);
        add(3);
        delete(2);
        insert(2, 10);
        System.out.println(Arrays.toString(arr));
    }
}


//简单方式:
//删除:new新数组的长度为原数组-1,将数据进行转移,除了要删除的
//插入:new新数组的长度为原数组+1,将数据(插入的数据也放在其中)进行转移到新数组中
package com.peng.demo;

public class Demo01 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4 };
        // 插入测试
        System.out.println(getInsArraya(arr, 1, 10)[1]);

        // //删除测试
        // System.out.println(getDelArraya(arr,0)[0]);

    }

    // 删除第x个元素
    public static int[] getDelArraya(int[] arr, int x) {
        int[] temp = new int[arr.length - 1];
        for (int i = x; i < arr.length - 1; i++) {
            arr[i] = arr[i + 1];
            System.out.println("-----" + arr[i + 1] + "--------");
        }
        System.arraycopy(arr, 0, temp, 0, arr.length - 1);
        return temp;
    }

    // 插入将y插入x处
    public static int[] getInsArraya(int[] arr, int x, int y) {
        int[] temp = new int[arr.length + 1];
        for (int i = 0; i < x; i++) {
            System.arraycopy(arr, 0, temp, 0, (x + 1));
        }
        temp[x] = y;
        for (int j = x + 1; j < temp.length; j++) {
            System.arraycopy(arr, x, temp, (x + 1), (temp.length - (x + 1)));
        }
        return temp;
    }
}

10. *完成数组的冒泡排序算法:给定一个数组:int[] a = {1,3,2,7,5},利用冒泡排序对其按照从小到大的顺序排序,然后输出结果

//冒泡算法:相邻两个数据进行比较,规律:趟数与循环次数的和为数组长度 package com.peng.demo;

public class Demo01 {

    public static void main(String[] args) {
        int[] a = { 1, 3, 2, 7, 5 };
        System.out.println(getOrderArray(a)[0]);
        System.out.println(getOrderArray(a)[1]);
        System.out.println(getOrderArray(a)[2]);
        System.out.println(getOrderArray(a)[3]);
        System.out.println(getOrderArray(a)[4]);
    }

public static int[] getOrderArray(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        for (int j = 1; j <= arr.length - i; j++) {
            if (arr[j - 1] > arr[j]) {
                int temp = arr[j - 1];
                arr[j - 1] = arr[j];
                arr[j] = temp;
            }
        }
    }

    return arr;
}
}

11. *使用第二种算法对数组进行排序

冒泡排序:相邻两个数进行比较,一次找一个最大的或是最小的(第n轮+第n轮的比较次数=数组长度)
public static int[] getOrderArray(int[] arr) {
    for (int i = 1; i < arr.length; i++) {
        for (int j = 1; j <= arr.length - i; j++) {
            if (arr[j - 1] > arr[j]) {
                int temp = arr[j - 1];
                arr[j - 1] = arr[j];
                arr[j] = temp;
            }
        }
    }

    return arr;
}

选择排序:第n位和之后的数字相比较(选中某一位一次和其他位置比较,习惯上从0位开始依次比较)
public static int[] getOrderArray(int[] arr) {
    for(int i=1;i<=arr.length;i++){
        for(int j=i-1;j<arr.length;j++){
            if(arr[i-1]>arr[j]){
                int temp=arr[i-1];
                arr[i-1]=arr[j];
                arr[j]=temp;
            }
        }
    }

    return arr;
}

12. *输出杨辉三角

1 
1 1
1 2 1
1 3 3 1
。。。

package com.peng.demo;

import java.util.Arrays;
import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        // 杨辉三角
        int n = 10;
        int[][] arr = new int[n][];
        for (int i = 0; i < arr.length; i++) {
            int[] temp = new int[(i + 1)];
            arr[i] = temp;
            for (int j = 0; j < temp.length; j++) {
                if (temp.length > 2) {
                    if (j == 0 || j == temp.length - 1) {
                        arr[i][j] = 1;
                    } else {
                        arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
                    }
                } else {
                    arr[i][j] = 1;
                }
            }
        }
        //打印杨辉三角
        for (int a = 0; a < arr.length; a++) {
            for (int b = 0; b < arr[a].length; b++) {
                System.out.print(arr[a][b] + "\t");
            }
            System.out.println();
        }
    }

}

13. *数学黑洞6174已知:一个任意的四位正整数。将数字重新组合成一个最大的数和最小的数相减,重复这个过程,最多七步,必得6174。即:7641-1467=6174。将永远出不来。求证:所有四位数数字(全相同的除外),均能得到6174。输出掉进黑洞的步数。

package com.peng.demo;

import java.util.Arrays;
import java.util.Scanner;

public class Demo01 {

    public static void main(String[] args) {
        int x = new Scanner(System.in).nextInt();
        do {
            System.out.println(x);
            x = getMax(x) - getMin(x);
        } while (x != 6174);
        System.out.println(x);
    }

    // 任意数字求最大值
    public static int getMax(int x) {
        int[] temp = new int[4];
        for (int i = 0; i < temp.length; i++) {
            temp[i] = x % 10;
            x /= 10;
        }
        Arrays.sort(temp);
        return 1000 * temp[3] + 100 * temp[2] + 10 * temp[1] + temp[0];
    }

    // 任意数字求最小值
    public static int getMin(int x) {
        int[] temp = new int[4];
        for (int i = 0; i < temp.length; i++) {
            temp[i] = x % 10;
            x /= 10;
        }
        Arrays.sort(temp);
        // 防止出现类类似0123,0开头的数
        return 1000 * temp[0] + 100 * temp[1] + 10 * temp[2] + temp[3];
    }
}

14. *筛选法求质数:输入一个整数n,求小于这个整数的所有质数。

算法:定义一个长度为n 的boolean 数组,true 表示是质数,false 表示不是质数。初始均为true。之后从2 开始循环:1. 找到第一个值为true 的下标i2. 把所有下标为i 的倍数的值置为false。直到扫描完数组中的所有数值。最后遍历数组,如果下标i 的值为true,则说明i 为质数

//注意1:数组的下标是从0开始的,如果数想与下标一一对应的话,必须将数组大小+1处理;
//注意2:遍历时,0,1不用遍历,直接从2开始     
package com.peng.demo;

import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        int n = new Scanner(System.in).nextInt();
        // 因为下标从0开始到length-1,所以这里创建时大小为n+1;
        boolean[] b = new boolean[n + 1];
        // 开始认为所有数都是质数
        for (int i = 2; i < b.length; i++) {
            b[i] = true;
        }
        //
        for (int j = 2; j < b.length; j++) {
            if (b[j]) {
                // 把该质数的倍数全部置为false
                for (int m = j * 2; m < b.length; m += j) {
                    b[m] = false;
                }
            }
        }

        // 输出结果
        for (int i = 2; i < b.length; i++) {
            if (b[i]) {
                System.out.println(i);
            }
        }
    }
}

15. **定义一个奇数阶二维数组,把每个元素顺序填入不同的自然数,要求行列和对角线元素相加的结果相等

算法:1. 第一个数字填在第一行正中间2. 如果可以填在斜上方,则数字尽量填在斜上方3. 如果斜上方出了上边界,则数字填入同一列最下端4. 如果斜上方出了右边界,则数字填入同一行最左端5. 如果既出了右边界,又出了上边界,则数字填入上一个数字的下方6. 如果斜上方已经被填过,则数字填入上一个数字的下方

16. **十五个猴子围成一圈选大王,依次1-7 循环报数,报到7 的猴子被淘汰,直到最后一只猴子成为大王。问,哪只猴子最后能成为大王

package com.peng.demo;

import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int m = s.nextInt();// 多少只猴子
        int n = s.nextInt();// 报数大小
        s.close();

        // 记录猴子的个数
        boolean[] b = new boolean[m];
        // 记录报数
        int i = 1;
        // 记录剩余猴子的个数
        int left = m;
        // 记录哪只猴子在报数
        int index = 0;

        while (left != 1) {
            // 需要判断猴子还健在
            if (!b[index]) {
                // 如果报到n,将被舍弃
                if (i == n) {
                    b[index] = true;// 注意:这里利用Boolean的初始值为false的性质来操作
                    // 重新开始报数
                    i = 1;
                    // 剩余猴子数-1
                    left -= 1;
                } else {
                    // 否则的话,继续报数
                    i++;
                }
            }
            // 报数者+1
            index++;
            // 如果报数者超出了总数,则返回第一个
            if (index == m) {
                index = 0;
            }
        }
        // 输出猴子大王
        for (int o = 0; o < b.length; o++) {
            if (!b[o]) {
                System.out.println("第" + (o + 1) + "是大王!");
            }
        }

    }
}

17. *螺旋填数读入两个整数m,n,输出一个m 行n 列的矩阵,这个矩阵是1~mn 这些自然数按照右、下、左、上螺旋填入的结果。例如:读入4, 5,则输出

  • 1   2    3    4 5
  • 14 15 16 17 6
  • 13 20 19 18 7
  • 12 11 10 9   8

思路:分析题目,数字打印在控制台上后形成的是一个矩阵,考虑用二维数组来实现。那么定义一个int[m][n]的二维数组,m控制行,n控制列。并将这个二维数组中的元素全部用-1来填充,接下来需要考虑的就是如何将这些数据装入二维数组的问题。
   首先,数字由外向内旋转从1-m*n递增,观察数据发现,定义一个变量从1开始不断循环下面4步操作,直到变量值大于或者等于m*n的时候停止循环,最后将二维数组遍历输出即可:
    1、应该先让n递增,将变量自增1装入,当数字装入到第n列或者发现该位置的数字不是-1的时候(当不在是-1时,应该退回一位),转2;
    2、应该让m递增,将变量自增1装入,当数字装入到第m行或者发现该位置数字不是-1的时候(当不在是-1时,应该退回一位)转3;
    3、应该让n递减, 将变量自增1装入 ,当n减至0或者发现该位置的数字不是-1时(当不在是-1时,应该退回一位)转4;
    4、应该让m递减, 将变量自增1装入 ,当m减至0或者发现该位置的数字不是-1时(当不在是-1时,应该退回一位)转1; 

1. 输入行列值 m,n
2. 创建二维数组
3. 变量记录行下标 从0开始
4. 变量记录列下标 从0开始
5. 将数组第一个数置为1,
6. 向数组中填数
7. 定义方向来控制方向,int[][] direction={{0,1},{1,0},{0,-1},{-1,0}};//右下左上
8. 定义二维数组记录下标的变化 

package com.peng.demo;

import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int m = s.nextInt();// 行数
        int n = s.nextInt();// 列数
        s.close();

        // 定义一个二维数组
        int[][] arr = new int[m][n];
        // 定义一个变量记录对应的行下标
        int row = 0;
        // 定义一个变量记录对应的列下标
        int col = 0;
        // 将第一个数置为1
        arr[row][col] = 1;

        // 定义一个二维数组控制方向
        // {0,1}右
        // {1,0}下
        // {0,-1}左
        // {-1,0}上
        int[][] direction = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };

        // 定义一个变量记录二维数组下标的变化
        int di = 0;

        // 向数组中填数(螺旋填入,从第二个数开始填入)
        for (int i = 2; i <= m * n; i++) {
            // 按照原来的方向变化,先向右(再向下,再向左,再向上)
            row += direction[di][0];
            col += direction[di][1];
            // 判断是否需要改变方向
            if (row >= m || col >= n || row < 0 || col < 0
                    || arr[row][col] != 0) {
                // 恢复原位
                row -= direction[di][0];
                col -= direction[di][1];
                di++;
                // 控制螺旋方向
                if (di == 4) {
                    di = 0;
                }
                row += direction[di][0];
                col += direction[di][1];
            }
            arr[row][col] = i;
        }

        // 打印数组内容
        for (int[] a : arr) {
            for (int b : a) {
                System.out.print(b + "\t");
            }
            System.out.println();
        }
    }
}

18. ***八皇后问题在8×8 的国际象棋盘上,放置八个皇后,使任何一个皇后都不能吃掉另一个。国际象棋规则中,皇后可以吃到任何一个与他在同一行、同一列或者同一斜线上的敌方棋子,所以八皇后问题的所有解满足:8 个皇后都不在同一行、同一列,或者同一斜线上。输出所有的解。提示:使用递归。

解题思路一
因为要求出92种不同摆放方法中的任意一种,所以我们不妨把92种不同的摆放方法一次性求出来,存放在一个数组里。为求解这道题我们需要有一个矩阵仿真棋盘,每次试放一个棋子时只能放在尚未被控制的格子上,一旦放置了一个新棋子,就在它所能控制的所有位置上设置标记,如此下去把八个棋子放好。当完成一种摆放时,就要尝试下一种。若要按照字典序将可行的摆放方法记录下来,就要按照一定的顺序进行尝试。也就是将第一个棋子按照从小到大的顺序尝试;对于第一个棋子的每一个位置,将第二个棋子从可行的位置从小到大的顺序尝试;在第一第二个棋子固定的情况下,将第三个棋子从可行的位置从小到大的顺序尝试;依次类推。
首先,我们有一个8*8的矩阵仿真棋盘标识当前已经摆放好的棋子所控制的区域。用一个有92行每行8个元素的二维数组记录可行的摆放方法。用一个递归程序来实现尝试摆放的过程。基本思想是假设我们将第一个棋子摆好,并设置了它所控制的区域,则这个问题变成了一个7皇后问题,用与8皇后同样的方法可以获得问题的解。那我们就把重心放在如何摆放一个皇后棋子上,摆放的基本步骤是:从第1到第8个位置,顺序地尝试将棋子放置在每一个未被控制的位置上,设置该棋子所控制的格子,将问题变为更小规模的问题向下递归,需要注意的是每次尝试一个新的未被控制的位置前,要将上一次尝试的位置所控制的格子复原。
public class WolfQueen {
    /**
     * 一共有多少个皇后(此时设置为8皇后在8X8棋盘,可以修改此值来设置N皇后问题)
     */
    int max = 8;
    /**
     * 该数组保存结果,第一个皇后摆在array[0]列,第二个摆在array[1]列
     */
    int[] array = new int[max];

    public static void main(String[] args) {
        new WolfQueen().check(0);
    }

    /**
     * n代表当前是第几个皇后
     * @param n
     * 皇后n在array[n]列
     */
    private void check(int n) {
        //终止条件是最后一行已经摆完,由于每摆一步都会校验是否有冲突,所以只要最后一行摆完,说明已经得到了一个正确解
        if (n == max) {
            print();
            return;
        }
        //从第一列开始放值,然后判断是否和本行本列本斜线有冲突,如果OK,就进入下一行的逻辑
        for (int i = 0; i < max; i++) {
            array[n] = i;
            if (judge(n)) {
                check(n + 1);
            }
        }
    }

    private boolean judge(int n) {
        for (int i = 0; i < n; i++) {
            if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) {
                return false;
            }
        }
        return true;
    }

    private void print()  {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + 1 + " ");
        }
        System.out.println();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风御浪云帆之上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值