Java - 如何检查字符串中的重复字符?

时间:2022-09-04 07:00:31

I need to write a function that checks a string for duplicate values and returns the count of unique characters. If the count is greater than 3, it should return true. If the count is less than 3, it should be false. Here is what I have been trying (notice I'm new to java)

我需要编写一个函数来检查字符串是否有重复值,并返回唯一字符的数量。如果计数大于3,则应返回true。如果计数小于3,则应该为假。这是我一直在尝试的(注意我是java的新手)

private boolean isFormatValid(String password) {
    CharSequence inputStr = password;
    int length = inputStr.length();
    int numberDups = 0;

    for(int i=0; i < length; ++i) {
        Pattern pattern = Pattern.compile("(.)(?=.*?\1){1,20}");
        Matcher matcher = pattern.matcher(inputStr);
        numberDups += 1;
    }
    if (numberDups < 3) {
        return false;
    }
    return true;
}

I was trying to use a regex because it was suggested it might be easier. But if I can accomplish this without a regex I'd be happier.

我试图使用正则表达式,因为它被认为可能更容易。但如果我能在没有正则表达式的情况下实现这一点,我会更快乐。

Is this what is meant?

这是什么意思?

private boolean isFormatValid(String password) {
    int length = inputStr.length();
    int numberChars = 0;

    for(int i=0; i < length; ++i) {
                int index = password.indexOf(i);
        CharArray[i] = charAt(i);   
    }
}

I feel this isn't even close to being right...

我觉得这甚至不是正确的......

3 个解决方案

#1


1  

I think the variable numberDups in your sample code is misnamed, and that's confusing some people. That variable is supposed to represent the number of different characters, is it not? That is, if the string is abcabc the number would be 3, and for the string aaaaaaaaa it would be 1.

我认为示例代码中的变量numberDups名称错误,这让一些人感到困惑。该变量应该代表不同字符的数量,不是吗?也就是说,如果字符串是abcabc,则数字将是3,而对于字符串aaaaaaaa,它将是1。

That being the case, the simplest solution is, as others have said, to use a Set. In fact your code is almost there; just get rid of that numberDups counter and replace it with a HashSet<Character>, like so:

在这种情况下,最简单的解决方案就像其他人所说的那样,使用Set。实际上你的代码几乎就在那里;只是摆脱那个numberDups计数器并用HashSet 替换它,如下所示:

static boolean isFormatValid(String password) {
    CharSequence inputStr = password;
    int length = inputStr.length();
    Set<Character> uniqueChars = new HashSet<Character>();

    for(int i=0; i < length; ++i) {
        uniqueChars.add(inputStr.charAt(i));
    }

    return uniqueChars.size() >= 3;
}

(However, you don't need to create the inputStr variable. You can call CharSequence methods like charAt() and length() on the password variable because String implements the CharSequence interface.)

(但是,您不需要创建inputStr变量。您可以在密码变量上调用charSequence方法,如charAt()和length(),因为String实现了CharSequence接口。)


EDIT: I also want to point out that, the way you were using the Pattern and Matcher, you weren't using them. You correctly created the Matcher from the Pattern, and associated it with the input string, but then it just sat there. In order to apply the regex, you have to call one of the methods, find() or matches() (or lookingAt(), but nobody ever uses that one).

编辑:我也想指出,你使用模式和匹配器的方式,你没有使用它们。你正确地从Pattern创建了Matcher,并将它与输入字符串相关联,但它只是坐在那里。为了应用正则表达式,你必须调用其中一个方法find()或matches()(或lookingAt(),但没有人使用过那个方法)。

That's is a very common beginner's mistake. Java has a reputation for being excessively verbose anyway, but it's especially noticeable (and surprising) in this case. I mean, what are regexes for, if not to let you solve problems without writing reams of code? But it's not always that bad; here's a one-line solution using a regex:

这是一个非常普遍的初学者的错误。 Java无论如何都有过于冗长的声誉,但在这种情况下它尤其引人注目(并且令人惊讶)。我的意思是,什么是正则表达式,如果不是让你在不编写大量代码的情况下解决问题?但它并不总是那么糟糕;这是使用正则表达式的单行解决方案:

return inputStr.replaceAll("(.)(?=.*\\1)", "").length() >= 3;

That is, remove all the duplicates, and the length of the resulting string is the same as the number of unique characters. The set-based solution is still simpler, though; this one is just shorter.

也就是说,删除所有重复项,结果字符串的长度与唯一字符的数量相同。但是,基于集合的解决方案仍然更简单;这个只是更短。

#2


6  

You're pretty much there. Rather than use a regular expression, you can use the index: i to index into the String and read a particular character using charAt(int).

你几乎就在那里。您可以使用索引:i索引到String并使用charAt(int)读取特定字符,而不是使用正则表达式。

You then need a data structure to keep track of the number of occurences of each character. I suggest using a HashMap for this whereby the map key is the Character you've read and the map value is the Integer count of the number of occurences.

然后,您需要一个数据结构来跟踪每个角色的出现次数。我建议使用HashMap,其中map键是你读过的Character,map值是出现次数的Integer计数。

#3


3  

Algorithm is very simple:

算法很简单:

  1. Split string into array of characters
  2. 将字符串拆分为字符数组

  3. Add all these characters to Set (HashSet).
  4. 将所有这些字符添加到Set(HashSet)。

After that your set contains only unique characters.

之后,您的集合仅包含唯一字符。

#1


1  

I think the variable numberDups in your sample code is misnamed, and that's confusing some people. That variable is supposed to represent the number of different characters, is it not? That is, if the string is abcabc the number would be 3, and for the string aaaaaaaaa it would be 1.

我认为示例代码中的变量numberDups名称错误,这让一些人感到困惑。该变量应该代表不同字符的数量,不是吗?也就是说,如果字符串是abcabc,则数字将是3,而对于字符串aaaaaaaa,它将是1。

That being the case, the simplest solution is, as others have said, to use a Set. In fact your code is almost there; just get rid of that numberDups counter and replace it with a HashSet<Character>, like so:

在这种情况下,最简单的解决方案就像其他人所说的那样,使用Set。实际上你的代码几乎就在那里;只是摆脱那个numberDups计数器并用HashSet 替换它,如下所示:

static boolean isFormatValid(String password) {
    CharSequence inputStr = password;
    int length = inputStr.length();
    Set<Character> uniqueChars = new HashSet<Character>();

    for(int i=0; i < length; ++i) {
        uniqueChars.add(inputStr.charAt(i));
    }

    return uniqueChars.size() >= 3;
}

(However, you don't need to create the inputStr variable. You can call CharSequence methods like charAt() and length() on the password variable because String implements the CharSequence interface.)

(但是,您不需要创建inputStr变量。您可以在密码变量上调用charSequence方法,如charAt()和length(),因为String实现了CharSequence接口。)


EDIT: I also want to point out that, the way you were using the Pattern and Matcher, you weren't using them. You correctly created the Matcher from the Pattern, and associated it with the input string, but then it just sat there. In order to apply the regex, you have to call one of the methods, find() or matches() (or lookingAt(), but nobody ever uses that one).

编辑:我也想指出,你使用模式和匹配器的方式,你没有使用它们。你正确地从Pattern创建了Matcher,并将它与输入字符串相关联,但它只是坐在那里。为了应用正则表达式,你必须调用其中一个方法find()或matches()(或lookingAt(),但没有人使用过那个方法)。

That's is a very common beginner's mistake. Java has a reputation for being excessively verbose anyway, but it's especially noticeable (and surprising) in this case. I mean, what are regexes for, if not to let you solve problems without writing reams of code? But it's not always that bad; here's a one-line solution using a regex:

这是一个非常普遍的初学者的错误。 Java无论如何都有过于冗长的声誉,但在这种情况下它尤其引人注目(并且令人惊讶)。我的意思是,什么是正则表达式,如果不是让你在不编写大量代码的情况下解决问题?但它并不总是那么糟糕;这是使用正则表达式的单行解决方案:

return inputStr.replaceAll("(.)(?=.*\\1)", "").length() >= 3;

That is, remove all the duplicates, and the length of the resulting string is the same as the number of unique characters. The set-based solution is still simpler, though; this one is just shorter.

也就是说,删除所有重复项,结果字符串的长度与唯一字符的数量相同。但是,基于集合的解决方案仍然更简单;这个只是更短。

#2


6  

You're pretty much there. Rather than use a regular expression, you can use the index: i to index into the String and read a particular character using charAt(int).

你几乎就在那里。您可以使用索引:i索引到String并使用charAt(int)读取特定字符,而不是使用正则表达式。

You then need a data structure to keep track of the number of occurences of each character. I suggest using a HashMap for this whereby the map key is the Character you've read and the map value is the Integer count of the number of occurences.

然后,您需要一个数据结构来跟踪每个角色的出现次数。我建议使用HashMap,其中map键是你读过的Character,map值是出现次数的Integer计数。

#3


3  

Algorithm is very simple:

算法很简单:

  1. Split string into array of characters
  2. 将字符串拆分为字符数组

  3. Add all these characters to Set (HashSet).
  4. 将所有这些字符添加到Set(HashSet)。

After that your set contains only unique characters.

之后,您的集合仅包含唯一字符。