Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

stringclean challenge

Hi,

I am working on below challenge.
http://codingbat.com/prob/p104029
Psedo code:
1. check the string if length 0  or 1 then retun same str
2.else return string by removing duplicates

I wrote my code as below and not passing all tests
public String stringClean(String str) {
    if(str.length()==0||str.length()==1){
      return str;
    }
    else if(str.charAt(0)==str.charAt(1)){
      return str.charAt(0)+stringClean(str.substring(2));
    }
    else return null;
}

Open in new window


Expected      Run            
stringClean("yyzzza") → "yza"      "yznull"      X      
stringClean("abbbcdd") → "abcd"      null      X      
stringClean("Hello") → "Helo"      null      X      
stringClean("XXabcYY") → "XabcY"      "Xnull"      X      
stringClean("112ab445") → "12ab45"      "1null"      X      
stringClean("Hello Bookkeeper") → "Helo Bokeper"      null      X      
other tests
X      


Any improvements or alternate approaches?      

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

Line 8 of your code returns null. That won't work. You have to return a String.
Line 6 of your code  
      return str.charAt(0)+stringClean(str.substring(2));

Open in new window

 does what step 2 of your pseudo code describes. But, if there is more than two identical adjacent characters, then your code won't know about it. For example,  consider the String  "zzzawq".  The first "z" will be str.charAt(0)  .  You removed the second "z".  Next you call stringClean("zawq") but no knowledge of the first two z's was passed. So, the third "z" will not be removed.
Avatar of gudii9

ASKER

public String stringClean(String str) {
    if(str.length()<1){
      return str;
    }
    else if(str.charAt(0)==str.charAt(1)){
      return str.charAt(0)+stringClean(str.substring(2));
    }
    else return str.charAt(0)+stringClean(str.substring(1));
}

Open in new window


above failse some tests
Avatar of gudii9

ASKER

Expected      Run            
stringClean("yyzzza") → "yza"      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 1 (line number:5)      X      
stringClean("abbbcdd") → "abcd"      "abbcd"      X      
stringClean("Hello") → "Helo"      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 1 (line number:5)      X      
stringClean("XXabcYY") → "XabcY"      "XabcY"      OK      
stringClean("112ab445") → "12ab45"      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 1 (line number:5)      X      
stringClean("Hello Bookkeeper") → "Helo Bokeper"      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 1 (line number:5)      X      
other tests
X      
Your progress graph for this problem
ASKER CERTIFIED SOLUTION
Avatar of rrz
rrz
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

public String stringClean(String str) {
    if(str.length()<2){
      return str;
    }
    else if(str.charAt(0)==str.charAt(1)){
      return str.charAt(0)+stringClean(str.substring(2));
    }
    else return str.charAt(0)+stringClean(str.substring(1));
}

Open in new window


above fails few
Expected      Run            
stringClean("yyzzza") → "yza"      "yzza"      X      
stringClean("abbbcdd") → "abcd"      "abbcd"      X      
stringClean("Hello") → "Helo"      "Helo"      OK      
stringClean("XXabcYY") → "XabcY"      "XabcY"      OK      
stringClean("112ab445") → "12ab45"      "12ab45"      OK      
stringClean("Hello Bookkeeper") → "Helo Bokeper"      "Helo Bokeper"      OK      
other tests
X      
Your progress graph for this problem


please advise
Avatar of gudii9

ASKER

public String stringClean(String str) {
    if(str.length()<2){
      return str;
    }
    else if(str.charAt(0)==str.charAt(1)){
      return stringClean(str.substring(1));
    }
    else {
      return str.charAt(0)+stringClean(str.substring(1));
    }
}

Open in new window


above passes all tests.

any improvements or alternate approaches?

how above approach different from below


public String stringClean(String str) {
    if(str.length()<2){
      return str;
    }
    if(str.charAt(0)==str.charAt(1)){
      return stringClean(str.substring(1));
    }
    else {
      return str.charAt(0)+stringClean(str.substring(1));
    }
}

Open in new window


above is preferred or below in case of this challenge or in general?
Avatar of gudii9

ASKER

