string yak challenge

Hi,

I am trying below challenge
http://codingbat.com/prob/p126212

i have not understood the problem description. Please advise on how to proceed
Suppose the string "yak" is unlucky. Given a string, return a version where all the "yak" are removed, but the "a" can be any char. The "yak" strings will not overlap.

stringYak("yakpak") → "pak"
stringYak("pakyak") → "pak"
stringYak("yak123ya") → "123ya"
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:
It looks like the tests on that challenge do not make use of the
 but the "a" can be any char
clause, so I'd suggest attempting the problem ignoring that part.
0
dpearsonCommented:
You're looking for strings with this pattern:

y*k   where * can be anything

and then you need to skip over those strings and return everything else.

Here's some code to get you started:

public String stringYak(String str) {
  StringBuilder result = new StringBuilder() ;
  int i = 0 ;
  int len = str.length() ;
  
  while (i < len) {
      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
          // We've found a yak string
      } else {
          // This is not part of yak string so we should keep it
      }
      i++ ;
  }
  return result.toString() ;
}

Open in new window


Can you see how it detects the sequence y*k in the string?

Now the question is what should you do when you find that string and what should you do when you don't find that string?  I've put comments in the places where you need to fill in some code.  1 line of code in each place should do the trick...

Doug
0
krakatoaCommented:
public String stringYak(String str) {
  return str.replace(str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y"))+1),"");
}

Open in new window

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

gudii9Author Commented:
public String stringYak(String str) {
  StringBuilder result = new StringBuilder() ;
  int i = 0 ;
  int len = str.length() ;
  
  while (i < len) {
      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
          // We've found a yak string
          result.append(str.substring(i+3,len));
      } else {
          // This is not part of yak string so we should keep it
      }
      i++ ;
  }
  return result.toString() ;
}

Open in new window


i wrote as above some test cases passed but some are failed as below.

Expected      Run            
stringYak("yakpak") → "pak"      "pak"      OK         
stringYak("pakyak") → "pak"      ""      X         
stringYak("yak123ya") → "123ya"      "123ya"      OK         
stringYak("yak") → ""      ""      OK         
stringYak("yakxxxyak") → "xxx"      "xxxyak"      X         
stringYak("HiyakHi") → "HiHi"      "Hi"      X         
stringYak("xxxyakyyyakzzz") → "xxxyyzzz"      "yyyakzzzzzz"      X         


please advise
0
ozoCommented:
What happens when
This is not part of yak string so we should keep it
?
What happens when there is more than one "yak" in the string?
0
gudii9Author Commented:
public String stringYak(String str) {
  StringBuilder result = new StringBuilder() ;
  int i = 0 ;
  int len = str.length() ;
  
  while (i <= len) {
  
      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
          // We've found a yak string
          result.append(str.substring(len-3));
      } else {
          // This is not part of yak string so we should keep it
      }
      i++ ;
  }
  return result.toString() ;
}

Open in new window


I modified like above and still faling lot of test cases
Expected	Run		
stringYak("yakpak") → "pak"	"pak"	OK	    
stringYak("pakyak") → "pak"	"yak"	X	    
stringYak("yak123ya") → "123ya"	"3ya"	X	    
stringYak("yak") → ""	"yak"	X	    
stringYak("yakxxxyak") → "xxx"	"yakyak"	X	    
stringYak("HiyakHi") → "HiHi"	"kHi"	X	    
stringYak("xxxyakyyyakzzz") → "xxxyyzzz"	"zzzzzz"	X	 

Open in new window


please advise
0
dpearsonCommented:
Your code is trying to keep the pieces that match 'yak'.  You're meant to be skipping those.

Try this instead:

public String stringYak(String str) {
  StringBuilder result = new StringBuilder() ;
  int i = 0 ;
  int len = str.length() ;
  
  while (i < len) {
  
      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
          // We've found a yak string
          i += 2 ;
      } else {
          // This is not part of yak string so we should keep it
          result.append(str.charAt(i)) ;
      }
      i++ ;
  }
  return result.toString() ;
}

