Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
Solved

# string contains xx

Posted on 2014-10-15
Medium Priority
196 Views
Hi,
I am trying below challenge
http://codingbat.com/prob/p194667
I wrote as below

``````int countXX(String str) {
int count=0;
for(int i=0;i<str.length();i++){
str.contains("xx");
count=count+1;
}
return count;
}
``````
It is failing below scenarios
Expected      Run
countXX("abcxx") → 1      5      X
countXX("xxx") → 2      3      X
countXX("xxxx") → 3      4      X
countXX("abc") → 0      3      X
countXX("Hello there") → 0      11      X
countXX("Hexxo thxxe") → 2      11      X
countXX("") → 0      0      OK
countXX("Kittens") → 0      7      X
countXX("Kittensxxx") → 2      10      X

0
Question by:gudii9
• 17
• 12
• 4
• +3

LVL 20

Expert Comment

ID: 40382807
``````int countXX(String str) {
int count = 0;
for (int i = 0; i < str.length()-1; i++) {
if (str.substring(i, i+2).equals("xx")) count++;
}
return count;
}
``````
0

LVL 14

Expert Comment

ID: 40382826
Russ,

I'm pretty sure gudii9 could click the "Show Solution" button, too, if he wanted to.
0

LVL 17

Expert Comment

ID: 40382882
Here's one take :

``````int countXX(String str) {

int count=0;

for (int i=0;i<str.length()-1;i++){

if (str.charAt(i)== 'x' && str.charAt(i+1)== 'x'){count++;}
}

return count;
}
``````
0

LVL 36

Expert Comment

ID: 40383652
Here's my minimal solution...
``````int countXX(String str) {
int count = 0;
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);
return count;
}
``````
0

LVL 7

Author Comment

ID: 40384230
from = str.indexOf("xx", from) + 1
what is meaning of above line. Please advise. Why we initialized 'from' and checking id string index of xx +1 greater than zero erc.
0

LVL 17

Expert Comment

ID: 40384525
'from' is the index position from where the indexOf function starts to look for the "xx" substring. 'from' steps to where it finds each incidence of the "xx" substring during the loop, and because it only stops when it finds two "xx"s together, it does not move through the redundant characters, and therefore when two lots of "xx" are in different parts of the search string, 'from' jumps to their index, making it more efficient than a fully exhaustive string iteration. If indexOf() finds no more "xx"s, (or never finds any to begin with), then count doesn't get incremented, and the method returns the number that it did find during the loop.

mccarl's method is somewhat more 'professional-level', and more powerful because it eschews irrelevant parts of the search string, and syntactically slightly more difficult construction than the standard loop concepts you see more generally, such as the one I posted, or, indeed, the suggested one in codingbat.

You can see how mccarl has thought through the requirements of the process to the ultimate level here.
0

LVL 7

Author Comment

ID: 40385761
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);

why we need +1 in above statement.
0

LVL 7

Author Comment

ID: 40385767
``````int countXX(String str) {
int count=0;
for(int i=0;i<str.length()-1;i++){
str.substring(i,i+2).equals("xx");
count=count+1;
}
return count;
}
``````

Why some test cases are failing and some passing when i write as above
Expected      Run
countXX("abcxx") → 1      4      X
countXX("xxx") → 2      2      OK
countXX("xxxx") → 3      3      OK
countXX("abc") → 0      2      X
countXX("Hello there") → 0      10      X
countXX("Hexxo thxxe") → 2      10      X
countXX("") → 0      0      OK
countXX("Kittens") → 0      6      X
countXX("Kittensxxx") → 2      9      X

