Avatar of gudii9
gudii9Flag for United States of America asked on

plusOut java challenge

Hi,
I am working on below challenge
http://codingbat.com/prob/p170829
I tried my code as below
public String plusOut(String str, String word) {
return str.replaceAll(".word.","+word+");
  
}

Open in new window

I am getting below result
Expected      Run            
plusOut("12xy34", "xy") → "++xy++"      "12xy34"      X         
plusOut("12xy34", "1") → "1+++++"      "12xy34"      X         
plusOut("12xy34xyabcxy", "xy") → "++xy++xy+++xy"      "12xy34xyabcxy"      X         
plusOut("abXYabcXYZ", "ab") → "ab++ab++++"      "abXYabcXYZ"      X         
plusOut("abXYabcXYZ", "abc") → "++++abc+++"      "abXYabcXYZ"      X         
plusOut("abXYabcXYZ", "XY") → "++XY+++XY+"      "abXYabcXYZ"      X         
plusOut("abXYxyzXYZ", "XYZ") → "+++++++XYZ"      "abXYxyzXYZ"      X         
plusOut("--++ab", "++") → "++++++"      "--++ab"      X         
plusOut("aaxxxxbb", "xx") → "++xxxx++"      "aaxxxxbb"      X         
plusOut("123123", "3") → "++3++3"      "123123"      X         
other tests

how to  improve my approach, results and design of this challenge. How do i make a graphical venn or flow chart or some other relevant diagram to design it before writing code to decide best strategy?
 Please advise
JavaJava EEProgrammingJava App ServersRegular Expressions

Avatar of undefined
Last Comment
ozo

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
ozo

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.
See how we're fighting big data
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
SOLUTION
Dan Craciun

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.
See how we're fighting big data
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
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.
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.
Dan Craciun

@CEHJ: very nice. Short and easy to understand.

Basically you avoided the problem "you cannot negate a whole word in regex" by using NUL instead of the search string.
ozo

public String plusOut(String str, String word) {
  word="(\\Q"+word.replaceAll("\\+","\\E.\\Q")+"\\E)";
  return str.replaceAll(word+"|.", "+$1").replaceAll("\\+"+word,"$1");
}
krakatoa

Does anyone have an explanation for the result produced by this:

for (int y=0;y<str.length();y++){
      
      if(!(str.indexOf(word,y)==y)){
         str=str.replace(str.charAt(y),'+'); 
      }
      else{y+= (word.length()-1);}
              
  }
  return str;

Open in new window

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
ozo

str.replace(str.charAt(y),'+'); may replace more than one character
krakatoa

Ah yes - I always forget about that behaviour of the method for some reason. My bad, thanks.
CEHJ

You can get the effect you wanted (with actually more efficiency) by doing this sort of thing:
    public String plusOut(String str, String word) {
        StringBuilder sb = new StringBuilder(str);
        int y = 0;

        while (y < sb.length()) {
            if (!(sb.indexOf(word, y) == y)) {
                sb.setCharAt(y, '+');
                y++;
            } else {
                y += word.length();
            }
        }

        return sb.toString();
    }

Open in new window

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

O gosh, yes, thanks CEHJ - I should have gone that route.

Think I've gone bats under the sheer weight of challenges.

 ;)
CEHJ

Moving the call to length() at line 10 and replacing it with a variable would of course be better
krakatoa

I was (incorrectly) mutating String, but, in any event, what I was aiming at was:

public String plusOut(String str, String word) {
  
  for ( int y=0;y<str.length();y++){
      
      if(!(str.indexOf(word,y)==y)){
	  
		 char[] ch = str.toCharArray();
		 ch[y]='+';
		 str = new String(ch); 
      }
      else{y+= (word.length()-1);}
    
  }
  return str;
}

Open in new window


(which I can only defend in a sense by the fact that being iterative rather than esoterically RE etc., may be more digestible for the OP) ;)
Your help has saved me hundreds of hours of internet surfing.
fblack61
CEHJ

Again, you wouldn't call toCharArray() in a loop
krakatoa

Can I ask you for more detail / background on that pls?
CEHJ

Well it's just a case of efficiency and not creating unnecessary allocations. Your code is creating a str.length() number of String instances, plus a str.length() number of char[] (toCharArray does not return the actual array that backs the String, it creates a copy)
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
krakatoa

Right. Important then, particularly if dealing with a larger number of Strings I guess. Would it make a lot of impact at this scale?
CEHJ

No ;)
krakatoa

Thanks. Edifying and concise. ;)

(And seeing as the Q is marked 'abandoned', guess one may as well put the bandwidth to 'best use')

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

public class PlusOutEx {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("value is"+plusOut("12xy34", "xy")); //→ "++xy++"

	}
	
	public static String plusOut(String str, String word) {
		int x=str.indexOf(word);
		System.out.println("x is--->"+x);
		System.out.println("--->"+str.substring(x,x+2));
		return str.replaceAll(str.substring(x,x+2),"++");
		  
		}

}

Open in new window

i wrote as above but that needs to be refined to get opposite effect
ASKER
gudii9

can i tweak my above approach to pass all tests?
ASKER
gudii9

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

trying to see easiest approach
ozo

public String plusOut(String str, String word) {
  String out="";
  String w="";
  for( String p:str.split("\\Q"+word,-1) ){
     out += w;
     out += p.replaceAll(".","+");
     w = word;
  }
  return out;
}

Open in new window

