算法--排序

本文围绕排序算法在实际问题中的应用展开,涵盖基础数组排序、面试分数线划定(需按成绩降序+报名号升序稳定排序)以及关键词频次统计后的多级排序(频次降序+字典序升序)。所有案例均强调排序的稳定性、自定义比较逻辑及边界处理,体现排序在算法设计与系统开发中的核心作用。

一、排序练习

给定一个长度为 n 的整数数组 A(允许元素重复),请将其按非递减顺序排序并输出。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            // 输入
            String num = in.nextLine();// 生成的长度
            String strAA = in.nextLine();// 指定长度的数组

            // 处理
            String[] array = Arrays.stream(strAA.split(" "))
                             .sorted(Comparator.comparing(Integer::valueOf)).toArray(String[]::new);
            System.out.println(String.join(" ", array));
        }
    }
}

运行结果

二、分数线划定

某市为世博会选拔志愿者,先进行笔试,再按笔试成绩划定面试分数线。规则如下:
∙∙ 计划最终录取 m 名志愿者;
∙∙ 面试名额定为 m的 150%,向下取整,记为 t=⌊1.5m⌋;
∙∙ 将所有报名号及笔试成绩按成绩从高到低、成绩相同报名号从小到大排序;
∙∙ 第 t名选手的成绩即为面试分数线;
∙∙ 所有笔试成绩不低于该分数线的选手均进入面试。
请输出面试分数线及所有进入面试选手的信息(按排序后的顺序)。

输入描述:

第一行输入两个整数 n,m(5≦n≦5000; 3≦m≦n),分别表示报名人数与计划录取人数。
接下来 n行,每行输入两个整数 k,s (1000≦k≦9999; 1≦s≦100),分别为报名号与笔试成绩。报名号保证唯一。

输出描述:

第一行输出两个整数:面试分数线 lineline 与进入面试的人数 cnt。
接下来 cnt行,按排序顺序输出每位选手的报名号 k 与成绩 s,每行两个整数,用空格分隔。

import java.util.*;
import java.io.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String[] line1 = bf.readLine().split(" ");
        int n = Integer.parseInt(line1[0]);
        int m = Integer.parseInt(line1[1]);
        ArrayList<Student> list = new ArrayList<>();
        String line;
        while ((line = bf.readLine()) != null) {
            Student s = new Student(Integer.parseInt(line.split(" ")[0]),
                                    Integer.parseInt(line.split(" ")[1]));
            list.add(s);

        }
        list.sort(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int i = o2.score - o1.score;//分数从高到低
                //如分数相同再按id排序(升序)
                //如果i非0,直接用分数差的正负值排序
                i = i == 0 ? o1.id - o2.id : i;
                return i;
            }
        });
        int en_num = (int)Math.floor(m *
                                     1.5); //实际进面人数由分数线决定,同分可进,大于en_num数
        int en_sco = list.get(en_num - 1).score;
        int count = 0;//统计分数
        for (int i = 0; i < n; i++) {
            if (list.get(i).score < en_sco) {
                break;
            }
            count++;
        }

        // System.out.println(m);
        System.out.println(en_sco + " " + count);
        for (int i = 0; i < count; i++) {
            System.out.println(list.get(i));
        }

    }
}
class Student {
    int id;
    int score;
    public Student(int id, int score) {
        this.id = id;
        this.score = score;
    }

    @Override
    public String toString() {
        return id + " " + score;
    }
}

运行结果

三、小红书推荐系统

小红书有一个推荐系统,可以根据用户搜索的关键词推荐用户希望获取的内容。
现在给定小红的搜索记录(记录为分词后的结果),我们认为当一个单词出现的次数不少于3次时,该单词为“用户期望搜索的单词”,即称为关键词。请你根据小红的记录,输出小红的用户画像对应的所有关键词。

输入描述:

一行字符串,仅由小写字母和空格组成。代表小红的搜索记录。
字符串长度不超过100000。

输出描述:

小红所有的关键词。每行输入一个。你需要按照搜索频次从高到低输出。频次相同的,你需要按字典序升序输出。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取整行搜索记录
        String line = scanner.nextLine();
        // 按空格分割成单词数组
        String[] words = line.split(" ");

        // 统计每个单词出现的次数
        Map<String, Integer> countMap = new HashMap<>();
        for (String word : words) {
            countMap.put(word, countMap.getOrDefault(word, 0) + 1);
        }

        // 筛选出出现次数不少于3次的单词(关键词)
        List<Map.Entry<String, Integer>> keywords = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
            if (entry.getValue() >= 3) {
                keywords.add(entry);
            }
        }

        // 自定义排序规则:
        // 1. 按出现次数从高到低排序
        // 2. 次数相同的按字典序升序排序
        Collections.sort(keywords, (a, b) -> {
            if (!a.getValue().equals(b.getValue())) {
                return b.getValue() - a.getValue(); // 次数降序
            } else {
                return a.getKey().compareTo(b.getKey()); // 字典序升序
            }
        });

        // 输出结果
        for (Map.Entry<String, Integer> entry : keywords) {
            System.out.println(entry.getKey());
        }
    }
}

运行结果

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值