5

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...

4
  • I would simply loop through and use the string indexOf functions with the way you are doing it. If you wanted to use a regex, you could write a regex that you only need to use against the string once. Commented Oct 28, 2011 at 15:04
  • The question asks for number of unique characters, but the code seems to be trying to count duplicates .... am I just reading this wrong?? Commented Oct 28, 2011 at 15:09
  • G_H - Thankfully it's not homework. I'm a beginner developer trying to learn JAVA on my own with some books and forums. Commented Oct 28, 2011 at 15:10
  • Matt - You aren't reading the code wrong. I was trying to use the approach of checking the length of the string and compare it to the number of duplicates and the difference would be number of unique characters. But that seems overly complicated now that it's down. Commented Oct 28, 2011 at 15:12

3 Answers 3

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).

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.

Sign up to request clarification or add additional context in comments.

5 Comments

This is exactly what I was going to suggest.
Could you please provide an example to what you mean. This approach sounds like what I want.
@Rich He is pretty clear.What u did not understand here so u r asking for an example???
@Rich: Probably better (for your understanding) if you have a first stab at writing the code and then post a new question or update this one describing any problems you run into. The trick with the HashMap is that if there is no mapping for a given character you add an entry: <character> -> 1. However, if there already exists a mapping, you add an entry: <character> -> <previous entry value + 1>.
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); } }
3

Algorithm is very simple:

  1. Split string into array of characters
  2. Add all these characters to Set (HashSet).

After that your set contains only unique characters.

4 Comments

Won't help counting occurrences, though. Only detecting if there are any duplicate characters.
Tell me if i wrong, the question was "function that checks a string for duplicate values and returns the count of unique characters"
I'm looking into this suggestion now. G_H - That's exactly what I'm looking to do.
@mishadoff You're right... I was focusing too much on the code. He did indeed ask for the number of unique characters. +1 in that case.
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.

3 Comments

That was very helpful with great explanations. I'm going to give it a shot right now.
Couple of points: You can exit the for loop early if uniqueChars is of size: 3 rather than iterate through the entire String. You could create your HashSet with an initial capacity of 3 in this case.
nice solution. Thx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.