首页 > 编程语言 >【华为OD-E卷-字符串重新排序 字符串重新排列 100分(python、java、c++、js、c)】

【华为OD-E卷-字符串重新排序 字符串重新排列 100分(python、java、c++、js、c)】

时间:2024-12-17 15:55:52浏览次数:5  
标签:java 重新排列 相同 单词 频率 字符串 长度 排序 字典

【华为OD-E卷-字符串重新排序 字符串重新排列 100分(python、java、c++、js、c)】

题目

给定一个字符串s,s包括以空格分隔的若干个单词,请对s进行如下处理后输出:
1、单词内部调整:对每个单词字母重新按字典序排序
2、单词间顺序调整:
1)统计每个单词出现的次数,并按次数降序排列
2)次数相同,按单词长度升序排列
3)次数和单词长度均相同,按字典升序排列
请输出处理后的字符串,每个单词以一个空格分隔。

输入描述

  • 一行字符串,每个字符取值范围:[a-zA-z0-9]以及空格,字符串长度范围:[1,1000]

输出描述

  • 输出处理后的字符串,每个单词以一个空格分隔

用例

用例一:
输入:
This is an apple
输出:
an is This aelpp
用例二:
输入:
My sister is in the house not in the yard
输出:
in in eht eht My is not adry ehosu eirsst

python解法

  • 解题思路:
  • 本题要求对一组单词进行排序。排序的规则是:

按照每个单词的出现频率从高到低排序。
如果多个单词出现的频率相同,则按单词长度从短到长排序。
如果频率和长度都相同,则按字典序(即字母顺序)排序。
解题步骤
标准化单词:
先将每个单词的字母排序,以消除字母顺序对结果的影响。例如,“abc” 和 “cab” 都变成 “abc”。
统计单词频率:
使用 defaultdict(int) 来记录每个标准化单词的出现次数。
排序规则:
对列表进行排序时,使用自定义的排序规则:
主要按频率从高到低排序。
次要按长度从短到长排序。
最后按字典序排序。
返回结果:
最终,返回排序后的单词列表,用空格连接起来。

from collections import defaultdict

# 定义排序函数
def sort_words(lst):
    # 对每个单词按字母排序(标准化处理)
    lst = ["".join(sorted(w)) for w in lst]
    
    # 使用defaultdict记录每个标准化后的单词出现的次数
    cnt = defaultdict(int)
    
    # 手动计数每个单词的出现次数
    for w in lst:
        cnt[w] += 1

    # 按照自定义的排序规则排序单词
    # 1. 按照出现频率从高到低(-cnt[x])
    # 2. 按照单词的长度从短到长(len(x))
    # 3. 按照字典序从小到大(x)
    lst.sort(key=lambda x: (-cnt[x], len(x), x))

    # 返回排序后的单词列表,单词之间用空格连接
    return " ".join(lst)

# 读取输入的单词列表
words = input().split()
# 调用排序函数并输出结果
print(sort_words(words))

java解法

  • 解题思路
  • 本题的目的是对给定的一组单词进行排序,排序规则如下:

按照单词出现的频率从高到低进行排序。
如果多个单词的频率相同,则按单词的长度从短到长排序。
如果频率和长度都相同,则按字典序(即字母顺序)排序。
具体步骤:
标准化单词:首先对每个单词中的字母进行排序。这样,不同字母顺序的单词将会被视为相同。例如,“abc”、“bca”、“cab” 都会被转换为 “abc”。

统计单词频率:使用 TreeMap 来记录每个标准化后的单词的出现次数。TreeMap 会根据字母顺序对单词进行自动排序,但在本题中并不依赖于它的自然顺序,主要用于统计。

自定义排序规则:根据以下优先级对单词进行排序:

频率:出现次数较多的单词排在前面。
长度:出现次数相同的情况下,按单词的长度从短到长排序。
字典序:如果频率和长度都相同,按字典顺序排序。
生成排序结果:最后根据排序后的顺序构建输出字符串。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        System.out.println(processWords(input));  // 调用处理单词的方法并输出结果
    }

    // 处理单词的函数
    public static String processWords(String s) {
        // 按空格分割输入字符串,得到所有单词
        String[] words = s.split(" ");
        
        // 使用 TreeMap 来统计每个标准化单词出现的次数
        // TreeMap 会按照字典序存储键(标准化后的单词)
        Map<String, Integer> countMap = new TreeMap<>();

        // 遍历每个单词,进行字母排序后存储到 TreeMap 中
        for (String word : words) {
            // 将单词转换为字符数组,并排序
            char[] chars = word.toCharArray();
            Arrays.sort(chars);  // 排序字母
            String sortedWord = new String(chars);  // 转换回字符串
            
            // 使用 getOrDefault 方法统计该标准化单词的出现次数
            countMap.put(sortedWord, countMap.getOrDefault(sortedWord, 0) + 1);
        }

        // 将 countMap 的条目转为列表,方便自定义排序
        List<Map.Entry<String, Integer>> entryList = new ArrayList<>(countMap.entrySet());
        
        // 自定义排序规则:
        // 1. 按照频率降序排序
        // 2. 如果频率相同,按单词长度升序排序
        // 3. 如果频率和长度都相同,按字典序排序
        entryList.sort((a, b) -> {
            if (!b.getValue().equals(a.getValue())) {
                return b.getValue() - a.getValue();  // 按频率降序
            } else {
                // 如果频率相同,按长度升序
                return a.getKey().length() - b.getKey().length() != 0 ? a.getKey().length() - b.getKey().length() : a.getKey().compareTo(b.getKey());
            }
        });

        // 使用 StringBuilder 拼接结果
        StringBuilder result = new StringBuilder();
        for (Map.Entry<String, Integer> entry : entryList) {
            // 按照频率输出每个单词,输出时每个单词后加空格
            for (int i = 0; i < entry.getValue(); i++) {
                result.append(entry.getKey()).append(" ");
            }
        }
        
        // 去掉最后一个空格并返回结果
        return result.toString().trim();
    }
}

