1. 引言

在各种文本处理任务中,我们经常需要在一个给定的字符串中找到特定字符的第 n 个最后一个出现位置。这种操作在解析日志、分析文本数据或从字符串中提取相关信息等场景中特别有用。

在这个教程中,我们将探讨使用 Java 寻找字符串中第 n 个最后一个字符的各种方法。

2. 使用传统循环

查找字符串中第 n 个最后一个字符的一种常见方法是通过迭代循环。这种方法是从字符串末尾开始遍历,计数目标字符的出现次数,直到达到所需的位置。

让我们来看看如何实现:

String str = "Welcome to Baeldung";
char target = 'e';
int n = 2;
int expectedIndex = 6;

@Test
public void givenStringAndCharAndN_whenFindingNthLastOccurrence_thenCorrectIndexReturned() {
    int count = 0;
    int index = -1;
    for (int i = str.length() - 1; i >= 0; i--) {
        if (str.charAt(i) == target) {
            count++;
            if (count == n) {
                index = i;
                break;
            }
        }
    }
    assertEquals(expectedIndex, index);
}

在这个测试方法中,我们系统地反向遍历字符串 str 的字符。我们创建变量如 count 来追踪出现次数,index 存储所需出现位置,并仔细管理搜索过程。

每次检查一个字符是否与 target 字符匹配,相应地增加 count,直到达到第 n 个出现位置。

最后,我们验证获取的 index 是否准确对应于 expectedIndex,确保我们的实现正确无误。

3. 使用 Java 流和 IntStream

另一种方法是利用 Java 的 IntStream 类来操作字符串中的字符索引。这是一个示例:

@Test
public void givenStringAndCharAndN_whenFindingNthLastOccurrenceUsingStreams_thenCorrectIndexReturned() {
    OptionalInt result = IntStream.range(0, str.length())
      .map(i -> str.length() - 1 - i)
      .filter(i -> str.charAt(i) == target)
      .skip(n - 1)
      .findFirst();
    int index = result.orElse(-1);
    assertEquals(expectedIndex, index);
}

在这个测试方法中,我们采用函数式编程的方法,利用 IntStream.range() 生成一个表示输入字符串字符的整数索引流。然后,我们映射每个索引到字符串末尾的相应位置,便于反向遍历。

接着,我们应用过滤操作,保留与目标字符匹配的索引。通过调用 skip(n-1) 跳过初始出现,然后使用 findFirst() 查找第 n 个最后一个出现的索引,这些操作封装在 OptionalInt 中。

一旦得到 result,我们从 OptionalInt 中提取索引,并验证它与 expectedIndex 的准确性。

这种函数式编程方法不仅提供了更简洁、更具表达力的解决方案,还符合现代编程范式,强调不可变性和函数组合。

4. 总结

在这篇文章中,我们探讨了使用 Java 在字符串中寻找第 n 个最后一个字符的不同方法,包括传统循环和利用 Java 流程的函数式编程方法。完整的代码示例可在 GitHub 上找到。