(Java)[NOIP2006 普及组] 明明的随机数

[NOIP2006 普及组] 明明的随机数

    • 一、题目描述
    • 二、输入格式
    • 三、输出格式
    • 四、样例输入
    • 五、样例输出
    • 六、正确代码
      • (1)方法一
      • (2)方法二
      • (3)方法三
    • 七、思路与分析
      • (1)题目分析
      • (2)Set系列集合特点
      • (3)Set集合实现类特点
          • ①HashSet:无序、不重复、无索引。
          • ②LinkedHashSet: **有序**、不重复、无索引。
          • ③TreeSet:**排序**、不重复、无索引
      • (3)实现类:TreeSet
          • ①TreeSet集合概述和特点
          • ②TreeSet集合默认的规则
            • ●对于数值类型:Integer , Double,官方默认按照大小进行升序排序。
            • ●对于字符串类型:默认按照首字符的编号升序排序。
      • (4)Set集合的遍历方式
        • 方式一:迭代器
          • ①迭代器遍历概述
          • ②Collection集合获取迭代器
          • ③Iterator中的常用方法
          • ④总结
        • 方式二:foreach/ 增强for循环
          • ①增强for循环
          • ②格式
          • ③总结
        • 方式三:lambda表达式
          • ①Lambda表达式遍历集合
          • ②Collection结合Lambda遍历的API
      • (5)具体思路

一、题目描述

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N N N 1 1 1 1000 1000 1000 之间的随机整数 ( N ≤ 100 ) (N\leq100) (N100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

二、输入格式

输入有两行,第 1 1 1 行为 1 1 1 个正整数,表示所生成的随机数的个数 N N N

2 2 2 行有 N N N 个用空格隔开的正整数,为所产生的随机数。

三、输出格式

输出也是两行,第 1 1 1 行为 1 1 1 个正整数 M M M,表示不相同的随机数的个数。

2 2 2 行为 M M M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

四、样例输入

10
20 40 32 67 40 20 89 300 400 15

五、样例输出

8
15 20 32 40 67 89 300 400

六、正确代码

(1)方法一

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        Set set = new HashSet<>();
        for (int i = 0; i < n; i++) {
            set.add(a[i]);
        }
        System.out.println(set.size());
        TreeSet T = new TreeSet();
        T.addAll(set);
        Iterator it = T.iterator();
        while (it.hasNext()){
            int result = it.next();
            System.out.print(result + " ");
        }
    }
}

(2)方法二

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        Set set = new TreeSet<>();
        for (int i = 0; i < n; i++) {
            set.add(a[i]);
        }
        System.out.println(set.size());
        for (Integer result:set) {
            System.out.print(result + " ");
        }
    }
}

(3)方法三

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        Set set = new TreeSet<>();
        for (int i = 0; i < n; i++) {
            set.add(a[i]);
        }
        System.out.println(set.size());
        set.forEach(s -> {
            System.out.print(s + " ");
        });
    }
}

七、思路与分析

(1)题目分析

读完题目发现本题的考点就是“去重”与“排序”,说到去重,我们就应该想到Set系列集合啦,而排序我们可以利用TreeSet实现。下面我们来看一下set集合的相关知识

(2)Set系列集合特点

●无序:存取顺序不一致
●不重复:可以去除重复,
●无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素。

(3)Set集合实现类特点

①HashSet:无序、不重复、无索引。

(Java)[NOIP2006 普及组] 明明的随机数_第1张图片
在这里插入图片描述

②LinkedHashSet: 有序、不重复、无索引。

(Java)[NOIP2006 普及组] 明明的随机数_第2张图片
在这里插入图片描述

③TreeSet:排序、不重复、无索引

Set集合的功能上基本上与Collection的API一致。

(3)实现类:TreeSet

①TreeSet集合概述和特点

●不重复、无索引、可排序
●可排序:按照元素的大小默认升序(有小到大)排序。
●TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。
●注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序。

②TreeSet集合默认的规则
●对于数值类型:Integer , Double,官方默认按照大小进行升序排序。
●对于字符串类型:默认按照首字符的编号升序排序。

(Java)[NOIP2006 普及组] 明明的随机数_第3张图片
(Java)[NOIP2006 普及组] 明明的随机数_第4张图片

(4)Set集合的遍历方式

方式一:迭代器

①迭代器遍历概述

●遍历就是一个一个的把容器中的元素访问一遍。
●迭代器在Java中的代表是Iterator, 迭代器是集合的专用遍历方式。

②Collection集合获取迭代器
方法名称 说明
Iterator iterator( ) 返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引
③Iterator中的常用方法
方法名称 说明
boolean hasNext() 询问当前位置是否有元素存在,存在返回true,不存在返回false
E next() 获取当前位置的元素,并同时将迭代器对象移向下一个位置,注意防止取出越界