for(int i=0;i<str.length()-1;i++){

0

LVL 36

Expert Comment

ID: 40385983
why we need +1 in above statement.
The  + 1  makes the code start looking from the NEXT character once it has found "xx" somewhere. If it didn't have the  + 1  it would keep find the same "xx" over and over again and it would be in an infinite loop.

Why some test cases are failing and some passing when i write as above
Some are passing out of sheer coincidence. Your code simply calculates the length of the string - 1. Look at the test cases... the first example has 5 characters and your code returns 4, the second example has 3 characters and your code returns 2.

The count=count + 1 line gets executed every time around the loop; it's not dependant on anything. And your that calls the ".equals()" method does nothing with the return value (it may as well not be there at all).

You need an if statement in there to check the result of .equals and so that count is NOT just updated every time through the loop.

what is the importance of '-1' in above statement.
The  - 1  is there because you don't need to check the LAST character of the string. Since it is only ONE character, it can NEVER be equal to "xx" as that is TWO characters.
0

LVL 17

Expert Comment

ID: 40386189

. . . and, it has been a frequent area of doubt in your questions about the indexing situation. You will have to make a DETERMINED effort to *remember* that arrays (such as a String is (because it is just an array of chars actually)) ALWAYS start at 0. Therefore to make any for loops and other loops start at the beginning - which is character (or element) ZERO, it follows that the last character (or element) index number - POSITION - is going to be the length of that variable *MINUS 1*

This idea is never going to go away in Java, and I would say that unless and until you absorb this fact fully, you are going to waste a whole lot of your time.

------------

String s = "ABCD";
s.length() is 4.

**BUT** in a loop like this :
for(int position=0;position<s.length();position++){//blah blah}

THE LOOP WILL ONLY KEEP RUNNING while 'position' is less than 4. That means the last iteration will set 'position' to 3, and index 3 is the LAST character in string s. Like this :

A = s.charAt(0)  B = s.charAt(1)  C= s.charAt(2) and D = s.charAt(3)

You can see that the letters ABCD are each taken care of by the index positions 0-3.
0

LVL 7

Author Comment

ID: 40386780
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);

The  + 1  makes the code start looking from the NEXT character once it has found "xx" somewhere. If it didn't have the  + 1  it would keep find the same "xx" over and over again and it would be in an infinite loop.

How it increments 'from' (middle part). I see count only has increment(last part) not like from++. Please advise
0

LVL 17

Expert Comment

ID: 40387156
'from' is assigned to 0 the first time, OK?

THEN on each subsequent iteration of the for loop, IF the search found "xx", then 'from' would be incremented to that index position  :

(from = str.indexOf("xx", from) + 1)

PLUS 1.

so in plain English, the above line says : from = the-position-at-which-you-found-"xx"-but-you-MUST-start-looking-from-position-'from' (which to begin with was 0).

AT THAT POINT, dear JVM, because you found "xx", at a CERTAIN position, please now add "1" to the position at which you found "xx", and put it into (overwrite the value in) the variable 'from', so that when the loop returns for another iteration, it can't find the one it just found again, because it MUST start looking from the new 'from' position, which is one more than where it found the last "xx".
0

LVL 14

Assisted Solution

CPColin earned 500 total points
ID: 40387182
While that loop is certainly clever, it's obviously clever to the point of being confusing. You could just use a while loop and have it be much more clear what's going on:

``````int from = str.indexOf("xx") + 1;

while (from > 0)
{
from = str.indexOf("xx", from) + 1;
count++;
}
``````
0

LVL 17

Expert Comment

ID: 40387185
and with that you'd have to do "return count+1" if I am not mistaken?
0

LVL 7

Author Comment

ID: 40387192
``````int countXX(String str) {
int from = str.indexOf("xx") + 1;

while (from > 0)
{
from = str.indexOf("xx", from) + 1;
count++;
}
return count+1;
}
``````

i wrote as above getting error

Compile problems:

Error:      count++;
^^^^^
count cannot be resolved

0

LVL 7

Author Comment

ID: 40387205
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);
Below statement I thought will check the 'xx' is present at position of 'from' or not present
str.indexOf("xx", from)

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int,%20int)

indexOf
public int indexOf(int ch,
int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.

but based on below explanation i am not clear if it increments to index posistion?

IF the search found "xx", then 'from' would be incremented to that index position  :
0

LVL 17

Expert Comment

ID: 40387214
Error:      count++;
^^^^^
count cannot be resolved

CPColin was partially abstracting - obviously you need to declare the variable before you can use it, which you haven't done.
0

LVL 17

Expert Comment

ID: 40387318
Below statement I thought will check the 'xx' is present at position of 'from' or not present

str.indexOf("xx", from)

It does check that it is present - starting at position 'from'.
0

LVL 17

Expert Comment

ID: 40387365
Please put these two amended lines of mccarl's code into the appropriate place in your code :

``````countXX("xxabcdxxxxxx");
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++){System.out.println(from);}
``````

To save you doing that if you are busy, I can tell you that it will print out :

1
7
8
9
10
11

which are the positions **+1** in which it finds "xx", and which are the values held by 'from'.