both passes all tests
As you know by now, there are many ways Java can accomplish the same task. Consider that rather than comparing characters, why not replace first character in the rest of the string with "" (empty string) then recursively pass in the substring starting at the next index until the string length is less than 2 -
if (str.length() < 2 { return str; }
else return str.charAt(0) + str.substring(1).replaceAll(str.charAt(0), "");
any improvements or alternate approaches?
No, your code is good.
above is preferred or below in case of this challenge or in general?
In this case the use of the else word is optional because the flow is controlled by the return statements. You can write your code in a way that makes sense to you(and the compiler). But, you should consider readability.  A lot of times we write code and come back to it years later. It is frustrating not being able to understand ones own code.
Avatar of gudii9

ASKER

public String stringClean(String str) {
   if (str.length() < 2) { 
     return str; 
     
   }
else
{
  return str.charAt(0) + str.substring(1).replaceAll(str.charAt(0), "");
}
}

Open in new window


above gives below error
Compile problems:


Error:      return str.charAt(0) + str.substring(1).replaceAll(str.charAt(0), "");
                                              ^^^^^^^^^^
The method replaceAll(String, String) in the type String is not applicable for the arguments (char, String)


see Example Code to help with compile problems

please advise
Avatar of gudii9

ASKER

public String stringClean(String str) {
  if (str.length() < 2){ 
    return str;
    
  }
  if (str.charAt(0) == str.charAt(1))
    {
      return stringClean(str.substring(1));
      
    }
  else
   { 
     return str.charAt(0) + stringClean(str.substring(1));
     
   }
}

Open in new window


above passes all tests. any improvements or alternate approaches?
Sorry about the compile error. The replaceAll function requires a String for the first parameter and the str.charAt(0) returns a char. Convert the char to a String using the Character.toString() method and it will work. I've split the steps up so you can see what each method is doing.
public static String stringClean(String str) {
	if (str.length() < 2) { 
	     return str;
	} else {
	     String c = Character.toString(str.charAt(0));
	     String s = str.replaceAll(c, "");
	     return c + stringClean(s.substring(1));
	}
}

Open in new window

Avatar of gudii9

ASKER

 else {
	     String c = Character.toString(str.charAt(0));
	     String s = str.replaceAll(c, "");
	     return c + stringClean(s.substring(1));
	}

Open in new window


are we replacing everytime each character with ""?
are not we supposed to do above only if there is repetition of same character as a clean up activity?
Avatar of gudii9

ASKER

public static String stringClean(String str) {
	if (str.length() < 2) { 
	     return str;
	} else {
	     String c = Character.toString(str.charAt(0));
	     String s = str.replaceAll(c, "");
	     return c + stringClean(s.substring(1));
	}
}

Open in new window


above giving below error


Error:Bad code
Common problems: code should not use println or class or static or exceptions

please advise
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

public String stringClean(String str) {
	if (str.length() < 2) { 
	     return str;
	} else {
	     String c = Character.toString(str.charAt(0));
	     String s = str.replaceAll(c, "");
	     return c + stringClean(s.substring(1));
	}
}

Open in new window



above gives below error

Expected      Run            
stringClean("yyzzza") → "yza"      "yz"      X      
stringClean("abbbcdd") → "abcd"      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: -1 (line number:7)      X      
stringClean("Hello") → "Helo"      "Hl"      X      
stringClean("XXabcYY") → "XabcY"      Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: -1 (line number:7)      X      
stringClean("112ab445") → "12ab45"      "1a4"      X      
stringClean("Hello Bookkeeper") → "Helo Bokeper"      "Hl oker"      X      
other tests

please advise
Avatar of gudii9

ASKER

why we chose only c why not z or x etc?


public static String stringClean(String str) {
      if (str.length() < 2) {
           return str;
      } else {
           String c = Character.toString(str.charAt(0));
           String s = str.replaceAll(c, "");
           return c + stringClean(s.substring(1));
      }
}



>>are we replacing everytime each character with ""?
  are not we supposed to do above only if there is repetition of same character as a clean up activity?<<
 c is the first character as a String, So replaceAll() replaces all of those characters with an empty string but you return the character c +  a new result for stringClean passing in a substring that begins with a new character. code]
You can call it anything you like -
String thisIsTheStringThatRepresentsTheFirstCharacterInTheStringThatIWantToKeep = Character.toString(str.charAt(0));
String s = str.replaceAll("thisIsTheStringThatRepresentsTheFirstCharacterInTheStringThatIWantToKeep","");
return thisIsTheStringThatRepresentsTheFirstCharacterInTheStringThatIWantToKeep + stringClean(s.substring(1));
Avatar of gudii9

ASKER

is just variable name not the character we chose from str.

public String stringClean(String str) {
	if (str.length() < 2) { 
	     return str;
	} else {
	     String c = Character.toString(str.charAt(0));
	     String s = str.replaceAll(c, "");
	     return c + stringClean(s.substring(1));
	}
}

Open in new window



Expected

Run



stringClean("yyzzza") → "yza" "yz" X  
stringClean("abbbcdd") → "abcd" Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: -1 (line number:7) X  
stringClean("Hello") → "Helo" "Hl" X  
stringClean("XXabcYY") → "XabcY" Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: -1 (line number:7) X  
stringClean("112ab445") → "12ab45" "1a4" X  
stringClean("Hello Bookkeeper") → "Helo Bokeper" "Hl oker" X  

other tests
 X
above fail belw tests. please advise
@awking00, you better rethink your code. The  replaceAll  method isn't helpful for this challenge. You only want to remove adjacent chars.
line 7  
	     return c + stringClean(s.substring(1));

Open in new window

should be
	     return c + stringClean(s);

Open in new window

after making that change, you will see my point above.
Wow! I totally misread the challenge :-( Thanks, rrz, for pointing out the error of my ways.
@awking00, I have been there. I think we all have been there.
Avatar of gudii9

ASKER

How to fix above code to make work in experts exchange?
How to fix above code to make work in experts exchange?
Are you referring to the code that awking00 posted? If yes, then I don't see how. The replaceAll method will remove all the characters of the String that match the supplied argument  instead of just the  adjacent characters.
Avatar of gudii9

ASKER

Me too not sure