检测字符串中的重复字符

时间:2015-07-21 22:02:48

标签: java string arraylist char

我正在Cracking The Coding Interview中进行练习,我正在尝试确定字符串中是否有重复的字符。我正在使用ArrayList数据结构。我的方法是返回类型Boolean,如果有重复则返回true,如果没有重复字符则返回false。我添加了第三个return语句,因此程序将编译,但它总是返回false。

public static class IQueryableExtensions
{
    public static IQueryable<T> ApplySort<T>(this IQueryable<T> source, string sort)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }

        if (sort == null)
        {
            return source;
        }

        // split the sort string
        var lstSort = sort.Split(',');

        // run through the sorting options and create a sort expression string from them

        string completeSortExpression = "";
        foreach (var sortOption in lstSort)
        {
            // if the sort option starts with "-", we order
            // descending, otherwise ascending

            if (sortOption.StartsWith("-"))
            {
                completeSortExpression = completeSortExpression + sortOption.Remove(0, 1) + " descending,";
            }
            else
            {
                completeSortExpression = completeSortExpression + sortOption + ",";
            }

        }

        if (!string.IsNullOrWhiteSpace(completeSortExpression))
        {
            source = source.OrderBy(completeSortExpression.Remove(completeSortExpression.Count() - 1));
        }

        return source;
    }
}

7 个答案:

答案 0 :(得分:4)

您没有将字符串分隔为字符,而是创建包含字符串的单元素列表。如果不对算法进行大的更改,您可以这样做:

public static void main(String[] args) {
    String s = "abcdefga";

    System.out.print(check(s));
}

public static boolean check(CharSequence g) {
    for (int i = 0; i < g.length(); i++) {
        for (int j = i + 1; j < g.length(); j++) {
            if (g.charAt(i) == g.charAt(j)) {
                return true;
            }
        }
    }
    return false;
}

请注意,第一个return false;也不正确,因为它会阻止算法继续进行第一次比较。

另外,当 比较字符串时,您应该使用.equals()代替==

答案 1 :(得分:2)

您的解决方案会比较列表中的字符串引用。列表本身只包含一个字符串。

尝试以下方法:

// check one string for duplicate chars
public static boolean check(String checkString)
{
    // result flag
    boolean foundDuplicate = false;
    // get string length
    int stringLength = checkString.length();
    // create a set for all found characters (max size is number
    // of characters in the string to check
    Set<Character> characters = new HashSet<>(stringLength);
    // loop all characters in string
    for (int i = 0; i < stringLength; i++)
    {
        // construct a object (may be use internal JDK cache)
        Character c = Character.valueOf(checkString.charAt(i));
        // check if character is already found
        if (characters.contains(c))
        {
            // yes, set result to TRUE
            foundDuplicate = true;
            // break the loop
            break;
        }
        else
        {
            // not found, add char to set
            characters.add(c);
        }
    }
    return foundDuplicate;
}

这受字符串长度和堆大小的限制。但我假设所有UTF-8字符都可以放入堆中。

@Maarten Bodewes你是对的。支票可以简化为:

        // add character to set and check result
        if (!characters.add(c))
        {
            // returned false: character already exists
            foundDuplicate = true;
            // break the loop
            break;
        }
        // no else necessary

答案 2 :(得分:1)

以下是我的代码版本的结果。

abcdefga true
abcdefgh false
abcdefdh true
  1. 我修改了check参数以获取单个String。不需要字符串列表。

  2. 在check方法中,您可以在一对字符匹配后退出。您必须先测试整个字符串,然后才能说没有匹配的字符。

  3. 第一个for循环可以在倒数第二个字符处停止。第二个for循环将获得最后一个字符。

  4. 由于我正在比较char值,我使用==。如果我正在比较字符串值,我会使用.equals方法。

  5. 这是代码。

    package com.ggl.testing;
    
    public class QuestionOneCrackingCode {
    
        public static void main(String[] args) {
            String s = "abcdefga";
            System.out.println(s + " " + check(s));
            s = "abcdefgh";
            System.out.println(s + " " + check(s));
            s = "abcdefdh";
            System.out.println(s + " " + check(s));
        }
    
        public static boolean check(String s) {
            for (int i = 0; i < (s.length() - 1); i++) {
                for (int j = i + 1; j < s.length(); j++) {
                    if (s.charAt(i) == s.charAt(j)) {
                        return true;
                    }
                }
            }
            return false;
        }
    }
    

答案 3 :(得分:1)

我的参与:

    public static void main(String[] args) {
        System.out.println(check("abcdefga"));                    // true
        System.out.println(check("noduplicate"));                 // false
        System.out.println(check("withduplicate"));               // true
        System.out.println(check("abcdefghijklmnopqrstuvwxyz"));  // false
        System.out.println(check("abcdefghijklmnopqrstuvwxyzz")); // true
    }

    /**@brief Check if a String contains duplicated characters.
     * Strong expectation for the string: The String must only contains
     * lowercase alpha characters (ie. in [a-z])
     * @returns true if a char is present more than once */
    public static boolean check(String str) {
        int presentChars = 0; // will store the table of already found characters
        int l = str.length();
        for (int i = 0; i < l; ++i) {
            char c = str.charAt(i);
            int offset = c - 'a';             // a=0, b=1, ... z=25
            int mask = 1 << offset;
            if ((presentChars& mask) != 0) {  // Oh! Char already tagged as found
                return true;                  // No need to process further, bye!
            }
            presentChars|= mask;              // Tag the current char as present
        }
        return false;                         // No duplicate
    }

}

我对此代码的目标是最大限度地降低复杂性。在最坏的情况下,该算法在O(N)中。此外,函数的内存占用非常低:即使我使用更多以提高可读性,也只需要int presentChars {= 1}}。

此代码的缺点:输入字符串有一个很大的先决条件。我在评论中对此进行了详细说明,但它仅适用于[a-z]范围内的字符。

我希望它有所帮助!

答案 4 :(得分:0)

  1. 使用String而不是ArrayList。
  2. 如果比较失败,请不要返回,您需要继续搜索而不返回false,这就是为什么它总是返回false。
  3. 即使这样,这也不是最优化的解决方案,尝试考虑桶排序以及它如何适应这个问题。这将使您的解决方案以O(N)而不是O(N ^ 2)运行。
  4. public static boolean check(String g) {
    
        for (int i = 0; i < g.length(); i++) {
            for (int j = i + 1; j < g.length(); j++) {
                if (g.charAt(i) == (g.charAt(j))) {
                    return true;
                }
            }
        }
    
        return false;
    }
    

答案 5 :(得分:0)

在Java 8中,你可以这样做:

public static boolean check(CharSequence checkString)
{
  return checkString.length() != checkString.chars().distinct().count();
}

即。如果字符串中不同字符的数量与字符总数不同,则表示存在重复。它不一定是最有效的方式,但它很简洁。

答案 6 :(得分:0)

我使用一个表格来计算一个字符重复多少次,如果一个字符出现多次,然后返回true,则最坏情况下的代码为O(n)

public static void main(String[] args) {

    String test ="abdefghijklmnoPQRSTUVWXYZa";
    System.out.println(isThereAnyCharacterRepeated(test));
}


public static boolean isThereAnyCharacterRepeated(String str){

    int repeatedCharacters[] = new int[255];
    for(int i=0;i<str.length();i++){
        int index=(int)str.charAt(i);
        repeatedCharacters[index]++;
        if(repeatedCharacters[index]>1)return true;
    }
    return false;
}