Now you are going to ask why the numbers above don't start at 0 and end at 10. The reason for that is that when str.indexOf("xx",from) first executes, 'from' IS zero. But it is immediately incremented by 1, so that by the time the printout is done for that loop iteration, 'from' holds the value 1, not zero.

OK?

But of course the point of this is that you can see that the characters at positions 2,3,4,5 and 6 (or strictly speaking, positions 1,2,3,4 and 5 according to array indexation protocol), ARE SKIPPED OVER in the search *. How is that? Well as has been said, because 'from' is incremented by 1, the loop CAN NEVER FIND AGAIN the previous pair of "xx"s that it just found, because the start position has moved on. QED. And O&O.

(* = this is true as far as we are concerned here in Java; but 'under the hood', the native code will be iterating the entire String, and only returning a found value to the 'from' variable, for our higher-level Java purposes).
0

LVL 7

Author Comment

ID: 40387746
``````package eePackage;

public class Test15 {

public static void main(String[] args) {
// TODO Auto-generated method stub
int howMany= countXX("axxbcxxeexddxr");
System.out.println("number is--->"+howMany);

}

static int countXX(String str) {
int from = str.indexOf("xx") + 1;
int count=0;
while (from > 0)
{
from = str.indexOf("xx", from) + 1;
count++;
}
return count;
}

}
``````

I got correct output as
number is--->2

all test cases are passing as well
Expected      Run
countXX("abcxx") → 1      1      OK
countXX("xxx") → 2      2      OK
countXX("xxxx") → 3      3      OK
countXX("abc") → 0      0      OK
countXX("Hello there") → 0      0      OK
countXX("Hexxo thxxe") → 2      2      OK
countXX("") → 0      0      OK
countXX("Kittens") → 0      0      OK
countXX("Kittensxxx") → 2      2      OK

and with that you'd have to do "return count+1" if I am not mistaken?

If i return again count+1 i am getting wrong result
0

LVL 7

Author Comment

ID: 40387782

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#indexOf(int,%20int)

indexOf
public int indexOf(int ch,
int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.
i think i looked at wrong indexOf API method where it is taking int ch and in fromIndex as variables not String and int as in our method
str.indexOf("xx", from)

where can i see above API method?
0

LVL 7

Author Comment

ID: 40387812
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);

instead of from name using 3 times can we use different names?
0

LVL 7

Author Comment

ID: 40387915
looks like substring method is far easy to grasp than this index method to me

for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);

0

LVL 7

Author Comment

ID: 40387920
``````package eePackage;

public class Test15 {

public static void main(String[] args) {
// TODO Auto-generated method stub
int howMany= countXX("xxabcdxxxxxx");
System.out.println("number is--->"+howMany);

}

static int countXX(String str) {
int from = str.indexOf("xx") + 1;
int count=0;
while (from > 0)
{
from = str.indexOf("xx", from) + 1;
System.out.println(from);
count++;
}
return count;
}

}
``````

when i ran above code i got some confusing output different than yours

7
8
9
10
11
0
number is--->6

I have not got 1 at all.
0

LVL 36

Assisted Solution

mccarl earned 500 total points
ID: 40387921
when this loop ends. To me >0 is always satisfied leading to infinity loop
If you look in the Javadoc for String.indexOf (any of them), you will see that it states that if the string is NOT found then it will return -1. And since we have the + 1 in the brackets, then -1 + 1 = 0 and since 0 is NOT > 0 the loop will end.
0

LVL 7

Author Comment

ID: 40387922
i finally found the api for this

int      lastIndexOf(String str, int fromIndex)
Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the specified index.

str.indexOf("xx", from)

where can i find more simple examples on above api. please advise
0

LVL 17

Assisted Solution

krakatoa earned 500 total points
ID: 40388075
looks like substring method is far easy to grasp than this index method to me

for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);

Well I don't think I personally can help on this one much more. You will see in the comments that all your questions have been covered repeatedly. I think what you do not grasp is that the elements of an array of any type - including STRING - start at zero. In mccarl's "for" code, the variable 'from' starts at zero, and is then increased by one more than where it found the last "xx"  - IF it finds it. He then asks whether that value is more than zero because the middle term of the for loop (the termination condition), has to return a boolean.

What you are missing also is that this will *******NOT******* result in an infinite loop, because the last return value will not be more than zero, because WHERE would the code find "xx" again AFTER THE END OF THE STRING????

