Java刷题细节知识点汇总——partThree

1 Java实现顺序数组的打乱

重点:构建指定长度顺序数组的方法构造及打乱数组的思路!

import java.util.Arrays;
import java.util.Random;

public class exercise {
    public static void main(String[] args) {
        int[] a = f();
        System.out.println("原顺序数组:" + Arrays.toString(a));
        shuffle(a);
        System.out.println("打乱后的数组:" + Arrays.toString(a));
    }
    //编写f[]方法构造顺序数组
    public static int[] f() {
        int[] a = new int[7];
        for(int i=0; i<a.length; i++) {
            a[i] = i+1;
        }
        return a;
    }

    public static void shuffle(int[] a) {
        for (int i = 0; i < a.length; i++) {
            //随机下标j,范围:[0, a.length)
            int j = new Random().nextInt(a.length);
            int t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
}

输出结果:
原顺序数组:[1, 2, 3, 4, 5, 6, 7]
打乱后的数组:[1, 7, 2, 3, 6, 5, 4]


2 Java实现模拟双色球生成问题(M个数中抽取N个不同的数)

题:体彩中有一项是双色球,要求在1-33号共33个红色球里选出6个,1-16号共16个蓝色球中选出一个作为中奖号码,请编写程序实现上述要求。

重点: 实现从M个元素的顺序数组中抽取N个不同的数。

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Random;

public class exercise {
    public static void main(String[] args) {
        int[] red = f(33);
        int[] blue = f(6);
        getNumber(6, red);
        getNumber(1, blue);
    }

    public static int[] f(int n) {
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = i + 1;
        }
        return array;
    }

    public static void getNumber(int n, int[] a) {
    //调用Arrays中的方法toString(arrayname)将数组元素以字符串的形式输出
        System.out.println("待抽取的标号数组: " + Arrays.toString(a));
        int[] r = new int[n];
        for (int i = 0; i < n; i++) {
            //j随机定位
            int j = i + new Random().nextInt(a.length - i);
            int x = r[i];
            r[i] = a[j];
            a[j] = x;
        }
        System.out.println("抽取的标号数组: " + Arrays.toString(r) + "\n");
    }
}
输出结果:
待抽取的标号数组: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]
抽取的标号数组: [28, 14, 25, 7, 9, 8]

待抽取的标号数组: [1, 2, 3, 4, 5, 6]
抽取的标号数组: [2]

涉及的算法设计思路(常用于等可能随机抽取数组元素或等可能打乱数组元素位置):
费雪耶兹随机置乱算法详情见此!


3 经典题目之打印三角星

打印指定行数的三角形状星星:

import java.util.Scanner;

public class exercise6 {
    public static void main(String[] args) {
        System.out.println("请输入您想要打印的三角形行数:");
        int n = new Scanner(System.in).nextInt();
        if(n<1)
        {
            System.out.println("Error Input!");
        }
        else {
        //控制行数
            for(int i=0;i<n;i++)
            {
            //控制每行打印空格数
                for(int j=0;j<n-1-i;j++)
                {
                    System.out.print(" ");
                }
                //控制每行打印星数
                for(int k=0;k<2*i+1;k++)
                {
                    System.out.print("*");
                }
                //每行打印完成之后换行,注意换行的格式!!!
                System.out.print("\n");   //也可以直接System.out.print();
            }
        }
    }
}

输出结果为:
      *
     ***
    *****
   *******
  *********
 ***********
*************

4 Java实现输出范围内的所有完数

完数:如果一个数等于其所有因子之和,我们就称这个数为"完数",比如6的因子为1、2、3,而 6 = 1 + 2 + 3,那么6就是一个完数。

例如:编程输出1000以内所有的完数。

public class exercise{
    public static void main(String[] args){
        getNum(1000);     //输入待查找的范围
    }
    public static void getNum(int n){
        int[] a = new int[500];       //创建数组储存所有因数
        for(int i=1;i<=n;i++){
            int k = 0;    //记录因数数目
            int sum = 0;    //储存所有因数之和
            for(int j=1;j<=(i/2)+1;j++){    //遍历求得所有因数
                if(i%j == 0){
                    a[k]=j;
                    k++;
                }
            }
            for(int x=0;x<k;x++){
                sum+=a[x];
            }
            if(sum == i){
                System.out.print(a[0]);
                for(int y=1;y<k;y++){
                    System.out.print( "+" + a[y]);
                }
                System.out.println("=" + i);
            }
        }
    }
}

输出结果:
1=1
1+2+3=6
1+2+4+7+14=28
1+2+4+8+16+31+62+124+248=496


5 Java实现随机数组的归并排序

要求:生成两个随机数组,合并为一个数组并按数字由小到大排序输出。

import java.util.Arrays;
import java.util.Random;

