java substring challenge

hi,

I was going through below challenge
http://codingbat.com/prob/p178318

I have not understood the problem clearly


Given a string, return the count of the number of times that a substring length 2 appears in the string and also as the last 2 chars of the string, so "hixxxhi" yields 1 (we won't count the end substring).

last2("hixxhi") → 1
last2("xaxxaxaxx") → 1
last2("axxxaaxx") → 2

Are they saying substring could be xx and aa as well or only xx(excluding last one)r. Please advise
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.

ozoCommented:
In the examples "xaxxaxaxx" and "axxxaaxx" the substring could only be xx

last2("hixxhi") → 1
We count this one:  "hixxhi"
last2("xaxxaxaxx") → 1
We count this one: "xaxxaxaxx"
last2("axxxaaxx") → 2
We count these two: "axxxaaxx"  "axxxaaxx"
0
gudii9Author Commented:
why aa is not substring. please advise
0
ozoCommented:
We don't count it because it doesn't appear "as the last 2 chars of the string"
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

gudii9Author Commented:
if my Sting is like " yqaawaataa" then substring count is 2 and substring is "aa" right
0
ozoCommented:
That would be my understanding.
0
dpearsonCommented:
A tip would be to start by finding the last 2 characters in the string.

Then decide how often those 2 characters appear elsewhere in the string.

Doug
0
krakatoaCommented:
So any String less than 4 chars long will return zero. (Just an observation here) ;)
0
oleberCommented:
imagine the string "aaaa", what is the return value?
0
krakatoaCommented:
@oleber -

is your comment directed at the OP or me?
0
krakatoaCommented:
As oleber may be referring to - a String such as "xxxx" (which is one of their test strings) is a dubious one in my opinion, because you can't have a return value of 2 for that, if the last pair of "xx"s  is supposed to fall outside the ambit. The challenge doesn't mention overlapping !

Another test shows the ambiguity I am talking about :

last2("1717171") → 2

because in the "xxxx" text, the third char is being borrowed to make a second match. But in the "17" scenario, the third "7" isn't being borrowed - so I have no idea what they have in mind. But I could, of course, be wrong.
0
ozoCommented:
overlapping is implied by
last2("axxxaaxx") → 2
and
last2("xxxx") → 2
seems to imply that some String less than 4 chars long may return non-zero
0
krakatoaCommented:
ozo - yes, but look at the "17" scenario.
0
krakatoaCommented:
And, as has been covered  before by many of us, (mccarl made the point first), using for-next (as the answer suggests) for this question is not as efficient as skipping the counter to the last-found incidence of the substring.

String searching in serious contexts would take far longer than necessary using a for-next; whereas a selective increment would be far more productive.
0
ozoCommented:
Do you mean the example ending with "71"?
last2("1717171") → 2
Overlap does not apply here, so we count these two: "1717171"  "1717171"
0
awking00Commented:
public int last2(String str) {
      String last2 = str.substring(str.length() -2,str.length());
      String notLast2 = str.substring(0,str.length() -2);
      int counter = 0;
      for (int i = 0; i < notLast2.length() - 1; i++) {
            String pair = notLast2.substring(i, i + 2);
            if (pair.equals(last2)) {
                  counter++;
            }
      }
      System.out.println(str + "  " + counter);
      return counter;
}
0
krakatoaCommented:
Do you mean the example ending with "71"?

Ah - well spotted! Looks like I suffered from some dyslexia here! My bad.
0
krakatoaCommented:
@ awking -

that code will not pass all tests.
0
krakatoaCommented:
You'd have to do this :

public int last2(String str) {

  int count=0;

  if(str.length()<4){return 0;}
    
  String end = str.substring(str.length()-2);
  String front = str.substring(0,str.length()-1); 
  int a=0;
  
 while(front.indexOf(end,a)>-1){
 			              
				   a=(front.indexOf(end,front.indexOf(end,a)))+1;		   
                   count++;       
			  
  }    
        return count;
}

Open in new window

0
gudii9Author Commented:
public class Test20 {

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

	public static int last2(String str) {
		int len=str.length();
		int count=0;
		int initialCount=0;
		if(len>4){
		if((str.substring(len-2,len-1)).equals((str.substring(len-2,len-1))))
		{
		for(int i=0;i<len;i++){
			if(str.contains("xx")){
		initialCount = initialCount+1;
		
			}
			count=initialCount-1;

		}
		}
		else{
		count=0;
		}
		}


		return count;
		  
		}
}

