华为OD真题机试---英文输入法(Java)

华为OD机试真题中的“英文输入法”题目主要考察的是字符串处理、单词提取、以及基于前缀的单词联想功能。以下是对该题目的详细解析:

一、题目描述

主管期望你来实现英文输入法单词联想功能。具体需求如下:

  • 依据用户输入的单词前缀,从已输入的英文语句中联想出用户想输入的单词。
  • 按字典序输出联想到的单词序列。
  • 如果联想不到,请输出用户输入的单词前缀。

二、输入描述

输入为两行:

  • 首行输入一段由英文单词和标点符号组成的语句str
  • 接下来一行为一个英文单词前缀pre

三、输出描述

输出符合要求的单词序列或单词前缀。如果存在多个单词,则按字典序排列并以空格分隔;如果联想不到任何单词,则直接输出用户输入的单词前缀。

四、解题思路

  1. 提取单词:首先,需要从输入的英文语句中提取出所有英文单词。这通常可以通过正则表达式来实现,匹配连续的字母序列(考虑大小写)。
  2. 过滤和排序:然后,根据用户输入的单词前缀,过滤出所有以该前缀开头的单词。之后,按照字典序对这些单词进行排序。
  3. 输出结果:最后,输出排序后的单词序列。如果没有找到任何匹配的单词,则输出用户输入的单词前缀。
0 < word.length() <= 20
0 < str.length <= 10000
0 < pre <= 20

输出描述:
字典序输出符合要求的单词序列或单词前缀,存在多个时,单词之间以单个空格分割

输入:

I love you
He	

输出 :

He	

说明:
从用户已输入英文语句”I love you”中提炼出“I”、“love”、“you”三个单词,接下来用户输入“He”,从已输入信息中无法联想到任何符合要求的单词,因此输出用户输入的单词前缀。

输入 :

The furthest distance in the world, 
Is not between life and death, 
But when I stand in front of you, 
Yet you don’t know that I love you.
f	

输出:
front furthest
说明:
从用户已输入英文语句”The furthestdistance in the world, Is not between life and death, But when I stand in frontof you, Yet you dont know that I love you.”中提炼出的单词,符合“f”作为前缀的,有“furthest”和“front”,按字典序排序并在单词间添加空格后输出,结果为“front furthest”。

五、代码实现

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Autocomplete {
    public static void main(String[] args) {
       // String sentence = "The furthest distance in the world, Is not between life and death, But when I stand in front of you, Yet you dont know that I love you.";
        // prefix = "f";
        Scanner scanner = new Scanner(System.in);
        String sentence = scanner.nextLine();
        String prefix = scanner.nextLine();
        System.out.println(autocomplete(sentence, prefix));
    }

    /**
     * 根据给定的句子和前缀,提供一个自动补全的方法
     * 该方法旨在从句子中提取出以给定前缀开头的单词,并按字母顺序排序后返回
     * 如果没有找到以给定前缀开头的单词,则直接返回前缀本身
     *
     * @param sentence 完整的句子,从其中提取单词
     * @param prefix 需要自动补全的前缀
     * @return 自动补全后的单词列表,以空格分隔;如果没有可补全的单词,则返回前缀本身
     */
    public static String autocomplete(String sentence, String prefix) {
        // 提取单词
        List<String> words = extractWords(sentence);
        // 过滤并排序
        List<String> filteredWords = filterAndSort(words, prefix);
        // 输出结果
        if (!filteredWords.isEmpty()) {
            return String.join(" ", filteredWords);
        } else {
            return prefix;
        }
    }


    /**
     * 从句子中提取单词列表
     * 该方法使用正则表达式来识别句子中的单词,并将其存储在列表中
     *
     * @param sentence 待处理的句子
     * @return 包含句子中所有单词的列表
     */
    private static List<String> extractWords(String sentence) {
        // 使用正则表达式提取单词
        Pattern pattern = Pattern.compile("\\b[A-Za-z]+\\b");
        // 创建匹配器
        Matcher matcher = pattern.matcher(sentence);
        List<String> words = new ArrayList<>();
        // 循环匹配
        while (matcher.find()) {
            words.add(matcher.group());
        }
        return words;
    }


    /**
     * 过滤并排序字符串列表
     * 该方法用于接收一个字符串列表和一个前缀字符串,过滤出以该前缀开头的字符串列表,并对其进行排序
     *
     * @param words   字符串列表,用于过滤和排序
     * @param prefix  前缀字符串,用于确定过滤条件
     * @return        返回过滤并排序后的字符串列表
     */
    private static List<String> filterAndSort(List<String> words, String prefix) {
        // 初始化一个新的字符串列表,用于存储过滤后的单词
        List<String> filteredWords = new ArrayList<>();

        // 遍历输入的字符串列表
        for (String word : words) {
            // 检查当前单词是否以指定的前缀开头
            if (word.startsWith(prefix)) {
                // 如果是,将其添加到过滤后的列表中
                filteredWords.add(word);
            }
        }

        // 对过滤后的字符串列表进行排序
        filteredWords.sort(String::compareTo);

        // 返回过滤并排序后的字符串列表
        return filteredWords;
    }

}