举例如下:

        Collection lists = new ArrayList<>();
        lists.add("one");
        lists.add("two");
        lists.add("three");
        lists.add("four");
        System.out.println(lists);
        //[one, two, three, four]

        //1.得到当前集合的迭代器对象
        Iterator it = lists.iterator();
        String s = it.next();
        System.out.println(s);//one
        System.out.println(it.next());//two
        System.out.println(it.next());//three
        System.out.println(it.next());//four
        //System.out.println(it.next());//NoSuchElementException 出现无此元素异常的错误
        Collection lists = new ArrayList<>();
        lists.add("one");
        lists.add("two");
        lists.add("three");
        lists.add("four");
        System.out.println(lists);
        //[one, two, three, four]

        //1.得到当前集合的迭代器对象
        Iterator it = lists.iterator();
//        String s = it.next();
//        System.out.println(s);//one
//        System.out.println(it.next());//two
//        System.out.println(it.next());//three
//        System.out.println(it.next());//four
//        //System.out.println(it.next());//NoSuchElementException 出现无此元素异常的错误

        //2.定义while循环
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }

在这里插入图片描述

④总结

1、迭代器的默认位置在哪里。
●Iterator iterator():得到迭代器对象,默认指向当前集合的索引0

2、迭代器如果取元素越界会出现什么问题。
●会出现NoSuchElementException异常。

方式二:foreach/ 增强for循环

①增强for循环

●增强for循环:既可以遍历集合也可以遍历数组。
●它是JDK5之后出现的,其内部原理是一个Iterator迭代器,遍历集合相当于是迭代器的简化写法。
●实现Iterable接 口的类才可以使用迭代器和增强for, Collection接口已经实现了Iterable接口。

②格式

(Java)[NOIP2006 普及组] 明明的随机数_第5张图片
(Java)[NOIP2006 普及组] 明明的随机数_第6张图片

        Collection lists = new ArrayList<>();
        lists.add("one");
        lists.add("two");
        lists.add("three");
        lists.add("four");
        System.out.println(lists);
        //[one, two, three, four]

        //遍历集合
        for (String s : lists) {
            System.out.println(s);
        }

        System.out.println("-----------------------");
        //遍历数组
        double[] scores = {59.5,60,99,88};
        for (double score : scores) {
            System.out.println(score);
        }

(Java)[NOIP2006 普及组] 明明的随机数_第7张图片
注意:修改变量的值时,数组的内容不会改变

        //遍历数组
        double[] scores = {59.5,60,99,88};
        System.out.println(Arrays.toString(scores));
        for (double score : scores) {
            System.out.println(score);
            if (score == 60){
                score = 66;//修改无意义,不会影响数组的元素值
            }
        }
        System.out.println(Arrays.toString(scores));

(Java)[NOIP2006 普及组] 明明的随机数_第8张图片

③总结

1、 增强for可以遍历哪些容器?
●既可以遍历集合也可以遍历数组。

2、增强for的关键是记住它的遍历格式

方式三:lambda表达式

①Lambda表达式遍历集合

●得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式。

②Collection结合Lambda遍历的API
方法名称 说明
default void forEach(Consumer action): 结合lambda遍历集合

(Java)[NOIP2006 普及组] 明明的随机数_第9张图片

        Collection lists = new ArrayList<>();
        lists.add("one");
        lists.add("two");
        lists.add("three");
        lists.add("four");
        System.out.println(lists);
        //[one, two, three, four]

//        lists.forEach(new Consumer() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }

        //化简
//        lists.forEach(s ->  {
//                System.out.println(s);
//        });

        //再化简
//        lists.forEach(s -> System.out.println(s));

        //继续化简
        lists.forEach(System.out::println);

(5)具体思路

首先先将随机数的个数以及所有的随机数读入并存储

随机数可利用for循环存储到一个数组中

Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }

然后就到了利用TreeSet集合去重和排序的时候啦~
我们将利用TreeSet*排序**、不重复、无索引的特点,实现去重和排序的作用

创建一个TreeSet集合,然后调用Set集合的add方法将数组中的数字添加到集合中,添加完成后,TreeSet集合本身就完成了去重和排序的操作,超级省心!

Set set = new TreeSet<>();
        for (int i = 0; i < n; i++) {
            set.add(a[i]);
        }

调用Set集合的方法获取集合中的元素个数并打印出来

System.out.println(set.size());

最后就只剩下将TreeSet集合中的元素输出啦,但由于Set集合没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素。可以遍历Set集合的方法如下:

方法一:利用迭代器遍历

Iterator it = set.iterator();
        while (it.hasNext()){
            int result = it.next();
            System.out.print(result + " ");
        }

方法二:foreach/ 增强for循环

for (Integer result:set) {
            System.out.print(result + " ");
        }

方法三:lambda表达式

set.forEach(s -> {
            System.out.print(s + " ");
        });

结束了!恭喜你掌握了该题~

你可能感兴趣的:(洛谷刷题(JAVA),java,算法,开发语言)