首页 > Java > java教程 > 正文

Java子字符串位置判断:前缀、后缀与中缀的精确识别

聖光之護
发布: 2025-09-05 13:44:01
原创
432人浏览过

Java子字符串位置判断:前缀、后缀与中缀的精确识别

本教程详细探讨了在Java中如何准确判断一个子字符串在目标字符串中的位置,即识别其是否为前缀、后缀或中缀。文章分析了常见编程误区,并提供了一套严谨的逻辑与示例代码,确保能够清晰、无歧义地对子字符串进行分类,避免因条件重叠导致的错误判断。

1. 问题背景与常见误区

在处理字符串时,我们经常需要判断一个给定的子字符串(substr)在另一个目标字符串(str)中的具体位置。常见的三种情况是:

  • 前缀 (Prefix):subStr 位于 str 的开头。
  • 后缀 (Suffix):subStr 位于 str 的末尾。
  • 中缀 (Infix):subStr 位于 str 内部,但既不是前缀也不是后缀。

许多初学者在尝试同时判断这三种情况时,容易遇到逻辑上的混淆。一个典型的错误在于对 String.contains() 方法的滥用。例如,以下代码片段展示了这种常见误区:

public static void substringProblem() throws FileNotFoundException {
    String response;
    String answer;
    Scanner input = new Scanner(System.in);
    System.out.println("Enter a substring: ");
    response = input.next();
    Scanner inDictionary = new Scanner(DICTIONARY);    
    for (int line = 1; line <= 23; line++) {
        answer = inDictionary.nextLine(); // 原始字符串
        if (answer.startsWith(response)) {
            answer = answer + " - prefix"; // 第一次修改
        }
        if (answer.contains(response)) { // 问题所在:如果response是前缀,此条件依然为真
            answer = answer + " - infix"; // 导致错误地标记为中缀
        }
        if (answer.endsWith(response)) { // 同理,如果response是后缀,此条件依然为真
            answer = answer + " - suffix";
        }
        else if (!answer.contains(response)) {
            answer = answer + " - not found";
        }
        System.out.println(answer); 
    }
}
登录后复制

上述代码存在两个主要问题:

  1. contains() 方法的判断过于宽泛: str.contains(subStr) 只要 subStr 存在于 str 中的任何位置,都会返回 true。这意味着如果 subStr 是 str 的前缀或后缀,contains() 也会为真,从而可能导致其被错误地标记为“中缀”。例如,当 response 是 "t" 且 answer 是 "tattarrattat" 时,startsWith("t") 为真,contains("t") 也为真,最终结果会同时显示“prefix”和“infix”,这与我们对“中缀”的严格定义(既非前缀也非后缀)相悖。
  2. 变量 answer 的重复修改: 在循环内部,answer 变量首先存储了字典中的原始单词,然后根据判断结果不断地将标签(如 "- prefix")追加到 answer 变量本身。这不仅使得代码难以阅读和维护,也可能导致后续的判断基于已被修改的字符串进行,从而引入更多错误。

2. 正确的子字符串位置分类逻辑

为了准确地判断子字符串的位置,我们需要一个更严谨的逻辑,特别是对“中缀”的定义进行明确:一个子字符串只有在目标字符串中存在,且既不是目标字符串的前缀也不是其后缀时,才被认定为中缀。

基于此定义,正确的判断逻辑如下:

立即学习Java免费学习笔记(深入)”;

  1. 首先,检查子字符串是否包含在目标字符串中。 如果不包含,则直接标记为“未找到”。
  2. 如果包含,则进一步判断其具体位置:
    • 前缀: 使用 str.startsWith(subStr)。
    • 后缀: 使用 str.endsWith(subStr)。
    • 中缀: 只有当 str.contains(subStr) 为真,且 !str.startsWith(subStr) 和 !str.endsWith(subStr) 都为真时,才标记为中缀。

这种分层和组合条件的判断方式,确保了每种分类的唯一性和准确性。

EasySub – AI字幕生成翻译工具
EasySub – AI字幕生成翻译工具

EasySub 是一款在线 AI 字幕生成器。 它提供AI语音识别、AI字幕生成、AI字幕翻译,本来就很简单的视频剪辑。

EasySub – AI字幕生成翻译工具 40
查看详情 EasySub – AI字幕生成翻译工具

3. 示例代码实现

以下是一个优化后的Java代码示例,它将核心判断逻辑封装在一个独立的方法中,提高了代码的可读性和复用性:

import java.util.Scanner;

