x after other x string challenge

I am trying below challenge

http://codingbat.com/prob/p186759

I wrote as below thinking this is perfect code

boolean doubleX(String str) {
  for(int i=0;i<str.length()-1;i++){
  
  if(str.substring(i).equals("X") && str.substring(i+1).equals("X")){
  return true;
  }
}
}

Open in new window


But i got below compilation error. I wonder why i got error saying no return eventhough i am returning true.


Compile problems:


Error:      boolean doubleX(String str) {
              ^^^^^^^^^^^^^^^^^^^
This method must return a result of type boolean

Possible problem: the if-statement structure may theoretically
allow a run to reach the end of the method without calling return.
Consider adding a last line in the method return some_value;
so a value is always returned.

see Example Code to help with compile problems



I modified my code as below by giving some explicit return false(I am not sure what to return so arbitrarily gave false) outside for loop

boolean doubleX(String str) {
  for(int i=0;i<str.length()-1;i++){
  
  if(str.substring(i).equals("X") && str.substring(i+1).equals("X")){
  return true;
  }
  
}

return false;
}

Open in new window


I have some test cases passing some failing as below

Expected      Run            
doubleX("axxbb") → true      false      X         
doubleX("axaxax") → false      false      OK         
doubleX("xxxxx") → true      false      X         
doubleX("xaxxx") → false      false      OK         
doubleX("aaaax") → false      false      OK         
doubleX("") → false      false      OK         
doubleX("abc") → false      false      OK         
doubleX("x") → false      false      OK         
doubleX("xx") → true      false      X         
doubleX("xax") → false      false      OK         
doubleX("xaxx") → false      false      OK         


Please advise on how to fix and improve my code
LVL 7
gudii9Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

krakatoaCommented:
Yes, but in the first case, you are trying to return a value from within an if clause - so if the condition doesn't hold, then there will be no return, and that is illegal since you promise to return something in the method signature.

In the second case, if you return an arbitrary false value, what would that achieve, apart from give you the wrong answer now and again?
0
krakatoaCommented:
boolean doubleX(String str) {

  boolean found = false;
  int intpos=0;
  
  if((intpos = str.indexOf("x"))>-1){
        if(intpos<str.length()-1&&str.charAt(intpos+1)=='x')
        {found = true;}
  
  }
  
   return found;
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
krakatoaCommented:
See for the fist time I've taken a look at the solution for this challenge, and I personally would say that their return statement is bad practice, even though it works -

return str.substring(i+1, i+2).equals("x");

The signature of the method is a boolean, and so that other people - and later most likely you too - can understand fully what's going on, return should be expressed simply by a finished boolean :

return found;

Others here may disagree, but if this is meant to be a learning exercise, then I'd say that that sort of esoteric and idiosyncratic phraseology is saved for later down the road.
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

ozoCommented:
You are always returning false, because str.substring(i).equals("X") is never true
0
krakatoaCommented:
In this question, your mistake was to use a loop - you do not need a loop for this. Think about it -

you have been asked to find if the first occurrence of x is followed immediately by another x. So all you have to do is to find x ONCE, and then ask if the next character after it is also an x. You can find it ONCE by str.indexOf("x")>-1.


- - - -
Footnote.
And let us be clear about this : the "-1" which is returned if x is not found, is not an absolute index position in the way that any positive result (ie 0 or more) would be. The -1 in such a case is a quasi-token for "false" (i.e. "not found"), and has to be an int because that is the return type for the method indexOf().
0
dpearsonCommented:
What krakatoa is suggesting is definitely a good approach, but working from where you started from you need to make a couple of changes.

First str.substring(i) is not what you want.  This returns the substring from i to the end of the string.  
You want str.substring(i, i+1) - so it returns just 1 character.

Also you need to leave the loop after finding the first match.

Something like this:

boolean doubleX(String str) {
  for(int i=0;i<str.length()-1;i++){
  
  if(str.substring(i, i+1).equals("x")) {
    if (str.substring(i+1, i+2).equals("x")){
      return true;
    }
    return false ;
  }
  
}

return false;
}

Open in new window


Does that make sense?

Doug
0
gudii9Author Commented:
boolean doubleX(String str) {

  boolean found = false;
  int intpos=0;
 
  if((intpos = str.indexOf("x"))>-1){
        if(intpos<str.length()-1&&str.charAt(intpos+1)=='x')
        {found = true;}
 
  }
 
   return found;
}

The above code worked fine. What is meaning of below line. Does there is scenario where intpos comes greater than str.length()-1.

 please advise
intpos<str.length()-1
0
CEHJCommented:
return should be expressed simply by a finished boolean :

return found;

Yes, i think that's clearer. I like your solution but would have done it slightly differently:

        boolean found = false;
        int intpos = -1;

        if ((intpos = str.indexOf('x')) > -1) {
            found = (intpos < str.length() - 1) && (str.charAt(intpos + 1) == 'x');
        }

        return found;

Open in new window


Another

 
       int ixFirstX = str.indexOf('x');

        return (ixFirstX >= 0) && (str.indexOf('x', ixFirstX + 1) == (ixFirstX + 1));

Open in new window

0
gudii9Author Commented:
In this question, your mistake was to use a loop - you do not need a loop for this.

Is using for loop reduces performance of the java process. Definitely agree the solutions you provided are far better than my original solution.
0
gudii9Author Commented:
int intpos = -1;

what is importance of defining as -1 rather than 0.


(str.charAt(intpos + 1) == 'x')
Instead of above can i say as below. please advise
(str.charAt(intpos + 1) .equals( '"x'");
0
gudii9Author Commented:
Error:      if(pos<str.length()-1&&str.charAt(pos+1).equals("x")){
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Cannot invoke equals(String) on the primitive type char

I got a error when i write like above.

I thought 'x' is also string. Cannot i consider it as string with only one character?
Why java does not like it with equals method for 'x' but rather forcing to use ==

Please advise
0
krakatoaCommented:
Definitely agree the solutions you provided are far better than my original solution.

Not so much a case of being better, but of being correct. Even then, correctness doesn't equate at all times to optimum efficiency.

I'd say now's your chance to study carefully what the big guns CEHJ and Doug have said about this matter, as again, these guys are waaaaay ahead in their knowledge of Java. Ozo too, and of course as I said mccarl.

You should concentrate on the objective before you decide how to begin to code anything. Good luck.
0
ozoCommented:
While there are advantages to some of the other approaches, to use a loop per se was not necessarily a mistake so much as the tests you made in the loop, and it could still be a useful exercise to try to understand why the results you originally generated were incorrect
0
gudii9Author Commented:
boolean doubleX(String str) {
  for(int i=0;i<str.length()-1;i++){
  
  if(str.substring(i,i+1).equals("X") && str.substring(i+1,i+2).equals("X")){
  return true;
  }
  
}

return false;
}

Open in new window



when i wrote as above some test cases failing as below

Expected      Run            
doubleX("axxbb") → true      false      X         
doubleX("axaxax") → false      false      OK         
doubleX("xxxxx") → true      false      X         
doubleX("xaxxx") → false      false      OK         
doubleX("aaaax") → false      false      OK         
doubleX("") → false      false      OK         
doubleX("abc") → false      false      OK         
doubleX("x") → false      false      OK         
doubleX("xx") → true      false      X         
doubleX("xax") → false      false      OK         
doubleX("xaxx") → false      false      OK         



Whereas below Doug code is passing all test cases
boolean doubleX(String str) {
  for(int i=0;i<str.length()-1;i++){
  
  if(str.substring(i, i+1).equals("x")) {
    if (str.substring(i+1, i+2).equals("x")){
      return true;
    }
    return false ;
  }
  
}

return false;
}

Open in new window



I wonderhow my code is different from above code.Please advise
0
dpearsonCommented:
The two programs are very similar.

You do have a small typo - you're testing for capital "X" instead of lower case "x".

But the only real difference is what happens after we find the first x.

In your program the code is essentially this:

if character(i) == 'x' AND character(i+1) == 'x'
   return true;

In my program the code is essentially this:

if character(i) == 'x' then
{
   if character(i+1) == 'x'
       return true ;
   return false ;
}

So can you see how my program will always return a result after it finds the first 'x' in the string?
While yours keeps checking all pairs?

Doug
0
gudii9Author Commented:
if character(i) == 'x' then
{
   if character(i+1) == 'x'
       return true ;
   return false ;
}

you program tries to find x at i+1 position only if it finds 'x' in the i position.

where as my program looking for pairs(xx).

But i feel both at the end find xx only right. I am missing what is the difference between these two approaches. Please advise
0
dpearsonCommented:
you program tries to find x at i+1 position only if it finds 'x' in the i position.
where as my program looking for pairs(xx).

That's correct, but my program always returns a result (true or false) once it finds that first 'x'.

Yours keeps checking for pairs.  So if the string is:

"xabcxx"

mine returns "false" because it finds the first 'x', checks the next letter ('a') and returns false immediately.

Yours finds the first 'x', sees that the next character is 'a' and then keeps on looking for more matches.
Eventually it finds 'xx' at the end of the string and returns "true".

Which in this case it should not (because of the way the problem was set up).

Make sense?

Doug
0
gudii9Author Commented:
It make sense now.

  if (str.substring(i+1, i+2).equals("x")){

Is equals is case sensitive
0
gudii9Author Commented:
My if condition is checking till it find pair of xx and then returning true.
Where as yours goes inside only if it finds x first time and goes inside other if loop and see if is followed by other x then return true.

I read challenge more carefully now which says  first instance of "x" in the string is immediately followed by another "x".


Given a string, return true if the first instance of "x" in the string is immediately followed by another "x".
0
dpearsonCommented:
Yep - I think you've got it now.

And yes "equals" is case sensitive.

There's also "equalsIgnoreCase()" that you can use if you want it to be case insensitive.

Doug
0
awking00Commented:
Why not just -
boolean doubleX(String str) {
 return str.indexOf("x") == str.indexOf("xx");
}
0
awking00Commented:
Oops. Need to take care of no "x" -
boolean doubleX(String str) {
if (str.indexOf("x") > -1 {
 return str.indexOf("x") == str.indexOf("xx");
}
 return false;
}
0
gudii9Author Commented:
after -1 i put ) and worked fine
0
awking00Commented:
Sorry about that. Yes the if condition should be surrounded by parentheses.
0
gudii9Author Commented:
return should be expressed simply by a finished boolean
what is meaning of above line. Is it like instead of returning false return corresponding variable name (which in this case found?)
Please advise
0
awking00Commented:
Instead of if (str.indexOf("x") > -1) { , you could also have used -
if (str.contains("x")) {
0
ozoCommented:
str.indexOf("x") can have an advantage over str.contains("x"), in that you could save the value and not have to compute it again to compare with str.indexOf("xx"),
but compared with some of the other methods, str.indexOf("x") == str.indexOf("xx") has the disadvantage that it can do a lot of extra work for
doubleX("xaaaaaaaaaaaaaaaaaaaxx")
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.