Open in new window


I wrote as above based on thoughts came to my mind i got wrong output
i is--->11


what i am doing mistake. please advise
0
krakatoaCommented:
Haven't checked it all yet, but len>4 should be len>=4 for one thing.

This will always be true :
if((str.substring(len-2,len-1)).equals((str.substring(len-2,len-1))))

. . .do you really want that? I'm surprised it even compiles.
0
awking00Commented:
Think of what is happening. The length of the string is 12. The substring of the string starting at index 10 (length - 2) and ending at index 11 (length - 1) is always going to equal the substring of the string starting at index 10 (length - 2) and ending at index 11 (length - 1) so the program always goes into the for loop, which says loop from 0 to less than 12 (meaning 11) or 12 loops (i.e. 0,1,2,3,4,5,6,7,8,9,10,11) and then, if the string contains "xx" anywhere (which it always does) add 1 to the initialCount so at the end of the looping, the initalCount would be 12 and initialCount minus 1 would make the count be 11 and you never reach the else, so 11 is returned.
0
krakatoaCommented:
if the string contains "xx" anywhere (which it always does)

No it doesn't always contain "xx". Look at the examples it has to run.
0
krakatoaCommented:
Your code gudii would need to shape more to

public int last2(String str) {
  int len=str.length();
		int count=0;
		//int initialCount=0;
		if(len>=4){
		//if((str.substring(len-2,len-1)).equals((str.substring(len-2,len-1))))
		//{
		for(int i=0;i<len-2;i++){
			if(str.substring(i,i+2).equals(str.substring(str.length()-2,str.length()))){
		//initialCount = initialCount+1;
		count++;
		
			}
			//count=initialCount-1;

		}
		//}
		//else{
		//count=0;
		//}
		}


		return count;
}

Open in new window

0
gudii9Author Commented:
public class Test20 {

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

	public static int last2(String str) {
		int len=str.length();
		int count=0;
		int initialCount=0;
		if(len>=4){
		if((str.substring(len-2,len-1)).equals((str.substring(len-1,len))))
		{
		for(int i=0;i<=len-2;i++){
			if((str.substring(i,i+2)).equals((str.substring(len-2,len)))){
		initialCount = initialCount+1;
		
			}
			count=initialCount-1;

		}
		}
		else{
		count=0;
		}
		}


		return count;
		  
		}
}

Open in new window


I modified as above and got right output
i is--->2
 
