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
ASKER CERTIFIED SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
SOLUTION
Avatar of Dan Craciun
Dan Craciun
Flag of Romania image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
SOLUTION
Avatar of awking00
awking00
Flag of United States of America image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
Avatar of Dan Craciun
Dan Craciun
Flag of Romania image

@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.
Avatar of ozo
ozo
Flag of United States of America image

public String plusOut(String str, String word) {
  word="(\\Q"+word.replaceAll("\\+","\\E.\\Q")+"\\E)";
  return str.replaceAll(word+"|.", "+$1").replaceAll("\\+"+word,"$1");
}
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

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

Avatar of ozo
ozo
Flag of United States of America image

str.replace(str.charAt(y),'+'); may replace more than one character
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

Ah yes - I always forget about that behaviour of the method for some reason. My bad, thanks.
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

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

Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

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

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

 ;)
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Moving the call to length() at line 10 and replacing it with a variable would of course be better
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

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) ;)
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Again, you wouldn't call toCharArray() in a loop
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

Can I ask you for more detail / background on that pls?
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

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)
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

Right. Important then, particularly if dealing with a larger number of Strings I guess. Would it make a lot of impact at this scale?
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

No ;)
Avatar of krakatoa
krakatoa
Flag of United Kingdom of Great Britain and Northern Ireland image

Thanks. Edifying and concise. ;)

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

;)
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

can i tweak my above approach to pass all tests?
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

please advise
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

trying to see easiest approach
Avatar of ozo
ozo
Flag of United States of America image

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

Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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

what is meaning of above line?

\\Q means what?
please advise
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

     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

Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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);
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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      
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

so after y=2 we are jumping to y=4 as attached to skip xy right?
falseValue3.png
Avatar of ozo
ozo
Flag of United States of America image

str.replace(str.charAt(y),'+'); may replace more than one character
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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
Avatar of ozo
ozo
Flag of United States of America image

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")
Avatar of ozo
ozo
Flag of United States of America image

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

Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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);}
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

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;
}
Avatar of gudii9
gudii9
Flag of United States of America image

ASKER

i forgot attachment
debugMore.png
Avatar of ozo
ozo
Flag of United States of America image

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

Java is a platform-independent, object-oriented programming language and run-time environment, designed to have as few implementation dependencies as possible such that developers can write one set of code across all platforms using libraries. Most devices will not run Java natively, and require a run-time component to be installed in order to execute a Java program.

102K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo