Avatar of gudii9
gudii9
Flag for United States of America asked on

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"
JavaJava EEProgramming Languages-Other

Avatar of undefined
Last Comment
ozo

8/22/2022 - Mon
ozo

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

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
krakatoa

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

Open in new window

gudii9

ASKER
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
Your help has saved me hundreds of hours of internet surfing.
fblack61
ozo

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?
gudii9

ASKER
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
dpearson

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

Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
gudii9

ASKER
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

gudii9

ASKER
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
krakatoa

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.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
gudii9

ASKER
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

gudii9

ASKER
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?)
gudii9

ASKER
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
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
krakatoa

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

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
gudii9

ASKER
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
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
krakatoa

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

ASKER
what is integer and what is integer 2 here inside the substring method. Please advise
ASKER CERTIFIED SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
gudii9

ASKER
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
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
krakatoa

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

ASKER
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
krakatoa

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.
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
gudii9

ASKER
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)
gudii9

ASKER
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
krakatoa

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

Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
krakatoa

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

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?
krakatoa

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

All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
gudii9

ASKER
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
gudii9

ASKER
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)
gudii9

ASKER
"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
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
gudii9

ASKER
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
ozo

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

ASKER
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
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.