【华为OD机考 统一考试机试】字符串重新排序(C++ Java JavaScript Python )

319 阅读5分钟

华为OD机考:统一考试 C卷 + D卷 + B卷 + A卷

2023年11月份,华为官方已经将 华为OD机考:OD统一考试(A卷 / B卷)切换到 OD统一考试(C卷)和 OD统一考试(D卷) 。根据考友反馈:目前抽到的试卷为B卷或C卷/D卷,其中C卷居多 ,按照之前的经验C卷部分考题会复用A卷,B卷题,博主正积极从考过的同学收集C卷和D卷真题。 可以先继续刷B卷, C卷和D卷的题目会放在现在大家购买的专栏内,不需要重新购买,请大家放心。

专栏:2023华为OD机试( A卷+B卷+C卷+D卷)(C++JavaJSPy)

华为OD面试真题精选:华为OD面试真题精选

在线OJ:点击立即刷题,模拟真实机考环境

华为OD机考B卷C卷华为OD机考华为OD机考B卷华为OD机试B卷华为OD机试C卷华为OD机考C卷华为OD机考D卷题目华为OD机考C卷/D卷答案华为OD机考C卷/D卷解析华为OD机考C卷和D卷真题华为OD机考C卷和D卷题解

题目描述

给定一个字符串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
说明

题目解析

考察的是排序

先进行单词内部调整,然后再进行单词间顺序。

代码思路

这道题需要对输入的字符串进行处理,分为两个步骤:

  1. 对每个单词内部进行字典序排序
  2. 按照单词出现次数、单词长度、字典序升序排列

具体实现思路如下:

  1. 使用分割字符串,得到每个单词
  2. 对每个单词进行字典序排序,并存储到一个 List 中
  3. 统计每个单词出现的次数,并存储到一个 Map 中
  4. 使用 对 List 进行排序,排序规则如下:
    • 次数不同,按照次数降序排列
    • 次数相同,长度不同,按照长度升序排列
    • 次数和长度都相同,按照字典序升序排列
  5. 输出处理后的字符串,每个单词以一个空格分隔

C++

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

using namespace std;

int main() {
    // 读入字符串
    string input;
    getline(cin, input);
    // 使用 istringstream 分割字符串
    istringstream iss(input);
    string token;
    vector<string> words;
    while (getline(iss, token, ' ')) {
        // 对每个单词内部进行字典序排序
        sort(token.begin(), token.end());
        words.push_back(token);
    }

    // 统计每个单词出现的次数
    unordered_map<string, int> count;
    for (string word : words) {
        count[word]++;
    }

    // 按照要求排序
    sort(words.begin(), words.end(), [&](const string& a, const string& b) {
        if (count[a] != count[b]) {
            // 次数不同,按照次数降序排列
            return count[b] < count[a];
        } else if (a.length() != b.length()) {
            // 次数相同,长度不同,按照长度升序排列
            return a.length() < b.length();
        } else {
            // 次数和长度都相同,按照字典序升序排列
            return a < b;
        }
    });

    // 输出处理后的字符串
    ostringstream oss;
    for (string word : words) {
        oss << word << " ";
    }
    cout << oss.str() << endl;

    return 0;
}

JavaScript

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', (input) => {
  rl.close();

  // 使用 split 分割字符串
  const words = input.split(' ').map((word) => {
    // 对每个单词内部进行字典序排序
    return word.split('').sort().join('');
  });

  // 统计每个单词出现的次数
  const count = {};
  words.forEach((word) => {
    count[word] = (count[word] || 0) + 1;
  });

  // 按照要求排序
  words.sort((a, b) => {
    if (count[b] !== count[a]) {
      // 次数不同,按照次数降序排列
      return count[b] - count[a];
    } else if (a.length !== b.length) {
      // 次数相同,长度不同,按照长度升序排列
      return a.length - b.length;
    } else {
      // 次数和长度都相同,按照字典序升序排列
      return a.localeCompare(b);
    }
  });

  // 输出处理后的字符串
  console.log(words.join(' '));
});

Java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        scanner.close();

        // 使用 StringTokenizer 分割字符串
        StringTokenizer st = new StringTokenizer(input, " ");
        List<String> words = new ArrayList<>();
        while (st.hasMoreTokens()) {
            // 对每个单词内部进行字典序排序
            String token = st.nextToken();
            char[] chars = token.toCharArray();
            Arrays.sort(chars);
            words.add(new String(chars));
        }

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

        // 按照要求排序
        Collections.sort(words, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                if (!count.get(a).equals(count.get(b))) {
                    // 次数不同,按照次数降序排列
                    return count.get(b) - count.get(a);
                } else if (a.length() != b.length()) {
                    // 次数相同,长度不同,按照长度升序排列
                    return a.length() - b.length();
                } else {
                    // 次数和长度都相同,按照字典序升序排列
                    return a.compareTo(b);
                }
            }
        });

        // 输出处理后的字符串
        StringBuilder sb = new StringBuilder();
        for (String word : words) {
            sb.append(word).append(" ");
        }
        System.out.println(sb.toString().trim());
    }
}

Python

import collections
import functools

input = input()
words = input.split(" ")

# 对每个单词内部进行字典序排序
words = ["".join(sorted(word)) for word in words]

# 统计每个单词出现的次数
count = collections.Counter(words)

# 按照要求排序
words = sorted(words, key=functools.cmp_to_key(lambda a, b: count[b] - count[a] if count[a] != count[b] else len(a) - len(b) if len(a) != len(b) else -1 if a < b else 1))

# 输出处理后的字符串
output = " ".join(words)
print(output)

@[TOC]

doutub_gif