'from' gets assigned to the position where the indexOf() code finds "xx". At the LAST interrogation of the string, 'from' will be ****************-1**************, because the searched-for string has NOT been found. And, as mccarl said, adding 1 to -1 is ZERO, and ZERO is LESS THAN "MORE THAN ZERO" !!
0

LVL 17

Expert Comment

ID: 40388681
(@all :

sorry, btw, in all this cuffuffle, I missed the fact that CPColin had incremented. viz:

``````int from = str.indexOf("xx") + 1;
``````
)
0

LVL 28

Expert Comment

ID: 40388892
instead of from name using 3 times can we use different names?
Yes, we could rewrite mccarl's solution to the following.
``````int countXX(String str) {
int count = 0;
int currentIndex = str.indexOf("xx");
int fromIndex = 0;
for( ; currentIndex >= 0; ){
count++;
fromIndex = currentIndex + 1;
currentIndex = str.indexOf("xx", fromIndex);
}
return count;
}
``````
As CPColin posted it is clearer as
``````int countXX(String str) {
int count = 0;
int currentIndex = str.indexOf("xx");
int fromIndex = 0;
while(currentIndex >= 0){
count++;
fromIndex = currentIndex + 1;
currentIndex = str.indexOf("xx", fromIndex);
}
return count;
}
``````
0

LVL 7

Author Comment

ID: 40388919
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++);
Above code using from for initialization termination(where 'from' used two times) and then count for increment

till now i am familiar only with for loops where initialization, termination and increment all deals with single variable say 'i' as below

class ForDemo {
public static void main(String[] args){
for(int i=1; i<11; i++){
System.out.println("Count is: " + i);
}
}
}
``````/*package eePackage;

public class Test16 {

public static void main(String[] args) {
// TODO Auto-generated method stub

}

countXX("xxabcdxxxxxx");
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++){System.out.println(from);}

}*/

package eePackage;

public class Test16 {

public static void main(String[] args) {
// TODO Auto-generated method stub
int howMany= countXX("axxabcdxxesxxaxx");
System.out.println("number is--->"+howMany);

}

static int countXX(String str) {
int count=0;
for(int from = 0; (from = str.indexOf("xx", from) + 1) > 0; count++){
System.out.println(from);
//return count;
}
return count;

}

}
``````

when i tried above program i got correct  output including from position (which is 1 more of index position of xx)
2
8
12
15
number is--->4
0

LVL 28

Expert Comment

ID: 40388938
We could rewrite mccarl's solution to the following.
``````int countXX(String str) {
int count = 0;
int currentIndex = str.indexOf("xx");
int fromIndex = 0;
for( ; currentIndex >= 0; ){
count++;
fromIndex = currentIndex + 1;
currentIndex = str.indexOf("xx", fromIndex);
}
return count;
}
``````
As CPColin posted it is clearer as
``````int countXX(String str) {
int count = 0;
int currentIndex = str.indexOf("xx");
int fromIndex = 0;
while(currentIndex >= 0){
count++;
fromIndex = currentIndex + 1;
currentIndex = str.indexOf("xx", fromIndex);
}
return count;
}
``````
0

LVL 7

Author Comment

ID: 40388953
``````  for( ; currentIndex >= 0; ){
count++;
fromIndex = currentIndex + 1;
``````

can we write for loop without initialization and increment.

what is the main difference between currentIndex and fromIndex.( how do i remove my focus on variable names but rather keep focus on what is happening and what is adding etc process, i get confused sometimes with variable names which are completely arbitrary right)

I am wonder challenging nature of java where something like simple for loop can have so many ways of writing and still very thing is correct
0

LVL 28

Expert Comment

ID: 40388994
can we write for loop without initialization and increment.
Yes. We could also write it as
``````int countXX(String str) {
int count = 0;
int currentIndex = str.indexOf("xx");
int fromIndex = 0;
for( ; ; ){
if(currentIndex < 0)break;
count++;
fromIndex = currentIndex + 1;
currentIndex = str.indexOf("xx", fromIndex);
}
return count;
}
``````
what is the main difference between currentIndex and fromIndex
currentIndex is the index where we found the latest "xx" substring.  fromIndex is the index where we begin to look for the next "xx".
how do i remove my focus on variable names but rather keep focus on what is happening
I don't know. But, I think you are making good progress.
variable names which are completely arbitrary right
They are arbitrary. But, we should name them something that makes our code more readable.
I am wonder challenging nature of java
At some point, we fall in love with Java.
0

LVL 17

Expert Comment

ID: 40389010
till now i am familiar only with for loops where initialization, termination and increment all deals with single variable say 'i' as below

Well if you are, then you are familiar with another language, not Java.
0

LVL 7

Author Comment

ID: 40389047
I think you are making good progress.
that makes feel more confident. More more java i learn more more i feel i know only tiny bit and need to know whole lot. I feel i only drank glass full of water from ocean full of ocean :)
How to master java and  feel confident even if you face challenging situations. May be i wil put new topic of discussion for this.
0