ASKER
gudii9

 for( String p:str.split("\\Q"+word,-1) ){

what is meaning of above line?

\\Q means what?
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
ASKER
gudii9

     if (!(str.indexOf(str.charAt(i)) == idx)) {

what is meaning of above line in below solution

so idx is 2 which makes sense .

so we are checking 2 is equal to charAt(0) and then indexOf not equal?
public class PlusOutEx {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("value is"+plusOut("12xy34", "xy")); //→ "++xy++"

	}
	
	public static String plusOut(String str, String word) {
		StringBuilder sb = new StringBuilder();
		int len = word.length();
		for (int i = 0; i < str.length(); i++) {
			int idx = str.indexOf(word);
			if (!(str.indexOf(str.charAt(i)) == idx)) {
				sb.append("+");
			} else {
			sb.append(word);
			i+= (len - 1);
			}
		}
	        return sb.toString();
	}

}

Open in new window

ASKER
gudii9

charAt 0 is 1
so str.indexOf 1 is 0 which on comparing with idx 2
0==2 is false
so there is ! so false becomes true as
!false is true
then we are appening + to sb as below

sb.append("+");


else why are we doing as below ie appending word to sb

else {
                  sb.append(word);
ASKER
gudii9

as attached i see we are doing + for all other characters apart from word and appending word for else condition

why are we doing below assignment or addition

i+= (len - 1);
falseValue.png
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
gudii9

public String plusOut(String str, String word) {
	for (int y=0;y<str.length();y++){
      
      if(!(str.indexOf(word,y)==y)){
         str=str.replace(str.charAt(y),'+'); 
      }
      else{y+= (word.length()-1);}
              
  }
  return str;

}

Open in new window


above failing below two test cases. How to fix those two failing test cases
Expected      Run            
plusOut("12xy34", "xy") → "++xy++"      "++xy++"      OK         
plusOut("12xy34", "1") → "1+++++"      "1+++++"      OK         
plusOut("12xy34xyabcxy", "xy") → "++xy++xy+++xy"      "++xy++xy+++xy"      OK         
plusOut("abXYabcXYZ", "ab") → "ab++ab++++"      "ab++ab++++"      OK         
plusOut("abXYabcXYZ", "abc") → "++++abc+++"      "++++++++++"      X         
plusOut("abXYabcXYZ", "XY") → "++XY+++XY+"      "++XY+++XY+"      OK         
plusOut("abXYxyzXYZ", "XYZ") → "+++++++XYZ"      "++++++++++"      X         
plusOut("--++ab", "++") → "++++++"      "++++++"      OK         
plusOut("aaxxxxbb", "xx") → "++xxxx++"      "++xxxx++"      OK         
plusOut("123123", "3") → "++3++3"      "++3++3"      OK         
other tests
OK      
ASKER
gudii9

if(!(str.indexOf(word,y)==y)){

what is meaning of above line. Please advise
http://www.tutorialspoint.com/java/java_string_indexof.htm

so we are checking indexOf xy starting at y index is same as y which is 0 for first iteration?
falseValue2.png
ASKER
gudii9

so after y=2 we are jumping to y=4 as attached to skip xy right?
falseValue3.png
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
ozo

str.replace(str.charAt(y),'+'); may replace more than one character
ASKER
gudii9

str.replace(str.charAt(y),'+'); may replace more than one character

so due to above reason it is failing those two tests?
how to fix below solution then.
public String plusOut(String str, String word) {
	for (int y=0;y<str.length();y++){
      
      if(!(str.indexOf(word,y)==y)){
         str=str.replace(str.charAt(y),'+'); 
      }
      else{y+= (word.length()-1);}
              
  }
  return str;

}

Open in new window


please advise
ozo

public String plusOut(String str, String word) {
  for (int y=0;y<str.length();y++){
      
      if(!(str.indexOf(word,y)==y)){
         str=str.replaceFirst("\\Q"+str.charAt(y),"+"); 
      }
      else{y+= (word.length()-1);}
              
  }
  return str;
}

Open in new window

But that would still fail if one of the tests was plusOut("xyx", "xy")
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ozo

public String plusOut(String str, String word) {
  for (int y=0;y<str.length();y++){
      
      if(!(str.indexOf(word,y)==y)){
         str=str.replaceFirst("(.{"+y+"}).","$1+"); 
      }
      else{y+= (word.length()-1);}
              
  }
  return str;
}

Open in new window

ASKER
gudii9

public String plusOut(String str, String word) {
  for (int y=0;y<str.length();y++){
      
      if(!(str.indexOf(word,y)==y)){
         str=str.replaceFirst("(.{"+y+"}).","$1+"); 
      }
      else{y+= (word.length()-1);}
              
  }
  return str;
}

Open in new window


above passed all tests
ASKER
gudii9

what is meaning of below 3 lines . please advise

 
      if(!(str.indexOf(word,y)==y)){
         str=str.replaceFirst("(.{"+y+"}).","$1+");
     
      else{y+= (word.length()-1);}
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
ASKER
gudii9

not sure why code comments and quotes are missing in experts exchange now.

Any way i like below solution after debugging more after refrreing indexOf, replace, charAt functions as below
http://www.tutorialspoint.com/java/java_string_replace.htm
http://www.tutorialspoint.com/java/java_string_charat.htm
http://www.tutorialspoint.com/java/java_string_indexof.htm


public class PlusOutEx {

      /**
       * @param args
       */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println("value is" + plusOut("12xy34", "xy")); // → "++xy++"

      }

      public static String plusOut(String str, String word) {
            for (int y = 0; y < str.length(); y++) {

                  if (!(str.indexOf(word, y) == y)) {
                        str = str.replace(str.charAt(y), '+');
                  } else {
                        y += (word.length() - 1);
                        System.out.println("hi");
                  }

            }
            return str;

      }

}


But how you remember all above methods and what arguments they take on top of the head all the time?

so we are basically checking if 1st occurence of word does nto match the y position we are safely making that character as +
else we are jumping to position of end of that word occurence within str.

But i wonder why this approach is not good has more allocations etc ? Not clear why it created too many strings etc. How many strings it creates in total?



Well it's just a case of efficiency and not creating unnecessary allocations. Your code is creating a str.length() number of String instances, plus a str.length() number of char[] (toCharArray does not return the actual array that backs the String, it creates a copy)




public String plusOut(String str, String word) {
 
  for ( int y=0;y<str.length();y++){
     
      if(!(str.indexOf(word,y)==y)){
        
             char[] ch = str.toCharArray();
             ch[y]='+';
             str = new String(ch);
      }
      else{y+= (word.length()-1);}
   
  }
  return str;
}
ASKER
gudii9

i forgot attachment
debugMore.png
ozo

how you remember all above method
I don't.
I look them up on publicly accessible on-line documentation.
And when I'm not sure where the documentation is, I use a search engine.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.