问题
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)
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...
回答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
.
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:
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.)
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).
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:
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:
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)
.
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.
回答3:
Algorithm is very simple:
- Split string into array of characters
- Add all these characters to Set (HashSet).
After that your set contains only unique characters.
来源:https://stackoverflow.com/questions/7931012/java-how-to-check-for-duplicate-characters-in-a-string