首页 > Java > java教程 > 正文

Java教程:高效处理字符串去重与共享字符计数

心靈之曲
发布: 2025-09-22 10:09:19
原创
274人浏览过

java教程:高效处理字符串去重与共享字符计数

本文详细阐述了如何在Java中对给定字符串和字符串数组进行字符去重处理,并进一步统计数组中每个去重字符串与主去重字符串之间共享的独立字符数量。通过引入高效的辅助函数和数据结构,本教程提供了一种结构清晰、性能优化的解决方案,旨在帮助开发者有效处理此类字符串操作。

1. 问题概述

在许多文本处理场景中,我们可能需要对字符串进行字符去重,并在此基础上进行比较。具体来说,本教程将解决以下问题:给定一个目标字符串 B 和一个字符串数组 A,我们需要完成三个主要任务:

  1. 对目标字符串 B 进行字符去重,得到一个只包含唯一字符的新字符串。
  2. 对字符串数组 A 中的每个元素也进行字符去重,生成一个由去重字符串组成的新数组。
  3. 遍历去重后的数组 A 中的每个字符串,统计其中有多少个独立的字符同时存在于去重后的目标字符串 B 中。最终结果应是一个整数数组,其元素顺序与原始数组 A 保持一致,记录了每个对应位置的共享字符数量。

例如,如果 B = "iyee" 且 A = ["hi", "bye", "bebe"]:

  • 去重 B 得到 "iye"。
  • 去重 A 中的元素得到 ["hi", "bye", "be"]。
  • 对于 "hi",它与 "iye" 共享的独立字符是 'i' (1个)。
  • 对于 "bye",它与 "iye" 共享的独立字符是 'y', 'e' (2个)。
  • 对于 "be",它与 "iye" 共享的独立字符是 'e' (1个)。
  • 最终输出应为 [1, 2, 1]。

2. 核心思路与实现方法

为了高效地解决上述问题,我们可以将整个过程分解为两个主要部分:一个通用的字符串字符去重函数,以及一个利用该函数进行主逻辑处理的函数。

2.1 字符串字符去重函数 dist(String s)

这个辅助函数负责接收一个字符串,并返回其去重后的版本。实现去重最有效的方法之一是利用 HashSet 的特性:HashSet 不允许存储重复元素。我们可以遍历输入字符串的每个字符,尝试将其添加到 HashSet 中。如果 add() 方法返回 true,则表示该字符是首次出现,我们将其添加到 StringBuilder 中以构建去重后的字符串。

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

实现步骤:

怪兽AI数字人
怪兽AI数字人

数字人短视频创作,数字人直播,实时驱动数字人

怪兽AI数字人 44
查看详情 怪兽AI数字人
  1. 创建一个 StringBuilder 用于构建去重后的字符串。
  2. 创建一个 HashSet<Character> 用于记录已遇到的字符。
  3. 遍历输入字符串的每一个字符。
  4. 对于每个字符,尝试将其添加到 HashSet。如果添加成功(即 set.add(char) 返回 true),说明该字符是第一次出现,将其追加到 StringBuilder 中。
  5. 最终返回 StringBuilder 转换成的字符串。

2.2 主处理函数 mathProfessor(String b, String[] a)

主函数将协调调用 dist 函数,并执行最终的字符计数逻辑。

实现步骤:

  1. 首先,对目标字符串 b 调用 dist 函数进行去重,得到 distinctB。
  2. 创建一个 String 数组 distinctA,用于存储数组 a 中每个元素去重后的字符串。
  3. 遍历原始字符串数组 a,对每个元素调用 dist 函数,并将结果存储到 distinctA 中。
  4. 创建一个 int 数组 countArr,用于存储最终的计数结果,其长度与原始数组 a 相同。
  5. 初始化一个计数器 count 为 0。
  6. 遍历 distinctA 数组中的每一个去重字符串 sFromA。
    • 对于每个 sFromA,再次遍历去重后的目标字符串 distinctB 的每一个字符 charFromB。
    • 检查 sFromA 是否包含 charFromB。如果包含,则 count 加 1。
    • 内层循环结束后,将当前的 count 值存储到 countArr 的对应位置。
    • 重置 count 为 0,为下一个 sFromA 的计数做准备。
  7. 返回 countArr。

3. 示例代码实现

以下是基于上述思路的完整Java代码实现:

import java.util.HashSet;
import java.util.Set;
import java.util.Arrays; // 仅用于测试打印结果

public class DistinctCharacterProcessor {

