0

0

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

心靈之曲

心靈之曲

发布时间:2025-09-22 10:09:19

|

285人浏览过

|

来源于php中文网

原创

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免费学习笔记(深入)”;

实现步骤:

Akkio
Akkio

Akkio 是一个无代码 AI 的全包平台,任何人都可以在几分钟内构建和部署AI

下载
  1. 创建一个 StringBuilder 用于构建去重后的字符串。
  2. 创建一个 HashSet 用于记录已遇到的字符。
  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 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 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 则优化了字符串构建过程。理解这些核心概念和实现细节,将有助于开发者在面对类似字符串处理任务时,设计出健壮且高性能的解决方案。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

778

2023.08.22

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2023.11.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

319

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

653

2024.03.22

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

0

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 8万人学习

Java 教程
Java 教程

共578课时 | 53.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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