public class SubstringClassifier {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in); // 从控制台获取输入

        System.out.print("请输入一个目标字符串: ");
        String targetString = scanner.nextLine();

        System.out.print("请输入一个要查找的子字符串: ");
        String subString = scanner.nextLine();

        // 调用分类方法并打印结果
        System.out.println(targetString + " " + findSubstringPosition(targetString, subString));

        // 示例:可以模拟从字典文件读取并处理
        // 假设我们有一个简单的字符串数组作为“字典”
        String[] dictionary = {"preload", "helpful", "banana", "nana", "tattarrattat", "absobloominglutely", "apple"};
        System.out.println("\n--- 字典处理示例 ---");
        for (String word : dictionary) {
            System.out.println(word + " " + findSubstringPosition(word, subString));
        }

        scanner.close();
    }

    /**
     * 判断子字符串在目标字符串中的位置(前缀、后缀或中缀)。
     *
     * @param str 目标字符串
     * @param subStr 要查找的子字符串
     * @return 描述子字符串位置的字符串(例如 "-prefix", "-suffix", "-infix", "not found")
     */
    public static String findSubstringPosition(String str, String subStr) {
        StringBuilder result = new StringBuilder(); // 使用StringBuilder高效构建结果字符串

        if (str.contains(subStr)) { // 首先检查是否包含子字符串
            boolean isPrefix = str.startsWith(subStr);
            boolean isSuffix = str.endsWith(subStr);

            if (isPrefix) {
                result.append(" -prefix");
            }
            if (isSuffix) {
                result.append(" -suffix");
            }
            // 只有当既不是前缀也不是后缀时,才标记为中缀
            if (!isPrefix && !isSuffix) {
                result.append(" -infix");
            }

            // 如果一个字符串同时是前缀和后缀,但不是中缀(根据此严格定义),
            // 并且没有其他标签被添加,则将其视作仅为前缀/后缀的组合。
            // 例如 "na" in "nana" 会得到 "-prefix -suffix"
            // 如果 str 和 subStr 完全相同,例如 "hello" in "hello",则得到 "-prefix -suffix"
            // 注意:此处对 "infix" 的判断是互斥的,即如果已经是前缀或后缀,则不再认为是中缀。
            // 如果希望一个字符串即使是前缀或后缀,但其内部也包含子字符串时仍被标记为“infix”,
            // 则需要调整逻辑,但通常这种严格定义更为清晰。

        } else {
            result.append(" -not found"); // 如果不包含
        }

        // 如果结果为空,说明包含子字符串,但没有被任何特定标签匹配(例如子字符串为空)。
        // 针对实际应用,通常subStr不会为空,或者会在输入时进行校验。
        if (result.length() == 0 && str.contains(subStr)) {
             return " -found (unclassified)"; // 这种情况很少见,除非subStr为空字符串
        }

        return result.toString().trim(); // 返回结果,并去除可能的前导空格
    }
}
登录后复制

代码解析:

  • main 方法: 负责用户输入、调用核心逻辑方法并输出结果。它还包含一个模拟字典处理的示例,展示如何在循环中应用 findSubstringPosition 方法。
  • findSubstringPosition 方法:
    • 接收 targetString 和 subString 作为参数。
    • 使用 StringBuilder 来高效地构建结果字符串,避免了 String 频繁拼接产生的额外对象。
    • 首先通过 str.contains(subStr) 进行初步检查。
    • 如果包含,则分别通过 startsWith() 和 endsWith() 判断是否为前缀或后缀。
    • 关键点: if (!isPrefix && !isSuffix) 这一条件确保了只有当 subStr 既不是前缀也不是后缀时,才将其标记为中缀。这严格遵循了中缀的定义,避免了与前缀/后缀的混淆。
    • 如果 subStr 未在 str 中找到,则返回 "-not found"。
    • trim() 方法用于去除结果字符串开头可能存在的空格。

示例输出(以 subString = "na" 为例):

请输入一个目标字符串: banana
请输入一个要查找的子字符串: na
banana  -infix

--- 字典处理示例 ---
preload  -not found
helpful  -not found
banana  -infix
nana  -prefix -suffix
tattarrattat  -infix
absobloominglutely  -infix
apple  -not found
登录后复制

4. 关键点与注意事项

  • 明确定义: 在编程之前,务必明确“前缀”、“后缀”和“中缀”的精确定义,特别是中缀是否可以与前缀/后缀重叠。本教程采用了严格互斥的定义(中缀不包括前缀和后缀)。
  • 条件顺序与组合: 正确的条件判断顺序和逻辑组合是避免错误的关键。先判断 contains(),再判断 startsWith() 和 endsWith(),最后结合这些结果来判断 infix。
  • 避免副作用: 在处理过程中,尽量避免修改原始的输入字符串。将分类逻辑封装在纯函数(不修改外部状态)中是一个好习惯。
  • 使用 StringBuilder: 当需要频繁拼接字符串时,使用 StringBuilder 而不是 + 运算符,可以显著提高性能,尤其是在循环中。
  • 输入验证: 在实际应用中,应考虑对用户输入进行验证,例如检查子字符串是否为空或长度是否为零,以避免潜在的运行时错误。

总结

通过本教程,我们学习了如何在Java中准确地判断子字符串在目标字符串中的位置。核心在于理解 contains()、startsWith() 和 endsWith() 方法的特性,并结合严谨的逻辑来定义和区分前缀、后缀和中缀。采用模块化的设计和清晰的条件判断,能够编写出健壮且易于理解的字符串处理代码。

以上就是Java子字符串位置判断:前缀、后缀与中缀的精确识别的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号