确定字符串是否具有唯一字符

时间:2015-02-27 22:21:32

标签: java string algorithm char unique

问题要求"实现一种算法来确定字符串是否具有所有唯一字符。

我看到了解决方案,但不太明白。

public boolean isUniqueChars(String str) {
    if (str.length() > 256) return false;
    boolean[] char_set = new boolean[256];
    for (int i = 0; i < str.length(); i++) {
        int val = str.charAt(i);
        if (char_set[val])
            return false;
        char_set[val] = true;
    }
    return true;
}

我们不在代码前面使用parseInt(int)转换器吗? (str.charAt[i]会自动更改为int吗?) boolean[] char set=new boolean[256]是什么意思? 为什么我们需要设置char_set[val]=true

9 个答案:

答案 0 :(得分:3)

在评论中查看我的解释,因为您只标记了algorithm我假设没有语言,只是解决算法本身:

public boolean isUniqueChars(String str){

   //more than 256 chars means at least one is not unique
   //please see first comment by @Domagoj as to why 256 length
    if(str.length()>256) return false;  

        //keeping an array to see which chars have been used
        boolean[] char_set = new boolean[256];

        //iterating over the string
        for(int i=0; i<str,length;i++){

            //not sure what language this is, but let's say it returns an
            //int representation of the char
            int val=str.charAt(i);

            //meaning this has been set to true before, so this char is not unique
            if(char_set[val]) 
                //nope, not unique
                return false;

            //remember this char for next time
            char_set[val]=true;
        } 

    //if we reached here, then string is unique
    return true;
}

答案 1 :(得分:1)

我们还可以使用HashSet数据结构来确定字符串是否包含java中的所有唯一字符。

Set testSet = new HashSet();

for (int i = 0; i < str.length(); i++) {
    testSet.add(new Character(str.charAt(i)));
}

if (testSet.size() == str.length()) {
    System.out.println("All charcaters are Unique");
} else {
    System.out.println("All charcaters are niot unique");
}

答案 2 :(得分:1)

公共类UniqueString {

public static void main(String[] args) {

    String input = "tes";
    Map<String, Integer> map = new HashMap<String, Integer>();

    for (int i = 0; i < input.length(); i++) {

        if (!map.containsKey(Character.toString(input.charAt(i)))) {
            map.put(Character.toString(input.charAt(i)), 1);
        } else {            
            System.out.println("String has duplicate char");
            break;
        }
    }   
}

}

答案 3 :(得分:1)

Java SE 9

您可以简单地将字符串的长度与不同元素的数量相匹配。为了获得所有字符的IntStream,您可以使用String#chars,您可以在其上应用Stream#distinct来获得唯一元素的Stream。确保将字符串转换为单个大小写(大写/小写),否则函数 Stream#distinct 将无法将不同情况下的相同字符(例如 Ii)计为一个.

演示:

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // Test
        Stream.of(
                    "Hello", 
                    "Hi", 
                    "Bye", 
                    "India"
                ).forEach(s -> System.out.println(s + " => " + hasUniqueChars(s)));
    }

    static boolean hasUniqueChars(String str) {
        return str.toLowerCase().chars().distinct().count() == str.length();
    }
}

输出:

Hello => false
Hi => true
Bye => true
India => false

Java SE 8

static boolean hasUniqueChars(String str) {
    return Arrays.stream(str.toLowerCase().split("")).distinct().count() == str.length();
}

答案 4 :(得分:0)

想想如何用纸和笔做这件事。

写出一次字母。

然后逐字逐句地查看字符串。

当你到达一个字符时,将其从字母表中删除。

如果你去掉一个角色并发现它已经被划掉了,那么你就知道角色先前出现在你的字符串中,然后就可以停止了。

这基本上就是您发布的代码所使用的数组。操作在O(N)时间内以O(K)额外空间完成(其中K是您拥有的键数)。

如果您的输入包含大量元素,或者您无法提前知道它们是什么,则可以使用hash table来跟踪已经看到的元素。这再次花费O(N)时间与O(cK)额外空间,其中K是键的数量,c是一些大于1的值。

但哈希表可能占用相当多的空间。还有另一种方法可以做到这一点。对数组进行排序,这将花费O(N log N)时间但需要 no 额外空间。然后遍历数组检查以查看是否有任何两个相邻字符相同。如果是这样,你就有了重复。

答案 5 :(得分:0)

一个简单的解决方案是将String转换为Set并比较相应对象的长度。使用Java 8:

private static boolean checkUniqueChars(String copy) {
    if(copy.length() <= 1) return true;
    Set<Character> set = copy.chars()
       .mapToObj(e->(char)e).collect(Collectors.toSet());
    if (set.size() < copy.length()){
        return false;
    }
    return true;
}

答案 6 :(得分:0)

您可以在我的博客文章中查看详细说明: Check if string has all unique characters

最简单的解决方案是遍历所有字符,使用hashMap并将每个字符放入hashmap表中,然后检查该字符是否已存在。如果角色已经存在,则不是唯一的。

答案 7 :(得分:0)

为了获得最佳性能,您应该使用 Set,并将字符串的字符添加到集合中。如果set.add(...)方法返回false,表示给定的字符之前已经见过,所以返回false,否则返回true所有字符。< /p>

对于简单的解决方案,使用 Set<Character>

public static boolean allUniqueCharacters(String input) {
    Set<Character> unique = new HashSet<>();
    for (int i = 0; i < input.length(); i++)
        if (! unique.add(input.charAt(i)))
            return false;
    return true;
}

然而,这不会处理 BMP 之外的 Unicode 字符,比如表情符号,所以我们可能想要更改设置以使用 Unicode 代码点:

public static boolean allUniqueCodePoints(String input) {
    Set<Integer> unique = new HashSet<>();
    return input.codePoints().noneMatch(cp -> ! unique.add(cp));
}

然而,即使是代码点也不代表我们人类认为的“字符”。为此,我们需要处理 Grapheme Clusters:

public static boolean allUniqueClusters(String input) {
    BreakIterator breakIterator = BreakIterator.getCharacterInstance(Locale.US);
    breakIterator.setText(input);
    Set<String> unique = new HashSet<>();
    for (int start = 0, end; (end = breakIterator.next()) != BreakIterator.DONE; start = end)
        if (! unique.add(input.substring(start, end)))
            return false;
    return true;
}

或者使用 Java 9+:

public static boolean allUniqueClusters(String input) {
    Set<String> unique = new HashSet<>();
    return Pattern.compile("\\X").matcher(input).results()
                  .noneMatch(m -> ! unique.add(m.group()));
}

答案 8 :(得分:-1)

public class CheckStringUniqueChars {

    public static boolean checkUnique(String str) {
        int i=0,j=str.length()-1;
        while(i<j) {
            if(str.charAt(i) == str.charAt(j)) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
}