Open in new window

0
gudii9Author Commented:
public String stringYak(String str) {
  StringBuilder result = new StringBuilder() ;
  int i = 0 ;
  int len = str.length() ;
  
  while (i <= len) {
  
      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
          // We've found a yak string
        //  result.append(str.substring(len-3));
          //public StringBuilder delete(int start, int end)
          //result.delete(0,i);
          result.delete(i,len-1);
      } else {
          // This is not part of yak string so we should keep it
      }
      i++ ;
  }
  return result.toString() ;
}

Open in new window


I tried to delete as above getting failures in test cases and also getting string index out of bound. please advise
Expected	Run		
stringYak("yakpak") → "pak"	""	X	    
stringYak("pakyak") → "pak"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:13)"	X	    
stringYak("yak123ya") → "123ya"	""	X	    
stringYak("yak") → ""	""	OK	    
stringYak("yakxxxyak") → "xxx"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:13)"	X	    
stringYak("HiyakHi") → "HiHi"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:13)"	X	    
stringYak("xxxyakyyyakzzz") → "xxxyyzzz"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:13)"	X	   

Open in new window

0
gudii9Author Commented:
How to write using for loop rather than while loop. I like for loop better some reason. Also i like to use string builder delete method rather than append method in this case. How to make sure i never get string index out of bound exceptions in future. please advise
0
krakatoaCommented:
Getting StringIndexOutOfBoundsException is indicative of the fact that you still do not understand the workings of the for loop, and how it relies on its index incrementation.

As to writing for loops instead of whiles, this is not a choice you should make based on personal preference, but on programming reasoning. Unless you'd like to explain how that works here.
0
gudii9Author Commented:
public String stringYak(String str) {
  StringBuilder result = new StringBuilder() ;
  int i = 0 ;
  int len = str.length() ;
  
  while (i <= len) {
  
      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
        
          result.delete(i,len-1);
      } else {
         
      }
      i++ ;
  }
  return result.toString() ;
}

Open in new window


i see reason for string index out of bound is i am trying to delte on result string builder which has nothing in it.

I wonder how i pass one test case as below
Expected	Run		
stringYak("yakpak") → "pak"	""	X	    
stringYak("pakyak") → "pak"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:10)"	X	    
stringYak("yak123ya") → "123ya"	""	X	    
stringYak("yak") → ""	""	OK	    
stringYak("yakxxxyak") → "xxx"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:10)"	X	    
stringYak("HiyakHi") → "HiHi"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:10)"	X	    
stringYak("xxxyakyyyakzzz") → "xxxyyzzz"	"Exception:java.lang.StringIndexOutOfBoundsException (line number:10)"

Open in new window

0
gudii9Author Commented:
public String stringYak(String str) {
  StringBuilder result = new StringBuilder() ;
  int i = 0 ;
  int len = str.length() ;
  
  while (i < len) {
  
      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
          // We've found a yak string
       [b]   i += 2 ;[/b]
      } else {
          // This is not part of yak string so we should keep it
          result.append(str.charAt(i)) ;
      }
   [b]   i++ ;[/b]
  }
  return result.toString() ;
}

Open in new window


in above code as bolded why we are incrementing by 2(not 3) in the if loop and then incrementing by 1 (not 3 here )next to else loop. Doe the i value increamented in if loop carry over to i++ line(which is next to else loop?)
0
gudii9Author Commented:
package eePackage;

public class Test30 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str2=stringYak("pakyak123ya");
		System.out.println("str2 value is--->"+str2);

	}

	public static String stringYak(String str) {
		  StringBuilder result = new StringBuilder() ;
		  int i = 0 ;
		  int len = str.length() ;
		  
		  while (i < len) {
		  
		      if (i+2 < len && str.charAt(i) == 'y' && str.charAt(i+2) == 'k') {
		          // We've found a yak string
		        i += 2 ;
		      } else {
		          // This is not part of yak string so we should keep it
		          result.append(str.charAt(i)) ;
		      }
		      i++ ;
		  }
		  return result.toString() ;
		}

}

