DAY-2 | 哈希思想:求字符串包含的字符集合

简介: 这是一个关于代码实现的问题,主要展示了两种利用哈希思想去除字符串中重复字符的方法。第一种方法使用了`boolean[] flg`数组来标记字符是否出现过,遍历字符串时,如果字符未出现则添加到结果并标记为已出现。第二种方法使用`char[] ch`数组直接存储字符出现状态,先遍历一次字符串记录出现过的字符,再遍历一次输出未标记的字符。

一、题干



二、代码实现


以下的两种代码书写方式都是利用了哈希思想,只是实现上略有不同。


代码一


import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        //多组输入
        while (in.hasNextLine()) { 
            String str = in.nextLine();
            //创建标记数组flg
            boolean[] flg = new boolean[129];
            //StringBuilder对象用于存放输出结果
            StringBuilder sb = new StringBuilder();
 
            for(int i = 0; i < str.length(); i++) {
                //将字符串中的字符值作为下标,在flg数组中标记
                char ch = str.charAt(i);
                //flg[ch]等于false,说明该字符是第一次出现,需要存入结果
                if(flg[ch] == false) {
                    sb.append(ch);
                    //存入后,将flg数组对应位置标记为true,代表已经输出过
                    flg[ch] = true;
                }
            }
            //输出结果
            System.out.println(sb.toString());
        }
    }
}


说明:


  1. 创建标记数组:boolean[] flg = new boolean[129];  长度设定为129,是因为后续要以字符串中字母字符的值(也就是字符的ASCII码值)作为数组的下标索引进行标记。最后一个字母字符'z'的码值为122,因此这里创建了一个比122长度略长的数组。没有进行空间优化,因此这么做会造成一定的空间浪费。但宏观来讲,空间复杂度仍是O(1)。
  2. 遍历字符串时:

           1. char ch = str.charAt(i); 获取字符串中i下标处的字母字符值。这个值作为数组的索引。

           2. 检查flg[ch]在数组的值为true还是false。若为false,说明这个字符没有之前出现过,现在是第一次出现,故应当存入结果并输出。若为true,说明这已经是该字符的重复出现,不用输出。

           3. 在sb.append(ch);后,要把标记数组中该字符的位置更改为true,以防之后重复输出。


代码二



import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        while(reader.hasNext()) {
            String str1 = reader.nextLine();
            //创建标记数组
            char[] ch = new char[129];
            //先遍历一遍字符串,将出现过的字符在数组中标记
            for (int i = 0; i < str1.length(); i++) {
                ch[str1.charAt(i)] = 1;
            }
 
            //再遍历一遍数组,将标记过的字符输出
            for (int i = 0; i < str1.length(); i++) {
                if (ch[str1.charAt(i)] == 1) {
                    System.out.print(str1.charAt(i));
                    ch[str1.charAt(i)] = 0;
                }
            }
            System.out.println();
        }
    }
}



相关文章
|
6月前
|
存储
数据结构---串(赋值,求子串,比较,定位)
数据结构---串(赋值,求子串,比较,定位)
60 4
数据结构---串(赋值,求子串,比较,定位)
|
5月前
|
算法 搜索推荐 C++
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
|
5月前
|
C++ 安全
高效遍历:C++中分隔字符串单词的3种方法详解与实例
拷贝并交换(Copy-and-Swap)是C++中实现赋值操作符和异常安全拷贝构造函数的技巧。它涉及创建临时对象,使用拷贝构造函数,然后交换数据以确保安全。C++11之前的策略在此后及C++11引入的移动语义和右值引用下仍有效,但后者提供了更高效的实现方式。
|
6月前
|
索引 容器
06-数据容器str(字符串)-字符串的下标索引/字符串无法修改/查找字符串下标初始值/字符串的替换/字符串的分割/字符串去除前后空格/统计字符串的数量/字符串的循环遍历/对字符串进行分割
06-数据容器str(字符串)-字符串的下标索引/字符串无法修改/查找字符串下标初始值/字符串的替换/字符串的分割/字符串去除前后空格/统计字符串的数量/字符串的循环遍历/对字符串进行分割
|
6月前
|
算法 测试技术 C#
【字典树】 【哈希表】 【字符串】100251. 数组中的最短非公共子字符串
【字典树】 【哈希表】 【字符串】100251. 数组中的最短非公共子字符串
|
6月前
字符串,每个里面包含0-N个数字,如3,8,2,编写函数,将两个这样的字符串合并,并且输出的字符串里面没有重复的数字,并从大到小排列.
字符串,每个里面包含0-N个数字,如3,8,2,编写函数,将两个这样的字符串合并,并且输出的字符串里面没有重复的数字,并从大到小排列.
35 0
|
6月前
|
存储 算法 Java
【数据结构-字符串 四】【字符串识别】字符串转为整数、比较版本号
【数据结构-字符串 四】【字符串识别】字符串转为整数、比较版本号
52 0
|
11月前
字符集合!!!
字符集合!!!
40 0
|
存储 索引
数组与字符串的关系【了解一下】
数组与字符串的关系【了解一下】
123 0
|
C++ 容器
【C++】字符串遍历的三种方式
【C++】字符串遍历的三种方式