C++解法

  • 解题思路
  • 本题要求对输入的一组单词进行排序,排序规则如下:

频率排序:按照单词的出现频率,从高到低排序。
长度排序:如果两个单词的频率相同,按单词的长度,从短到长排序。
字典序排序:如果频率和长度都相同,则按字典序排序。
具体步骤:
标准化单词:每个单词需要进行字母排序。这样不同字母顺序的单词被视为相同,例如,“abc”和“cab”都应该视为“abc”。

统计单词的频率:使用 unordered_map 统计标准化后的单词出现的次数。

排序:对单词列表按照以下规则进行排序:

首先按出现频率降序排序。
如果频率相同,按单词的长度升序排序。
如果频率和长度都相同,按字典序排序。
输出排序后的结果:最终输出排序后的单词列表,用空格分隔

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <sstream>

using namespace std;

// 用于排序每个单词中的字母
void reorder(string &t) {
    sort(t.begin(), t.end());  // 对字符串中的字母进行排序
}

int main() {
    string line;
    getline(cin, line);  // 读取整行输入

    stringstream strStream(line);  // 将输入的字符串转换为 stringstream 流,方便逐个单词读取
    string token;
    vector<string> list;  // 用于存储处理后的单词列表
    unordered_map<string, int> frequency;  // 用于存储每个标准化单词的出现频率

    // 逐个单词读取,并进行字母排序,统计频率
    while (strStream >> token) {
        reorder(token);  // 对单词中的字母进行排序
        list.push_back(token);  // 将排序后的单词加入列表
        frequency[token]++;  // 统计该单词的出现次数
    }

    // 对单词列表进行排序,排序规则:
    // 1. 按照单词频率降序排序
    // 2. 如果频率相同,按单词长度升序排序
    // 3. 如果频率和长度都相同,按字典序排序
    stable_sort(list.begin(), list.end(), [&](const string &s1, const string &s2) {
        if (frequency[s1] != frequency[s2]) {
            return frequency[s1] > frequency[s2];  // 频率较高的排在前面
        } else if (s1.size() != s2.size()) {
            return s1.size() < s2.size();  // 长度较短的排在前面
        } else {
            return s1 < s2;  // 如果频率和长度都相同,则按字典序排序
        }
    });

    // 输出排序后的单词列表,单词之间用空格分隔
    for (size_t i = 0; i < list.size(); ++i) {
        cout << list[i];
        if (i < list.size() - 1) {
            cout << " ";  // 如果不是最后一个单词,添加空格
        }
    }

    return 0;
}

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

  • 本题的目标是对输入的一组单词进行处理并排序。排序规则如下:

频率排序:单词的排序首先依赖于它们的出现频率,从高到低排序。
长度排序:如果两个单词的频率相同,按单词的长度从短到长排序。
字典序排序:如果频率和长度都相同,按字典序排序。
详细步骤:
标准化单词:将每个单词中的字母按字典顺序排序。这样不同字母顺序的单词将被视为相同(例如,“abc”和“cab”会都被标准化为“abc”)。

统计单词的频率:使用 Map 来统计每个标准化单词的出现次数。

排序:对单词列表进行排序,排序规则是:

按出现频率降序排序。
如果频率相同,则按单词的长度升序排序。
如果频率和长度都相同,则按字典序排序。
输出结果:输出排序后的单词列表,用空格分隔。

// 用于将单词中的字符按字典顺序排序
function reorder(t) {
    return t.split('').sort().join(''); // 将单词转换为字符数组,排序后再连接成字符串
}