Open in new window


i see i jumped to 5 after i=3 after else loop once entering to if loop as attached.
so i is method local varialbe common across whole method right similar to global across common across whole class?
yakChallenge.jpg
0
krakatoaCommented:
You have code there that satisfies the challenge - it works.

So you are done!

Not quite sure what you mean about 'i' - it's in scope throughout the method call.
0
dpearsonCommented:
in above code as bolded why we are incrementing by 2(not 3) in the if loop and then incrementing by 1 (not 3 here )next to else loop. Does the i value increamented in if loop carry over to i++ line(which is next to else loop?)

Every pass through the loop ends up executing the i++ line - so we always move at least 1 character forward.

So when we find the 'y*k' pattern, we only need to move 2 additional characters forward, so that in total (2+1) we'll end up 3 characters ahead next time through the loop.

So yes this is true:
 
the i value incremented in if loop carry over to i++ line

Doug
0
gudii9Author Commented:
return str.replace(str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y"))+1),"");

Open in new window

in the above code

substring takes 2 integers right one start and other end(excluding last)

str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y")

what is above code doing.

i understand whatever is coming is replaced by ""
please advise
0
krakatoaCommented:
substring takes 2 integers right one start and other end(excluding last)

That's right.

So >>str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y")<<

it starts at the index of "y", and extends FROM THERE PLUS 1 to look for "k", and replace it with nothing.
0
gudii9Author Commented:
what is integer and what is integer 2 here inside the substring method. Please advise
0
krakatoaCommented:
In
str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y"))+1)

Open in new window


str.indexOf("y")

Open in new window

is the first int argument of substring and

str.indexOf("k",str.indexOf("y"))+1

Open in new window

is the second.
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:
import java.io.*;

public class Test {

   public static void main(String args[]) {
     // String Str = new String("Welccomeeeeo to Tutorialspoint.com");
	  String Str = new String("Wa1b2bcaaaaerwfafafa");
      String SubStr1 = new String("Tutorials");
      String SubStr2 = new String("Sutorials");
      System.out.println("length is"+Str.length());

      System.out.print("Found Index 1--:" );
      System.out.println(Str.indexOf( 'o' ));
      System.out.print("Found Index 2--:" );
      System.out.println(Str.indexOf( 'a', 19));
      System.out.print("Found Index 3---:" );
      System.out.println( Str.indexOf( SubStr1 ));
      System.out.print("Found Index 4---:" );
      System.out.println( Str.indexOf( SubStr1, 15 ));
      System.out.print("Found Index 5---:" );
      System.out.println(Str.indexOf( SubStr2 ));
   }
}

Open in new window


i ran above and got below output
length is20
Found Index 1--:-1
Found Index 2--:19
Found Index 3---:-1
Found Index 4---:-1
Found Index 5---:-1
it make perfect sense why i got 19

but indexOf within other indexOf is confusing to me as below
str.indexOf("k",str.indexOf("y"))+1
I am trying to understand what you mean by
extends FROM THERE PLUS 1 to look for "k",
why we have to do plus 1 why we have to extend from there....please advise
Is there is a way to break this program in simple steps and make it independent of index of y if at all possible.
please advise
0
krakatoaCommented:
str.indexOf("k",str.indexOf("y"))+1

this means " tell us the index of "k", but start looking for it from where you found "y".  When that index is obtained, add 1 to it.

After the 1 has been added, give us that finished index number so we can use it as the second parameter for the substring method - (to determine where the search extent ends in the string).
0
gudii9Author Commented:
When that index is obtained, add 1 to it.

This is because we exclude the end index within substring method right
substring(start, end)
where exclude end index
0
krakatoaCommented:
This is because we exclude the end index within substring method right
We don't EXCLUDE the end index. It's used as the end-of-substring marker.

The second argument of substring - (IF two arguments are supplied) - is  exclusive.
0
gudii9Author Commented:
The second argument of substring - (IF two arguments are supplied) - is  exclusive.

I thought we are sending two int arguments to this method. Am i wrong in saying that

str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y"))+1)
0
gudii9Author Commented:
str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y"))+1)

Open in new window

i felt writing like below is better (second int argument within parenthesis )

str.substring(str.indexOf("y"),(str.indexOf("k",str.indexOf("y"))+1) )

am i right?
please advise
0
krakatoaCommented:
Well ok, but you'd have to do this:

 return str.replace(str.substring(str.indexOf("y"),(str.indexOf("k",str.indexOf("y"))+1)),"");

Open in new window

0
krakatoaCommented:
I thought we are sending two int arguments to this method. Am i wrong in saying that

If you mean the substring method, then yes, it is taking 2 arguments.

I was simply pointing out that the API provides two forms of arguments for this method - it can either be called with 1 argument, or with 2. This time we need both. Under OTHER circumstances, just one might be sufficient. Say you want a substring of Hamburger. "Hamburger".substring(3) will give you "burger".
0
krakatoaCommented:
Try to run these examples which show you how substring works :

System.out.println("Hamburger".substring(3));
System.out.println("Hamburger".substring(3,4));
System.out.println("Hamburger".substring(3,7));
System.out.println("Hamburger".substring(3,"Hamburger".indexOf("e","Hamburger".indexOf("b")+1)));

Open in new window


. . .  before you run them, can you tell us what you think each will print out?
0
krakatoaCommented:
This is another one you can analyse :

System.out.println("Give me "+"Hamburger".substring(1,2)+" "+"Hamburger".substring("Hamburger".indexOf("b","Hamburger".indexOf("a")+1),"Hamburger".length()));

Open in new window

0
gudii9Author Commented:
System.out.println("Hamburger".substring(3));----burger
System.out.println("Hamburger".substring(3,4));---b
System.out.println("Hamburger".substring(3,7));--burg
System.out.println("Hamburger".substring(3,"Hamburger".indexOf("e","Hamburger".indexOf("b")+1)));---this i do not know


i think i got solid understanding of substring but my mind going blank with indexOf aling with substrng
0
gudii9Author Commented:
System.out.println("Hamburger".substring(3,"Hamburger".indexOf("e","Hamburger".indexOf("b")+1)));---this i do not know

"Hamburger".substring(3,x)
where x is "Hamburger".indexOf("e","Hamburger".indexOf("b")+1)
0
gudii9Author Commented:
"Hamburger".indexOf("e","Hamburger".indexOf("b")+1)

i supposed to look for index of b after finding first occurence of e right
so after
Hamburger so it is -1

or may be other way

i supposed to look for index of e after finding first occurence of b right
Hamburger so it is 6

If i consider as 6  then

System.out.println("Hamburger".substring(3,"Hamburger".indexOf("e","Hamburger".indexOf("b")+1)));
System.out.println("Hamburger".substring(3,6));---this is  bur
0
gudii9Author Commented:
That's right.

So >>str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y")<<

it starts at the index of "y", and extends FROM THERE PLUS 1 to look for "k", and replace it with nothing.

it has 3 indexOf() which consuses me.

can we break it down to simple steps
0
ozoCommented:
Step 1 = str.indexOf("y")
Step 2 = str.indexOf("k",str.indexOf("y")) =  str.indexOf("k",Step 1)
Step 3 = str.substring(str.indexOf("y"),str.indexOf("k",str.indexOf("y")) = str.substring(Step 1,Step 2)
0
gudii9Author Commented:
Step 2 = str.indexOf("k",str.indexOf("y")) =  str.indexOf("k",Step 1)
says find index of k after finding y?(i am still not completely clear on step2 )

cannot we do step 2 like step 1 instead of making step 2 dependent on step 1

Step 2 = str.indexOf("k")

please advise
0
ozoCommented:
str.indexOf("k",str.indexOf("y"))
depends on the result of str.indexOf("y")
so you cannot do str.indexOf("k",str.indexOf("y")) without doing str.indexOf("y")
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.