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

一、题目描述

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 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<Integer> 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<Integer> 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<Integer> 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<Integer> 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:无序、不重复、无索引。

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

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

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

(3)实现类:TreeSet

①TreeSet集合概述和特点

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

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

在这里插入图片描述
在这里插入图片描述

(4)Set集合的遍历方式

方式一:迭代器
①迭代器遍历概述

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

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

举例如下:

        Collection<String> 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<String> 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<String> 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<String> 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接口。

②格式

在这里插入图片描述
在这里插入图片描述

        Collection<String> 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);
        }

在这里插入图片描述
注意:修改变量的值时,数组的内容不会改变

        //遍历数组
        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));

在这里插入图片描述

③总结

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

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

方式三:lambda表达式
①Lambda表达式遍历集合

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

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

在这里插入图片描述

        Collection<String> 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<String>() {
//            @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<Integer> 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<Integer> 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 + " ");
        });

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

呦呦呦欸哟哟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值