LVL 17

Expert Comment

ID: 40389109
How to master java and  feel confident even if you face challenging situations.

One way is to pay close attention to what people like mccarl have to say - because you won't most likely be able to find that level of knowledge around every corner, or from a text book. The point I am making is you have to understand the mechanics of what the top experts say, and not go off onto something else before you have understood each point.
0

LVL 7

Author Comment

ID: 40392401
``````public class Test18 {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int a=countXX("xxabcdxxxxxx");
System.out.println("a is-->"+a);

}
static int countXX(String str) {
int count = 0;
int currentIndex = str.indexOf("xx");
int fromIndex = 0;
for( ; currentIndex >= 0; ){
count++;
fromIndex = currentIndex + 1;
currentIndex = str.indexOf("xx", fromIndex);
System.out.println("fromIndex is--->"+fromIndex);
System.out.println("currentIndex--->"+currentIndex);
}
return count;
}
}
``````

I merged different pieces from above comments to understand index(string, int) better. I got output as below

fromIndex is--->1
currentIndex--->6
fromIndex is--->7
currentIndex--->7
fromIndex is--->8
currentIndex--->8
fromIndex is--->9
currentIndex--->9
fromIndex is--->10
currentIndex--->10
fromIndex is--->11
currentIndex--->-1
a is-->6

I even looked below link to understand
http://www.tutorialspoint.com/java/lang/string_indexof_string_index.htm

0

LVL 7

Author Comment

ID: 40392404
why it printed

fromIndex is--->1
currentIndex--->6
fromIndex is--->7
currentIndex--->7

1,6 then 7, 7?
0

LVL 28

Accepted Solution

rrz earned 500 total points
ID: 40393497
Please run the following code. I made some changes to make the output make more sense.
``````public class Test {
public static void main(String[] args) {
String s = "xxabcdxxxxxxefxxghxx";
System.out.println("The given string is " + s);
int a = countXX(s);
System.out.println("The total number of \"xx\"s found is " + a);
}
static int countXX(String str) {
System.out.println("The length of the given string is " + str.length());
int count = 0;
int currentIndex = str.indexOf("xx");
int fromIndex = 0;
for( ; currentIndex >= 0; ){
System.out.println("A \"xx\" was found at index " + currentIndex);
count++;
System.out.println("The number of \"xx\"s found so far is " + count);
fromIndex = currentIndex + 1;
System.out.println("Now let's look for another \"xx\" starting from index " + fromIndex);
currentIndex = str.indexOf("xx", fromIndex);
}
System.out.println("No more \"xx\"s were found.");
return count;
}
}
``````
The output is
The given string is xxabcdxxxxxxefxxghxx
The length of the given string is 20
A "xx" was found at index 0
The number of "xx"s found so far is 1
Now let's look for another "xx" starting from index 1
A "xx" was found at index 6
The number of "xx"s found so far is 2
Now let's look for another "xx" starting from index 7
A "xx" was found at index 7
The number of "xx"s found so far is 3
Now let's look for another "xx" starting from index 8
A "xx" was found at index 8
The number of "xx"s found so far is 4
Now let's look for another "xx" starting from index 9
A "xx" was found at index 9
The number of "xx"s found so far is 5
Now let's look for another "xx" starting from index 10
A "xx" was found at index 10
The number of "xx"s found so far is 6
Now let's look for another "xx" starting from index 11
A "xx" was found at index 14
The number of "xx"s found so far is 7
Now let's look for another "xx" starting from index 15
A "xx" was found at index 18
The number of "xx"s found so far is 8
Now let's look for another "xx" starting from index 19
No more "xx"s were found.
The total number of "xx"s found is 8
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
###### Suggested Courses
Course of the Month10 days, 8 hours left to enroll