六、运行示例解析

在这个Autocomplete类的示例中,我们有一个完整的句子和一个前缀,目标是找出句子中所有以该前缀开头的单词,并将这些单词按字母顺序排序后返回。如果没有找到匹配的单词,则返回前缀本身。

示例代码解析
  1. 初始化句子和前缀

    String sentence = "The furthest distance in the world, Is not between life and death, But when I stand in front of you, Yet you dont know that I love you.";
    String prefix = "f";
    

    句子是一个包含多个单词和标点符号的字符串,前缀是"f"。

  2. 调用autocomplete方法

    System.out.println(autocomplete(sentence, prefix));
    

    这行代码将调用autocomplete方法,并打印其返回值。

  3. 提取单词

    • autocomplete方法中,首先调用extractWords方法来从句子中提取单词。
    • extractWords方法使用正则表达式\\b[A-Za-z]+\\b来匹配句子中的单词(即单词边界之间的字母序列)。
    • 匹配到的单词被添加到words列表中。
  4. 过滤并排序单词

    • 接下来,autocomplete方法调用filterAndSort方法来过滤出以指定前缀开头的单词,并对这些单词进行排序。
    • filterAndSort方法中,遍历words列表,检查每个单词是否以前缀"f"开头。
    • 匹配的单词被添加到filteredWords列表中。
    • 然后,filteredWords列表按字母顺序排序。
  5. 返回结果

    • 如果filteredWords列表不为空,则将其中的单词用空格连接成一个字符串,并返回该字符串。
    • 如果filteredWords列表为空(即没有找到以前缀"f"开头的单词),则返回前缀"f"本身。
结果解析
  • 在给定的句子中,以"f"开头的单词有"furthest"和"front"。
  • 这两个单词被提取、过滤、排序后,返回的结果是"furthest front"。
  • 因此,控制台将打印出:
    furthest front
    

这个示例展示了如何使用正则表达式从句子中提取单词,以及如何根据给定的前缀过滤和排序这些单词。如果在实际应用中,你可能还需要处理更复杂的句子结构(如包含数字、特殊字符或不同语言的单词),那么可能需要调整正则表达式或添加额外的处理逻辑。

七、注意事项

  1. 英文单词联想时,区分大小写:在匹配单词前缀时,需要考虑字母的大小写。
  2. 缩略形式处理:如“don’t”应判定为两个单词“don”和“t”,但在联想时通常只考虑非缩略形式的完整单词。
  3. 输出要求:输出的单词序列不能有重复单词,且只能是英文单词,不能有标点符号。如果存在多个符合要求的单词,它们之间应以单个空格分割。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值