Fork me on GitHub

判断字符串的字符是否重复

原文:Implement an algorithm to determine if a string has all unique characters. What if you can not use additional data structures?

译文:实现一个算法来判断一个字符串中的字符是否唯一(即没有重复).不能使用额外的数据结构。 (即只使用基本的数据结构)

解答:首先需要确定构成字符串的字符集有多大,是ASCII还是26个英文字母,对于不同的字符集有不同的解法。

  以字符集是ASCII为例,我们可以使用一个256大小的boolean数组,数组初始化为false,遍历一遍字符串中的字符,当bool数组对应位置的值为真, 表明该字符在之前已经出现过,即可得出该字符串中有重复字符。否则将该位置的bool数组 值置为true。

package test;public class Test {
    
    public static void main(String args[]){ 
        System.out.println(isRepeat("abcd"));
    }
    
    public static boolean isRepeat(String s){
        /**
         * 该数组默认是false
         */
        boolean[] bool = new boolean[256];
        /**
         * 遍历一遍字符串字节
         * 当bool数组对应位置的值为真, 表明该字符在之前已经出现过,
         * 即可得出该字符串中有重复字符,
         * 否则将该位置的bool数组值置为true。
         */
        for(byte a:s.getBytes()){
            if(bool[a])
                return true;
            else
                bool[a] = true;
        }
        return false;
    }
}

  这是一种解题思路,还可以通过位向量来减少空间的使用量。对于ASCII字符,我们需要256位,一个int型的数有4个字节,也就是32位,即一个长度为8的int 数组a即可。这里的关键是要把字符对应的数字,映射到正确的位上去。a[0]表示第1~32个数(0~31),a[1]表示第33~64个数(32~63)······

 

package test;

public class Test {
    
    public static void main(String args[]){ 
        System.out.println(isRepeat("abcdsa"));
    }
    
    public static boolean isRepeat(String s){
        /**
         * 该数组默认是false
         */
        int[] ints = new int[8];
        final int CONSTANT = 32;
        
        for(byte a:s.getBytes()){
            //商,判断在哪个数组
            int ids = a / CONSTANT;
            //余数,判断在数组的第几位
            int shift = a % CONSTANT;
            /**
             * 当前位是1,则返回true,说明重复
             * 当前位是0,则置为1。
             */
            if((ints[ids] & 1<< shift) > 0)
                return true;
            else
                ints[ids] =  ints[ids] | 1<< shift;
        }
        return false;
    }
}

 

关于位向量的几篇文章:

如何使用位逻辑运算来实现位向量的理解

Java位向量的实现原理与巧妙应用

 

posted @ 2018-06-12 15:22  爱跑步的星仔  阅读(2932)  评论(0编辑  收藏  举报