// 主处理函数
function processWords(input) {
    // 将输入字符串按空格分割成单词
    const words = input.split(' ');

    // 使用 Map 存储每个标准化单词的出现次数
    const countMap = new Map();

    // 遍历每个单词
    for (let word of words) {
        const sortedWord = reorder(word); // 将单词中的字母排序
        // 更新 Map 中的频率计数
        countMap.set(sortedWord, (countMap.get(sortedWord) || 0) + 1);
    }

    // 将 Map 转换为数组,以便进行排序
    const entryList = Array.from(countMap.entries());
    // 对 entries 进行排序
    entryList.sort((a, b) => {
        // 如果频率不同,按频率降序排序
        if (b[1] !== a[1]) {
            return b[1] - a[1];
        } 
        // 如果频率相同,按单词的长度升序排序
        else if (a[0].length !== b[0].length) {
            return a[0].length - b[0].length;
        } 
        // 如果频率和长度都相同,按字典序排序
        else {
            return a[0].localeCompare(b[0]);
        }
    });

    // 按照排序结果构建最终输出
    const result = [];
    for (let [key, value] of entryList) {
        for (let i = 0; i < value; i++) {
            result.push(key); // 每个标准化单词按照出现次数加入结果
        }
    }

    return result.join(' '); // 用空格连接并返回最终结果
}

// 主函数:读取输入并输出结果
function main() {
    // 从标准输入中读取数据并处理
    const line = require('fs').readFileSync('/dev/stdin', 'utf-8').trim();
    console.log(processWords(line)); // 调用处理函数并输出结果
}

// 调用主函数
main();

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

标签:java,重新排列,相同,单词,频率,字符串,长度,排序,字典
From: https://blog.csdn.net/CodeClimb/article/details/144513751

相关文章

  • Windows和Linux系统中安装JDK(Java Development Kit)
    一、在Windows系统中安装JDK下载JDK访问Oracle官方网站(https://www.oracle.com/java/technologies/javase-downloads.html)。根据你的操作系统(32位或64位)和需求,选择合适的JDK版本进行下载。例如,对于大多数普通开发,选择JavaSE(StandardEdition)的JDK安装包。运行安装程序......
  • JDK的常用java命令有哪些?
    java命令功能:用于运行已编译的Java程序(.class文件)。它通过加载Java虚拟机(JVM),然后执行字节码。示例:假设你有一个名为HelloWorld.class的文件,在命令行中进入该文件所在目录,然后输入javaHelloWorld(这里HelloWorld是主类名),就可以运行这个Java程序。如果程序有命令行参数,还可以在......
  • java poi 限定单元格只能输入数字
    importorg.apache.poi.ss.usermodel.*;importorg.apache.poi.ss.util.*;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;publicclassEasyPoiNumberValidation{publicstaticvoidmain(String[]args){Workbookworkbook=newXSSFWorkbook();......
  • 被裁后半月面试8家公司无果,凭借这份Java面试指南成功入职阿里
     前言上个月班上的好好的突然被通知"毕业了",现在工作也确实不好找。之前近一个月面了很多大大小小的公司降薪太严重都没考虑去,最后没办法本来都打算随便去一家了却偶然得到一个阿里的面试机会,足足面了七面(我太难了)因为我的工程项目经验基本为0所以被死磕Java,下面我简单说下......
  • 程序员面试必备的Java八股文,适合所有的Java求职者!
     说明本文分享Java后端真实高频面试题,有详细答案,保你稳过面试。题目包括:Java基础、多线程、JVM、数据库、Redis、Shiro、Spring、SpringBoot、MyBatis、MQ、ELK、SpringCloud、设计模式等。包含从简单到困难、从高频到低频的题目,适合所有Java求职者,包括:应届生、转行的、三......
  • Java Web项目部署教程简单实用
    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站学习总结1、掌握JAVA入门到进阶知识(持续写作中……)2、学会Oracle数据库入门到入土用法(创作中……)3、手把手教你开发炫酷的vbs脚本制作(完善中……)4、牛逼哄哄的IDEA......
  • Java核心技术卷1 第三章选读 其二
    前言本文内容选自Java核心技术卷1第10版,感兴趣的小伙伴可以自行阅读原书,以下内容为本人学习后摘取的片段与大家分享。正文3.7.2格式化输出可以使用SyStem.0Ut.print(x)将数值x输出到控制台上。这条命令将以x对应的数据类型所允许的最大非0数字位数打印输出X。例......
  • 【Java】LDAP AD域登录认证
    项目遇到需要进行AD域认证的情况,先是使用了LdapTemplate,结果认证不了,换了下面的方式认证成功了认证的时候,需要注意账号后面加上AD域服务器后缀!加上后缀!加上后缀! publicbooleanldapAuth(Stringusername,Stringpassword){booleanisLogin=false;//log.i......
  • Springboot 单元测试报错:javax.websocket.server.ServerContainer not available
    错误描述 解决方案@SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)  importlombok.extern.slf4j.Slf4j;importorg.junit.Test;importorg.junit.runner.RunWith;importorg.springframework.beans.factory.annotation.Autowired;im......
  • SSM高校社团学生会管理系统--47676(免费领源码)可做计算机毕业设计JAVA、PHP、爬虫、APP
    摘  要本论文基于SSM框架,设计和实现了一个高校社团学生会管理系统。该系统旨在提供一个全面、高效、智能的高校社团学生会管理平台,以便管理者可以迅速且便捷地进行各项管理工作,并及时向社团成员提供准确的社团信息。  该系统通过角色划分为社团成员、社团社长和管理员......