JAVA笔试题刷题打卡Day2

题目来源

牛客网——》华为2016秋招研发笔试题

题目要求

在这里插入图片描述
接替

在这里插入图片描述

解题(第一次)

思路

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

代码

package Practice2;

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
//        创建集合1,2,存储初始数据和处理过的数据
        ArrayList<String> list = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();
//        循环多组输入
        while (sc.hasNext()){
            list.add(sc.nextLine());//用nextLine()保存空格
        }
        sc.close();
//        创建结束,开始处理
        for (int i = 0; i < list.size(); i++) {
            for (int j = list.get(i).length() - 1; j >= 0 ; j--) {
                char c = list.get(i).charAt(j);//定义一个Char,当作字符串的遍历字符
//                这里需要注意的两点,
//                1. \ 反斜杠需要用转义符表示出来,在windows中是 \\
//                2. 如果是字符串,进行比较,就要用到equals 方法,而不能直接用 == ,因为对于引用类型,==比较的是地址。
                if ( c == '\\') {
                    list2.add( list.get(i).substring(j+1) );//这里字符串截取,直接用substring方法
                    break;//一旦检测到,立即退出该字符串的循环。
                }
            }
        }
//        第一轮处理后的字符串已经都在list2中了,进行有序哈希表的建立
        LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
        Integer init = 1;
        for (int i = 0; i < list2.size(); i++) {
//            进行判断,如果已经有了,则在当前数值上+1;否则则给个初值1
            if (map.containsKey( list2.get(i)) ){
                map.put( list2.get(i), map.get( list2.get(i)) + 1 );
            }else{
                map.put( list2.get(i), init );
            }
        }
//        进行有序哈希表 键的遍历,开头到空格有超过16字符的,截取后16个字符,给新的LinkedHashMap
        LinkedHashMap<String, Integer> map1 = new LinkedHashMap<>();
//          这里的遍历最好使用entry对象,效率高,速度快.LinkedHashMap存储和遍历都是有序的,即使使用entrySet里
//        Set<String> keySet = map.entrySet();//使用keySet,将map的key存储到set里进行遍历(LinkedHashMap存储和遍历都是有序的,即使存储到了set集合里)
        Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            int count = 0;
            Map.Entry<String, Integer> entry = it.next();
            for (int i = 0; i < entry.getKey().length(); i++) {
                char c = entry.getKey().charAt(i);
                if (c == ' ') {
                    count = i;
                    break;
                }
            }
            if (count <= 15) {
                map1.put(entry.getKey(), map.get(entry.getKey()));
            } else {
                String strTemp = entry.getKey().substring(count - 16, count);
                map1.put(strTemp, map.get(entry.getKey()));
            }

        }

//        只输出8个,按大小排序,出现顺序已经通过LinkedHashMap实现了
        ArrayList<Map.Entry<String, Integer>> list3 = new ArrayList<>(map1.entrySet());
        Collections.sort(list3, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o2.getValue() - o1.getValue();
            }
        });

//输出,这里的牛客网总是出现只输出一个键值对的问题,也没查到相应的资料解决,有懂的大佬麻烦解答一下,多谢!具体描述见下文

        for (int i = 0; i < ( list3.size() < 8 ? list3.size() : 8 ); i++) {
            System.out.print(list3.get(i).getKey() + " " + list3.get(i).getValue());//这里一旦用到println,就会出现只输出一个元素的现象,为了证明我的格式和答案是一样的,用print先试一下。
            if (i == ( list3.size() < 8 ? list3.size() : 8 )-1 ){
                break;
            }
            System.out.print(" ");
        }

    }
}

注意的地方

  1. 牛客网的题目要求有时会有多组输入,却没有确切的结束标志时,使用while(sc.hasNext()) 循环外加上 sc.close() 方法,编译规则会使输出跳出的,当然,自己的本地IDE是没法自动跳出的,必须给予结束输入的标志。
  2. 关于输入:next() 与nextLine()都能够输入字符串,区别是后者可以输入空格,即不以空格作为一次输入的结束标志,而next()遇到空格,则认为输入结束。
  3. 对于哈希表的遍历,建立Entry对象,通过entrySet()遍历 的速度和效率,大于 直接通过keyset()遍历。
  4. 有序哈希表LInkedHashMap,它的建立、存储、修改键值的过程都是有序的(在通过Entry对象修改键值的基础上)

疑问

  1. 最后输出的时候,一旦使用println,则哈希表的输出只有一个元素,不知道为什么。
  2. 代码中用的print,目的就是证明一下,我的结果应该是对的,只是多行输出总是只显示一行:
  3. 在这里插入图片描述

犯的错

  1. 输入问题
  2. 下标问题

后期改进的想法

  1. 通过一个哈希表直接进行两步处理,提高运行效率和存储。

猜你喜欢

转载自blog.csdn.net/weixin_42252770/article/details/88844526