    /**
     * 对给定字符串进行字符去重,返回只包含唯一字符的新字符串。
     * 例如:"iyee" -> "iye"
     *
     * @param s 待去重的字符串
     * @return 去重后的字符串
     */
    public static String dist(String s) {
        StringBuilder sb = new StringBuilder();
        Set<Character> set = new HashSet<>(); // 使用HashSet记录已遇到的字符
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (set.add(c)) { // 如果字符是第一次添加到Set中 (即是唯一的)
                sb.append(c); // 则将其追加到StringBuilder
            }
        }
        return sb.toString();
    }

    /**
     * 处理字符串数组,统计每个去重元素与主去重字符串共享的独立字符数量。
     *
     * @param b 主字符串
     * @param a 字符串数组
     * @return 一个整数数组,包含每个数组元素与主字符串共享的独立字符数量
     */
    public static int[] mathProfessor(String b, String[] a) {
        // 1. 对主字符串进行去重
        String distinctB = dist(b);

        // 2. 存储数组a中每个元素去重后的字符串
        String[] distinctA = new String[a.length];
        for (int i = 0; i < a.length; i++) {
            distinctA[i] = dist(a[i]);
        }

        // 3. 统计共享字符数量
        int[] countArr = new int[a.length];
        int count = 0; // 临时计数器

        for (int i = 0; i < distinctA.length; i++) {
            String sFromA = distinctA[i];
            for (int j = 0; j < distinctB.length(); j++) {
                // 检查 distinctA[i] 中的字符是否包含 distinctB 中的当前字符
                // 注意:这里是检查 distinctA[i] (例如 "hi") 是否包含 distinctB 中的单个字符 (例如 'i')
                if (sFromA.contains(Character.toString(distinctB.charAt(j)))) {
                    count++;
                }
            }
            countArr[i] = count; // 存储当前元素的计数结果
            count = 0; // 重置计数器,为下一个元素做准备
        }

        return countArr;
    }

    public static void main(String[] args) {
        // 示例测试
        String sampleInputB = "iyee";
        String[] sampleInputA = {"hi", "bye", "bebe"};
        int[] result = mathProfessor(sampleInputB, sampleInputA);
        System.out.println("Input B: \"" + sampleInputB + "\"");
        System.out.println("Input A: " + Arrays.toString(sampleInputA));
        System.out.println("Output: " + Arrays.toString(result)); // 预期输出: [1, 2, 1]

        String sampleInputB2 = "apple";
        String[] sampleInputA2 = {"banana", "orange", "grape"};
        int[] result2 = mathProfessor(sampleInputB2, sampleInputA2);
        System.out.println("\nInput B: \"" + sampleInputB2 + "\"");
        System.out.println("Input A: " + Arrays.toString(sampleInputA2));
        System.out.println("Output: " + Arrays.toString(result2)); // 预期输出: [1, 1, 1] (去重apple->aple, banana->ban, orange->orng, grape->grap. ban共享a, orng共享e, grap共享a,p)
    }
}
登录后复制

4. 代码解析与注意事项

4.1 dist 函数详解

  • Set<Character> set = new HashSet<>();: HashSet 提供了近乎常数时间 O(1) 的 add 和 contains 操作(平均情况),这使得字符去重非常高效。当处理大量字符或长字符串时,其性能优势尤为明显。
  • if (set.add(c)): add 方法在元素成功添加到 Set 中时返回 true,如果元素已存在于 Set 中(即重复),则返回 false。我们利用这一特性来判断字符是否是唯一的。
  • StringBuilder: 相较于直接使用 String 进行字符串拼接(+ 操作),StringBuilder 在循环中进行大量字符串修改时效率更高,因为它避免了创建大量的中间 String 对象。

4.2 mathProfessor 函数详解

  • 两次调用 dist: 首先对主字符串 b 调用 dist,然后在一个循环中对数组 a 的每个元素调用 dist。这是确保所有比较都基于去重字符的关键。
  • 嵌套循环进行计数: 外层循环遍历 distinctA 中的每个去重字符串,内层循环遍历 distinctB 中的每个字符。
  • sFromA.contains(Character.toString(distinctB.charAt(j))): 这一行是进行字符匹配的核心。它检查 distinctA 中的当前字符串是否包含 distinctB 中的某个特定字符。需要注意的是,contains 方法的参数是 CharSequence,所以我们需要将 char 类型转换为 String (Character.toString(char))。
  • 计数器重置: count = 0; 在每次处理完 distinctA 中的一个元素后,必须将计数器重置,以确保下一个元素的计数从零开始。

4.3 性能考量

  • dist 函数的时间复杂度大致为 O(N),其中 N 是输入字符串的长度,因为每个字符都被遍历一次并进行 HashSet 操作。
  • mathProfessor 函数中,对 b 和 a 数组中每个字符串调用 dist 的总时间复杂度取决于所有字符串的总长度。
  • 最后的嵌套循环部分,外层循环执行 distinctA.length 次,内层循环执行 distinctB.length() 次。sFromA.contains() 操作在最坏情况下可能需要 O(M) 时间(M 是 sFromA 的长度)。因此,这部分的总时间复杂度大致为 O(distinctA.length * distinctB.length() * avgLengthOfDistinctAString)。
  • 对于常见的字符集和字符串长度,这种方法通常是高效且实用的。

5. 总结

本教程提供了一种清晰且高效的Java解决方案,用于处理字符串去重以及统计共享独立字符的问题。通过将字符串去重逻辑封装在独立的 dist 辅助函数中,我们提高了代码的模块化和复用性。在主函数 mathProfessor 中,我们系统地应用了去重逻辑,并利用嵌套循环完成了字符匹配和计数。HashSet 的使用是提高去重效率的关键,而 StringBuilder 则优化了字符串构建过程。理解这些核心概念和实现细节,将有助于开发者在面对类似字符串处理任务时,设计出健壮且高性能的解决方案。

以上就是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号