boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

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


avatar
作者 2025年9月5日 12

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) 都为真时,才标记为中缀。

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

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

百度文心一格

百度推出的AI绘画作图工具

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

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

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() 方法的特性,并结合严谨的逻辑来定义和区分前缀、后缀和中缀。采用模块化的设计和清晰的条件判断,能够编写出健壮且易于理解的字符串处理代码。



评论(已关闭)

评论已关闭