public class exercise {
    public static void main(String[] args){
        int[] a = randomArray();
        int[] b = randomArray();
        Arrays.sort(a);
        Arrays.sort(b);
        System.out.println("排序后随机数组:"+Arrays.toString(a));
        System.out.println("排序后随机数组:"+Arrays.toString(b));
        int[] c = combineArray(a,b);
        System.out.println("合并后数组:"+Arrays.toString(c));
    }
    //随机数组的生成(随机长度、随机元素)
    private static int[] randomArray(){
        int n = new Random().nextInt(20);
        int[] array = new int[n];
        for(int i=0;i<array.length;i++)
        {
            array[i] = new Random().nextInt(1000);
        }
        System.out.println("排序前随机数组:"+Arrays.toString(array));
        return array;
    }
    //两个数组的合并及排序
    private static int[] combineArray(int[] array1,int[] array2){
        int[] array = new int[array1.length+array2.length];
        for(int i=0;i< array1.length+ array2.length;i++){
            if(i< array1.length){
                array[i]=array1[i];
            }
            else{
                array[i]= array2[i- array1.length];
            }
        }
        Arrays.sort(array);
        return array;
    }
}

输出结果:
排序前随机数组:[35, 843, 171, 390, 39, 995]
排序前随机数组:[838, 78, 562, 433, 503, 757, 598, 575, 464, 240, 177, 501, 357, 476]
排序后随机数组:[35, 39, 171, 390, 843, 995]
排序后随机数组:[78, 177, 240, 357, 433, 464, 476, 501, 503, 562, 575, 598, 757, 838]
合并后数组:[35, 39, 78, 171, 177, 240, 357, 390, 433, 464, 476, 501, 503, 562, 575, 598, 757, 838, 843, 995]

拓展(将两数组按数字大小顺序合并到一个数组):
拓展要求意为在合并的过程中同时实现按照元素大小渐次并入新数组,而非对合并后的数组进行排序处理。

参考答案:

import java.util.Arrays;
import java.util.Random;

public class exercise {
    public static void main(String[] args){
        int[] a = randomArray();
        int[] b = randomArray();
        Arrays.sort(a);
        Arrays.sort(b);
        System.out.println("排序后随机数组:"+Arrays.toString(a));
        System.out.println("排序后随机数组:"+Arrays.toString(b));
        int[] c = combineArray(a,b);
        System.out.println("合并后数组:"+Arrays.toString(c));
    }
    //随机数组的生成(随机长度、随机元素)
    private static int[] randomArray(){
        int n = new Random().nextInt(20);
        int[] array = new int[n];
        for(int i=0;i<array.length;i++)
        {
            array[i] = new Random().nextInt(1000);
        }
        System.out.println("排序前随机数组:"+Arrays.toString(array));
        return array;
    }
    //两个数组的合并及排序
    private static int[] combineArray(int[] a,int[] b){
        int[] c = new int[a.length+b.length];
        for(int i=0,j=0,k=0;i<c.length;i++) {
	         if(j>=a.length) {//j越界,b数组数据一个一个放入新数组
	            //c[i] = b[k];
	            //k++;
	            //continue;
	            System.arraycopy(b,k,c,i,b.length-k);
	            break;
	         } else if(k>=b.length) {//k越界,a数组数据一个个放入新数组
	            //c[i] = a[j];
	            //j++;
	            //continue;
	            System.arraycopy(a,j,c,i,a.length-j);
	            break;
	         }
	         //j和k,较小值放入i位置,并递增
	         if(a[j]<=b[k]) {
	            c[i] = a[j];
	            j++;
	         } else {
	            c[i] = b[k];
	            k++;
	         }
	      }    
        return c;
    }
}