Below statement
      for(int i=0;i<=len-2;i++){

if i give like

      for(int i=0;i<=len-1;i++){

I am getting index outpfbound. I wonder why. I usually remember giving i<=len-1(since lenght is always 1 more than index since index starts with 0).
What is the difference between my code and your code.
Please advise.
0
gudii9Author Commented:
public int last2(String str) {
  int len=str.length();
		int count=0;
		//int initialCount=0;
		if(len>=4){
		//if((str.substring(len-2,len-1)).equals((str.substring(len-2,len-1))))
		//{
		for(int i=0;i<len-2;i++){
			if(str.substring(i,i+2).equals(str.substring(str.length()-2,str.length()))){
		//initialCount = initialCount+1;
		count++;
		
			}
			//count=initialCount-1;

		}
		//}
		//else{
		//count=0;
		//}
		}


		return count;
}

Open in new window


In the challenge mentioned as below
so "hixxxhi" yields 1 (we won't count the end substring).

where you have taken care of that? Please advise
0
krakatoaCommented:
where you have taken care of that? Please advise

I am going to be busy for a while. I would say you ought to look at the differences between the code that works and that which doesn't, and go over the logic flows in your own mind.
0
dpearsonCommented:

where you have taken care of that? Please advise

This is handled by the loop stopping at "len-2" rather than "len":

for(int i=0;i<len-2;i++){
...
}

So the part where we're counting the number of matches in the string, stops 2 characters before the end of the string.

So it (correctly) doesn't count the last 2 characters as a "match".

Doug
0
gudii9Author Commented:

public class Test20 {

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

      public static int last2(String str) {
            int len=str.length();
            int count=0;
            int initialCount=0;
            if(len>=4){
            if((str.substring(len-2,len-1)).equals((str.substring(len-1,len))))
            {
            for(int i=0;i<=len-2;i++){
                  if((str.substring(i,i+2)).equals((str.substring(len-2,len)))){
            initialCount = initialCount+1;
            
                  }
                  count=initialCount-1;

            }
            }
            else{
            count=0;
            }
            }


            return count;
             
            }
}

how my code also working fine where i have to subtract by one

count=initialCount-1;
0
awking00Commented:
krakatoa,
>>that code will not pass all tests. <<
What test does it not pass?
>>No it doesn't always contain "xx". Look at the examples it has to run.<<
I was referring to his specific example where he has set the value of str to "axexxwexxwxx" in his code and, as strings are not immutable, it will always contain "xx"

gudii9,
Your test of if (str.substring(len-2,len-1).equals(str.substring(len-1,len)) is testing to see if the next to last character matched the last character, so it will not take care of the instance where the last two characters are different (as with the case of "hixxhi").
>>how my code also working fine where i have to subtract by one<<
Because your searching the entire string except the last two characters, but you only need to search the portion of the string without the two end characters up to the point of its next to last character (or the whole string except the last 3) since you're looking for a two-character combination.
0
awking00Commented:
I meant to say "as Strings are immutable" above.
0
gudii9Author Commented:
Because your searching the entire string except the last two characters, but you only need to search the portion of the string without the two end characters

Open in new window


I did not clearly get it. Above two sounding same to me. please advise
0
awking00Commented:
The string you are testing is "axexxwexxwxx" and your program is testing the portion in bold of the string (i.e. "axexxwexxwxx) but it only needs to test the portion up to the next to last character of that portion (i.e. "axexxwexxwxx") since you're looking for a matching string of two.
0
gudii9Author Commented:
public int last2(String str) {
      String last2 = str.substring(str.length() -2,str.length());
      String notLast2 = str.substring(0,str.length() -2);
      int counter = 0;
      for (int i = 0; i < notLast2.length() - 1; i++) {
            String pair = notLast2.substring(i, i + 2);
            if (pair.equals(last2)) {
                  counter++;
            }
      }
     // System.out.println(str + "  " + counter);
      return counter;
}

Open in new window


when i tried as above failing two test cases as below

Expected      Run            
last2("hixxhi") → 1      1      OK         
last2("xaxxaxaxx") → 1      1      OK         
last2("axxxaaxx") → 2      2      OK         
last2("xxaxxaxxaxx") → 3      3      OK         
last2("xaxaxaxx") → 0      0      OK         
last2("xxxx") → 2      1      X         
last2("13121312") → 1      1      OK         
last2("11212") → 1      1      OK         
last2("13121311") → 0      0      OK         
last2("1717171") → 2      2      OK         
last2("hi") → 0      0      OK         
last2("h") → 0      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: -1 (line number:2)      X         
last2("") → 0      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: -2 (line number:2)

Please advise
0
gudii9Author Commented:
This is handled by the loop stopping at "len-2" rather than "len":

for(int i=0;i<len-2;i++){
...
}

So the part where we're counting the number of matches in the string, stops 2 characters before the end of the string.

So it (correctly) doesn't count the last 2 characters as a "match".
when i write as below getting index out of bound. please advise

public int last2(String str) {
  int len=str.length();
		int count=0;
		//int initialCount=0;
		if(len>=4){
		//if((str.substring(len-2,len-1)).equals((str.substring(len-2,len-1))))
		//{
		for(int i=0;i<len;i++){
			if(str.substring(i,i+2).equals(str.substring(str.length()-2,str.length()))){
		//initialCount = initialCount+1;
		count++;
		
			}
			//count=initialCount-1;

		}
		//}
		//else{
		//count=0;
		//}
		}


		return count;
}

Open in new window



Expected      Run            
last2("hixxhi") → 1      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 7 (line number:9)      X         
last2("xaxxaxaxx") → 1      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 10 (line number:9)      X         
last2("axxxaaxx") → 2      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 9 (line number:9)      X         
last2("xxaxxaxxaxx") → 3      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 12 (line number:9)      X         
last2("xaxaxaxx") → 0      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 9 (line number:9)      X         
last2("xxxx") → 2      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 5 (line number:9)      X         
last2("13121312") → 1      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 9 (line number:9)      X         
last2("11212") → 1      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 6 (line number:9)      X         
last2("13121311") → 0      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 9 (line number:9)      X         
last2("1717171") → 2      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 8 (line number:9)      X         
last2("hi") → 0      0      OK         
last2("h") → 0      0      OK         
last2("") → 0      0
0
awking00Commented:
As for "xxx", I'm getting a result of 0, which I believe to be correct. As for "h" or any single character string, you will get an index out of bounds exception. The solution to that is to wrap the code in an if (str.length() > 1) with a default value of 0.
0
krakatoaCommented:
@awking00

You should know that your code does not pass the tests at the codingbat site, on which the OP is working. The link is at the top of his question, and if you try your code there as you posted it, you will see that it doesn't work in all cases.
0
dpearsonCommented:
You've got 2 solutions on the go at once now - so this is getting a bit complicated :)

But working with the first of these - you get an exception for the cases where the string is really short - because the code to lookup the last 2 characters:
      String last2 = str.substring(str.length() -2,str.length());

only works if the length is >= 2.

Try this slightly modified version (I also removed the notlast2 string as it's not needed at all):

public int last2(String str) {
      if (str.length() < 2)
        return 0 ;
        
      String last2 = str.substring(str.length() -2,str.length());
      int counter = 0;
      for (int i = 0; i < str.length()-2; i++) {
            String pair = str.substring(i, i + 2);
            if (pair.equals(last2)) {
                  counter++;
            }
      }
      return counter;
}

Open in new window

0
CEHJCommented:
Here's another - minimising substringing (which is relatively expensive)

 
   public int last2(String str) {
        int result = 0;
        int pos = 0;
        int len = str.length();
        if (len > 2) {
            String lastTwo = str.substring(len - 2);
            while ((pos = str.indexOf(lastTwo, pos)) > -1) {
                result++;
                pos++;
            }
            result--;
        }
        return result;
    }

Open in new window

0
awking00Commented:
CEHJ,
I like it, although I think the "if (len > 2)" condition needs to be modified to "if (len > 3)" as "xxx" would produce a result of 1 instead of 0.
0
krakatoaCommented:
It *should* produce a result of 1, not 0. That's what I pointed out to you once before.
0
awking00Commented:
I guess there's a misinterpretation of "we won't count the end substring". I'm taking it to mean that the last two characters can not be any part of the test and you're seeming to say that as long as the two characters exist at any index before the last two characters, the test is met.
0
ozoCommented:
I agree that the problem description leaves room for interpretation,
and the tests leave interpretations for "xxx" undetermined, but
last2("xxxx") → 2
would seem to support the view that "xx" appears at 3 places in "xxxx", of which one at the end does not count.
0
gudii9Author Commented:
public class Test20 {

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

	public static int last2(String str) {
		int len = str.length();
		int count = 0;

		if (len <= 2)
			return count;

		for (int i = 0; i < len - 2; i++) {
			if (str.substring(i, i + 2).equals(
					str.substring(str.length() - 2, str.length()))) {
				System.out.println("str.substring(i,i+2)-->"
						+ str.substring(i, i + 2));

				count++;

			}

		}

		return count;
	}
}

Open in new window







i modified as above and all test cases passing and got out put as
str.substring(i,i+2)-->xx
str.substring(i,i+2)-->xx
str.substring(i,i+2)-->xx
i is--->3

axexxwexxwxxq(len-3,i=12)x(len-2,i=13)x(len-1,i=14)
For above string
length 15
so once i=12

based on this
      if(str.substring(i,i+2).equals(str.substring(str.length()-2,str.length()))){
code looks for str.substring(12,14) which is qx right not xx with last two terms(xx)
0
krakatoaCommented:
code looks for str.substring(12,14) which is qx right

 . . . well, it looks for xq actually.

@awking and ozo :

not interpretation if you want to pass the tests. But as I said originally, the last two chars should be ignored for partial inclusion in overlapping finds for the search string in the remainder of the string. I think this question was a mess on their part.
0
CEHJCommented:
as "xxx" would produce a result of 1 instead of 0.

It should do afaics. Anyway it passes all the tests and that's good enough for me ;)
0
ozoCommented:
The tests do not resolve the question of whether last2("xxx") should be 0 or 1, but they do resolve the question of whether last2("xxxx") should be 1 or 2.

But regardless of the former question, for which there is insufficient information to answer definitively, and for which we can all find justification for our own opinions,
gudii9 is now able to pass all the tests, so the question seems moot.
0
gudii9Author Commented:
code looks for str.substring(12,14) which is qx right


 . . . well, it looks for xq actually.
axexxwexxw x   x   q    x    x
0123456789 10 11 12 13 14


As per above indexing positions and based on the link below i thought it is 'qx' not 'xq'. please advise

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


public String substring(int beginIndex,
               int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
Examples:

 "hamburger".substring(4, 8) returns "urge"
 "smiles".substring(1, 5) returns "mile"
 
Parameters:
beginIndex - the beginning index, inclusive.
endIndex - the ending index, exclusive.
0
ozoCommented:
"axexxwexxwxxqxx".substring(12,14) is qx, as you can see
 System.out.println( "axexxwexxwxxqxx".substring(12,14) );
0
gudii9Author Commented:
public class Test20 {

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

      public static int last2(String str) {
            int len = str.length();
            int count = 0;
             System.out.println( "axexxwexxwxxqxx".substring(12,14) );
            if (len <= 2)
                  return count;

            for (int i = 0; i < len - 2; i++) {
                  if (str.substring(i, i + 2).equals(
                              str.substring(str.length() - 2, str.length()))) {
                        System.out.println("str.substring(i,i+2)-->"
                                    + str.substring(i, i + 2));

                        count++;

                  }

            }

            return count;
      }
}

i also got qx

as below

qx
str.substring(i,i+2)-->xx
str.substring(i,i+2)-->xx
str.substring(i,i+2)-->xx
i is--->3
0
krakatoaCommented:
This question has become overcomplicated and the OP doesn't seem satisfied with any of the answers, and continues to go off on a tangent and try something else, so having said all I can say, I'm now out of this one.

And I do believe the question was a mess from the start - a string of 2 chars is just that, and simply because there was a case of overlapping in a previous question, doesn't mean that that pertains this time. "xxx" should be zero. Ciao.
0
krakatoaCommented:
As there is no limit on interpretations, this one will do all the tests except the two which are based on overlap.

public int last2(String str) {
  int num=0;
  int totlen=0;
  
  if(str.length()<4){return 0;}
String[] sA = str.split(str.substring(str.length()-2));

for(int i=0; i<sA.length;i++){

totlen = totlen + sA[i].length();
}
num = ((str.length()-totlen)-2)/2;

return num;
}

Open in new window

0
dpearsonCommented:
The last code you posted (gudii9) seems to be fine.

Is this problem solved for you now?  I'm not sure I understand what else you're asking.

	public int last2(String str) {
		int len = str.length();
		int count = 0;

		if (len <= 2)
			return count;

		for (int i = 0; i < len - 2; i++) {
			if (str.substring(i, i + 2).equals(
					str.substring(str.length() - 2, str.length()))) {

				count++;

			}

		}

		return count;
	}

Open in new window

0
krakatoaCommented:
I don't think we've had this one yet either . . .

public int last2(String str) {

                int len = str.length();
		int count = 0;
                int i = 0;

		if (len <= 2){return count;}

	while (i < len - 2) {

		if (str.substring(i, i+2).equals(str.substring(len - 2))) {
                         i = str.indexOf(str.substring(len-2),i)+1;
		         count++;
		}
                else{i=i+1;}
	}

		return count;
}

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
gudii9Author Commented:
	public int last2(String str) {
		int len = str.length();
		int count = 0;

		if (len <= 2)
			return count;

		for (int i = 0; i < len - 2; i++) {
			if (str.substring(i, i + 2).equals(
					str.substring(str.length() - 2, str.length()))) {

				count++;

			}

		}

		return count;
	}

Open in new window


I like all the solutions above. In the above solution below line was earlier confusing but now it is clear
if (str.substring(i, i + 2).equals(
                              str.substring(str.length() - 2, str.length())))
we are checking for last iternation as below for string axexxwexxwxxqxx

 if (str.substring(12, 14).equals(
                              str.substring(13, 15)))

since qx.equals("xx")that one is not counted.
And our for loop ending there so last 'xx' also not counting. Now it all make sense.


One last question with last post

while (i < len - 2) {

            if (str.substring(i, i+2).equals(str.substring(len - 2))) {
                         i = str.indexOf(str.substring(len-2),i)+1;
                     count++;
            }
                else{i=i+1;}
      }

Above code is not clear with below line
        i = str.indexOf(str.substring(len-2),i)+1;

What it means. Please advise
0
krakatoaCommented:
It's just incrementing the index position again from where to start searching, either to the position where it found the last "xx" (or whatever it's looking for), or, if it didn't find "xx", then it increments the start search position by 1, and searches the rest of the reference string again for it. It keeps doing this, until it cant find "xx" any more in the part of the string that exists after you subtract the last two characters from the original string.

I'm pleased you like all our suggestions. And talking about favourites - not that I am biased of course - my personal sweetheart is the one I posted which uses String.split(). This makes Java do the decisive part, and leaves you to play with a bit of simple maths. ;)
0
ozoCommented:
0
krakatoaCommented:
Who me?
0
ozoCommented:
The one who asked "What it means."
0
dpearsonCommented:
Above code is not clear with below line
        i = str.indexOf(str.substring(len-2),i)+1;

That's a pretty complicated line.  You might find it easier to see what it's doing if it was broken into 2 parts like this:

while (i < len - 2) {
           String end = str.substring(len-2) ; // Last 2 characters in the string

            if (str.substring(i, i+2).equals(end)) {
                         i = str.indexOf(end,i)+1;
                     count++;
            }
                else{i=i+1;}
      }

Open in new window


Now the line becomes:
                         i = str.indexOf(end,i)+1;

This uses a slightly more advanced version of "indexOf" where you start searching for the substring (end in this case) from position 'i', rather than from the start of the string.

So in English this is basically:
   - Find the position in the string 'str' where end appears, starting the search from position 'i'

Does that make sense?
0
ozoCommented:
Doing String end = str.substring(len-2) outside the loop can also be useful for not having to re-calculate str.substring(len-2) multiple times
0
dpearsonCommented:
Yeah - I just wasn't sure if he was going to put it before the guard, get an error and get confused.  Hence why it's in the loop :)
0
krakatoaCommented:
Call me slow to see the penny drop, but I *have* to say this :

this infamous "overlapping" issue is a nonsense in terms of this particular question. Why, well because you can have an overlapping "xx" (inside "xxx" for example), there's no such thing as an overlapping "hi" (nor any of the other heterogeneous tail-end substrings in the challenge). What would an overlapping "hi" look like - "hh", "ii"  - "ih" perhaps ? Lol.
0
gudii9Author Commented:
i = str.indexOf(end,i)+1;

instead of above we have to  say as below if no overlapping is allowed right? please advise

i = str.indexOf(end,i)+1;

I tried like
public class Test20 {

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

	public static int last2(String str) {

		int len = str.length();
		int count = 0;
		int i = 0;

		if (len <= 2) {
			return count;
		}

//		while (i < len - 2) {
//
//			if (str.substring(i, i + 2).equals(str.substring(len - 2))) {
//				i = str.indexOf(str.substring(len - 2), i) + 1;
//				count++;
//			} else {
//				i = i + 1;
//			}
		 String end = str.substring(len-2) ; // Last 2 characters in the string
		while (i < len - 2) {
	          

	            if (str.substring(i, i+2).equals(end)) {
	                         i = str.indexOf(end,i)+2;
	                     count++;
	            }
	                else{i=i+1;}
	      }

		

		return count;
	}
}

Open in new window


i got output of xx count without overlap
 i is--->3

i = str.indexOf(end,i)+4;


even i say as above i still get same output
 i is--->3


what is the significance of else loop with incrementing i value by 1(can we increment by 2 or 3 instead?

 else{i=i+1;}
please advise
0
krakatoaCommented:
public int last2(String str) {  /*beginning of method. Suck in a String for analysis. Ensure an int is returned.*/

                int len = str.length(); /*capture the length of the String you've been given, in case you need it.*/
            int count = 0; /* declare an int variable as a counter, and prime it so it's ready to use.*/
                int i = 0; /* declare and assign another int variable, to use as a loop counter. Doing it this way just makes what's going on in the while loop a tiny bit clearer, as it's decluttered from other terms, but usually, you'd handle this counter INSIDE the loop - most likely moreso in a for loop. Anyway, read on.*/

            if (len <= 2){return count;} /* if the length of the String is less than 3, then forget doing anything else, and just return 0, as we have been given a String that won't satisfy any of the criteria. And the main criterion was to see how many times the last 2 characters of the String are repeated throughout the String, with the exception of taking into account the last two characters. Since a String of length 3 or less cannot possibly fulfil this criterion, we may as well save a bit of processing time, and chuck it out a priori.*/

      while (i < len - 2) { /* Here we go then - we seem to have an eligible String. So all the time the variable i (which at the moment is zero) is less than the length of the String -2, then let's do this :*/

            if (str.substring(i, i+2).equals(str.substring(len - 2))) {/* Oow, here's another condition - we've got to ensure that even though I might be less than the length of the string-2, we further have to ensure that the part of the string which starts at position i, and goes on for 2 more characters past i, is equal to the last 2 characters of the String. And IF IT IS, then BINGO . . . we've FOUND a match; so we may as well prepare ourselves for the eventuality that there will be ANOTHER match further up the string, so let us now increment i, so that it points further up the string, and doesn't get stuck looking at the same old boring part of the string that we anyway just looked at. So here we go - let's increment i :*/
                         i = str.indexOf(str.substring(len-2),i)+1; /* i can now be set to ONE PLACE* more than where we just found our searched-for substring. We were looking in str, right, at the index position (i**) of the occurrence of these last two characters in the entire string (str.substring(len-2)) SO REALLY THIS LINE OF CODE SAYS "MAKE i EQUAL TO WHERE YOU FIND THE SUBSTRING (that instruction is up to the "+1" part of the code. BUUUUUUUUT, just as you thought we were about to leave this line of code, Java's precedence evaluation engine ALLOWS US TO ADD A POST ASSIGNMENT INCREMENT to that value, and so we move i on by 1, by saying :"+1". GOTCHA!! Now we have i right where we want it - ready to give a starting index for the NEXT loop of the search, which doesn't repeat the last starting position and waste out time.*/
                     count++; /* and because we met the above If condition (which was that those two chars at that particular i position, going on for 2 chars, WAS the same as the end two chars of the entire String (which is our overriding criterion), we can now increment the number of times counter that we have found the string by 1 !! Yippee!*/
            }
                else{i=i+1;} /* BUT, if we didn't find our two chars at that position, then we have to be prepared that they might be at the NEXT POSSIBLE position, and that NEXT POSSIBLE position can only be 1 character further along the string, because we can't afford to skip over anything, as it might contain what we are looking for, so an increment of 1 is the ONLY possible step we can make. Right?*/
      } /* I may not look like much, but I'm the loop folder. I think we should go back to the top of the while loop, and check that we've seen all this darn string before we shoot our mouth off and return some number that doesn't mean squat.*/

            return count; /* Oow - we searched all the string, and I'm sending back the number that we found. */
} /* I end the method - and remember, when you re-read the narrative alongside these comments, increase i and count each time where appropriate, and ask the same questions all over again. But whichever way you look at it, the loop will only exit when we've looked at the entire string, after which the method ends.*/
0
dpearsonCommented:
And who says the art of documentation is dead :)
0
krakatoaCommented:
Lol. ;)

My art is verbatim-  yours always cleaner and clearer. ;)

BTW OP, Doug ought really to have had 100 of my points  I think! We overkilled this one, as the lawd is my witness.
0
awking00Commented:
krakatoa,
I salute your latest response. I was in the process of generating a very lengthy response going line by line defining what each was doing when the acceptance came across, so I stopped and I'm glad I did since my editorial didn't have nearly the levity or brevity or your illustrious response. Good show!
0
krakatoaCommented:
I salute your salute ! How about that! ;)

I feel like I've been "sleeping in the office" since this question began, sometimes with only the cleaner to talk to as it were - all present company excepted of course.

Now you've come back through the door, it's like we are in the neighbourhood bar for a couple of trauma-taming beers, trying to get our lives back on track. ;)

And as we leave after our last drink, swaying from side to side, someone says "Hey fellas., did you guys ever clear up that overlapping thing?". We stop - eye contact. You say - "uh, shiiiiiiiishhhh man, who cares?!!".

I whisper to myself "yeah, well it was never really anything to ever need clearing up."

Outside, Doug draws a six-shooter and says "you guys think you're gonna slide off with my points then, do-ya?"
0
Jeyaseelan MCommented:
I wrote this program in C#  language. It works fine. Let's try this your own language. Here i am not using any builtin functions.

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter the string");
            string s = Console.ReadLine();
            string last = "";
            int size = s.Length - 2,count=0,j=0;
            for (int i = 0; i < s.Length; i++)
            {
                if (i >= size)
                {
                    last = last + s[i];
                }
            }
            for (int i = 0; i < size-1; i++)
            {
               
                    if (last[j] == s[i] && last[j + 1] == s[i + 1])
                    {
                        count++;
                    }                
               
            }
            Console.WriteLine(count);
            Console.ReadLine();
        }
    }
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.