思路: 先定义新数组,长度为原来两数组长度和,再通过for循环依次插入元素到新数组:将两数组目前待插入的元素比较,小者插入新数组,大者进行下一轮比较,循环至其中一数组全部插入完成,再将未完结数组剩余元素通过System.arraycopy()全部复制到新数组。
(注:Java中System.arraycopy()方法详情见此链接!

输出结果:
排序前随机数组:[531, 455, 231]
排序前随机数组:[859, 786, 806, 437, 394, 999, 759, 584, 341, 748, 342, 468, 591, 726, 227]
排序后随机数组:[231, 455, 531]
排序后随机数组:[227, 341, 342, 394, 437, 468, 584, 591, 726, 748, 759, 786, 806, 859, 999]
合并后数组:[227, 231, 341, 342, 394, 437, 455, 468, 531, 584, 591, 726, 748, 759, 786, 806, 859, 999]


6 Java实现求解循环报数问题(经典问题)

例题:15个猴子围成一圈选大王,依次1-7循环报数,报到7的猴子被淘汰,直到最后一只猴子称为大王,问:哪只猴子会成为大王?

import java.util.Scanner;

public class  exercise {
    public static void main(String[] args) {
        System.out.println("输入猴子的数目:");
        int n = new Scanner(System.in).nextInt();
        CircularReport(n);
    }
    private static void CircularReport(int n){
        boolean[] b=new boolean[n];
        //2.依次遍历每一只猴子
        //true---未淘汰  false---已淘汰
        for(int i=0;i<b.length;i++){
            b[i]=true;//先把所有猴子设置成存活
        }
        //3.定义变量保存猴子报的数
        int num=0;
        //4.定义变量保存剩余的猴子数
        int monkeyLeft=n;
        //5.定义数组下标
        int index=0;
        //6.循环,直到只剩最后一只猴子(猴子王)
        while(monkeyLeft>1){//判断条件
            //7.检测猴子是否已淘汰
            if(b[index]){
                //8.报数
                num++;
                //9.判断报数是否为7
                if(num==7){
                    b[index]=false;//为7淘汰
                    monkeyLeft--;//猴子数减一
                    num=0;//报数归零
                }
            }
            //10.下标移动
            index++;
            //11.围成一圈---最后一个置为0
            if(index==n){
                index=0;
            }
        }
        //遍历数组,找到最后活着的那个猴子王
        for(int i=0;i<b.length;i++){
            if(b[i]){
                System.out.println("最后留下的是第" + i+1 + "只猴子");
            }
        }
    }
}

输出结果:
输入猴子的数目:15
最后留下的是第 5 只猴子

此类循环报数问题主要思路类似:设计数组对应各个对象,每个对象对应一个boolean值,初始值全设为true,进行循环报数,被淘汰的对象置为false,下标移动,重复循环,直至数组对象数减为一,输出剩余的对象原始位次。

类似题目见此(相同解法)!


7 Java实现一次简单的面向对象编程示例(转载)

需求:设计宠物类,用户可以自由选择养猫还是养狗,可以给宠物起名字,还可以实现喂食互动的功能,宠物需要有饱食度和快乐度。

宠物类(父类):

package exercise;
public class Pet {
	String name;
	int full;
	int happy;
	public Pet(String name) {
		this(name, 50, 50);
	}
	public Pet(String name,int full,int happy) { 
		this.name = name;
		this.full = full;
		this.happy = happy;
	}
	public void feed() {//宠物的喂食方法
		if(full == 100) {
			System.out.println(name+"已经吃饱了");
			return;
		}
		System.out.println("给"+name+"喂食");
		full += 10;
		System.out.println("饱食度:"+full);
	}
	public void play() {//宠物的互动玩耍方法
		if(full == 0) {
			System.out.println(name+"已经饿得玩不动了");
			return;
		}
		System.out.println("陪"+name+"玩耍");
		happy += 10;
		full -= 10;
		System.out.println("快乐度:"+happy);
		System.out.println("饱食度:"+full);
	}
	public void punish() {//宠物的惩罚方法
		//子类不同的代码,改成调方法
		System.out.println(
				"打"+name+"的pp,"+name+"哭叫:"+cry());
		happy -= 10;
		System.out.println("快乐度:"+happy);
	}
	public String cry() {//小动物被打哭了
		//无意义代码
		//cry()方法需要在子类中重写,返回具体哭叫声
		return "此处有哭叫声";
	}
}

小猫类(子类):

package exercise;
public class Cat extends Pet{
	public Cat(String name, int full, int happy) {
		super(name, full, happy);
	}
	public Cat(String name) {
		super(name);
	}
	@Override
	public String cry() {
		return "喵~";
	}
}

小狗类(子类):

package exercise;
public class Dog extends Pet {
	public Dog(String name, int full, int happy) {
		super(name, full, happy);
	}
	public Dog(String name) {
		super(name);
	}
	@Override
	public String cry() {
		return "汪~";
	}
}

结果测试类:

package exercise;

import java.util.Random;
import java.util.Scanner;

public class TestPet {
	public static void main(String[] args) {
		System.out.println("1. 狗");
		System.out.println("2. 猫");
		System.out.print("选择:> ");
		int c = new Scanner(System.in).nextInt();
		System.out.print("给宠物起个名字:");
		String n = new Scanner(System.in).nextLine();
		//定义猫狗变量
		Dog dog = null;
		Cat cat = null;
		if(c == 1) {
			dog = new Dog(n);
			play(dog);
		} else {
			cat = new Cat(n);
			play(cat);
		}
	}
	private static void play(Dog dog) {
		System.out.println("按回车执行");
		while(true) {
			new Scanner(System.in).nextLine();
			int r = new Random().nextInt(6);
			switch(r) {
			case 0: dog.feed(); break;
			case 1: dog.play(); break;
			default: dog.punish(); break;
			}
		}
	}
	private static void play(Cat cat) {
		System.out.println("按回车执行");
		while(true) {
			new Scanner(System.in).nextLine();
			int r = new Random().nextInt(6);
			switch(r) {
			case 0: cat.feed(); break;
			case 1: cat.play(); break;
			default: cat.punish(); break;
			}
		}
	}
}

补充知识点:
(1)instanceof:
instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。
(2)Java中super()的使用详情见此
上述宠物类的实验中,小猫类与小狗类的构造方法中使用super()是为了调用父类Pet中的构造方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值