CodingBat: Java. String-3, Part II


For further help with Coding Bat (Java), please check out my books. I am also available for tutoring.


sameEnds:

public String sameEnds(String string) {
	String result = "";
	int len = string.length();
	for (int i = 0; i <= len / 2; i++)
		for (int j = len / 2; j < len; j++)
			if (string.substring(0, i).equals(string.substring(j)))
				result = string.substring(0, i);
	return result;
}

The variable in line 3 makes the code a bit more compact.

mirrorEnds:

public String mirrorEnds(String string) {
	String result = "";
	int len = string.length();
	for (int i = 0, j = len - 1; i < len; i++, j--)
		if (string.charAt(i) == string.charAt(j))
			result += string.charAt(i);
		else break;
	return result;
}

maxBlock:

public int maxBlock(String str) {
	int max = 0;
	for (int i = 0; i < str.length(); i++) {
		int count = 0;
		for (int j = i; j < str.length(); j++) {
			if (str.charAt(i) == str.charAt(j)) count++;
			else break;
		}
		if (count > max) max = count;
	}
	return max;
}

sumNumbers:

public int sumNumbers(String str) {
		int sum = 0;
		for (int i = 0; i < str.length(); i++) {
			if (Character.isDigit(str.charAt(i))) {
				int count = 0;
				for (int j = i; j < str.length(); j++) {
					if (Character.isDigit(str.charAt(j))) count++;
					else break;
				}
				sum += Integer.parseInt(str.substring(i, i + count));
				i += count;
			}
		}
		return sum;
}

notReplace:

public String notReplace(String str) {
	String result = "";
	str = " " + str + "  "; // avoid issues with corner cases
	for (int i = 0; i < str.length() - 2; i++) {
		if (str.charAt(i) == 'i') {
			if (str.charAt(i + 1) == 's'
					&& !Character.isLetter(str.charAt(i + 2))
					&& !Character.isLetter(str.charAt(i - 1))) {
				result += "is not";
				i += 1;
			} else result += "i";
		} else result += str.charAt(i);
	}
	return result.substring(1);
}

For further help with Coding Bat (Java), please check out my books. I am also available for tutoring.


26 thoughts on “CodingBat: Java. String-3, Part II

  1. Val

    I like your code to solve the corner cases. However, I am confused about corner cases. I was wondering when do I need to add your corner cases code? If I have a compiler available, then I will know to just check. If I’m at a white board for an interview, I will not know when to use your corner case code.

    Reply
    1. Gregor Ulm Post author

      A compiler won’t catch all corner cases, so I wouldn’t rely on that. The situation is a lot worse in C, though.

      I’d say it’s a good habit to consider corner cases. If you want to increase your level of confidence in the code you’re writing, then add some unit tests or, better, write properties for a tool like QuickCheck, which will generate test cases for you. The latter is incredibly powerful, and not often used in practice.

      Reply
  2. Charlie

    Regarding the “notReplace” answer, could you please explain why your answer does not leave off the last character in the given string? For example, if you have the string “abcde” and add a space at the beginning and end (per your answer), you have a string length of 7. The loop only continues if “i” is less than 7-2(i.e., 5), which would correspond to stopping at letter “d”. I must be missing something.

    Thanks,

    Reply
    1. Gregor Ulm Post author

      Charlie, I’m not adding one space character at the end of the string, but two. I hope this clears up your confusion.

      Reply
  3. Chris

    I am a bloody beginner in Java, but I tried solving the ‘maxBlock’ function with only one loop. Just thought I’d share, since you previously emphasized that the String-3 instructions (use 2 loops) baffled you and you showed that most stuff can be done with one loop.

    I am not saying this is nicer or whatever, just that has one less loop.

    Link: http://pastebin.com/3mEzGe2M

    Reply
  4. Earl

    A question about mirrorEnds – could you explain why this code:
    for(int i=0; i=0; j–)
    instead of
    for (int i = 0, j = len – 1; i < len; i++, j–)
    doesn't work? To me it looks like it does the same, but the results are different.

    Reply
  5. Earl

    The code is not showing correctly, what I meant was
    for(int i=0; i is less than len; i plus plus) and then another loop: for(int j=len-1; j is greater or equal to 0; j minus minus).

    Reply
    1. Gregor Ulm Post author

      The code I’ve written uses one loop. It’s beyond me why your code, which uses a nested for-loop, “looks like it does the same”. Are you sure you understand how a loop inside a loop is evaluated?

      Reply
  6. Laia

    Hi Gregor,
    Can you help me? I have tried to resolved the problem with this code that I wrote:

    public static String sameEnds ( String string ) {
    int meitat = string.length()/2;
    for ( int i = 1 ; i <= meitat ; i++ ) {
    if ( string.substring(0, i).equals( string.substring(string.length()-i) ) ) {
    if (!( i < meitat && string.substring(0, i+1).equals( string.substring(string.length()-i-1) ) ))
    return string.substring(0, i);
    }
    }
    return "";
    }

    It works for the firsts tests, but it fails at the "other tests" and I can't find what I'm doing wrong.

    Reply
  7. William

    Hi, just thought I’d add my answer to sameEnds, seems like it was a different take on it. I’m a java noob so I was just wondering if this is something I should be aiming to write or if it’s somehow inefficient or something. Any pointers would be great ^_^

    public String sameEnds(String string) {
    for(int i=string.length()/2;i>0;i–){
    if(string.substring(0,i).equals(string.substring(string.length()-i)))
    return string.substring(0,i);
    }
    return “”;
    }

    Reply
  8. Ambarish

    for sumNumbers below is the 0(n) time solution

    public int sumNumbers(String str) {
    int result = 0;
    int factor = 1;
    for (int i = str.length() – 1; i >= 0; i–) {
    if (Character.isDigit(str.charAt(i))) {
    result = result + (str.charAt(i) – ‘0’) * factor;
    factor = factor * 10;
    } else {
    factor = 1;
    }
    }
    return result;
    }

    Reply
  9. Ambarish

    for sumEnds below is the O(n) time solution

    public String sameEnds(String string) {
    int len = string.length();
    String result = “”;
    for (int i = 0; i < len/2; i++) {
    if (string.substring(0, i+1).equals(string.substring(len-1-i, len))) {
    result = string.substring(0, i+1);
    }
    }
    return result;
    }

    Reply
  10. OldWhovian

    My solution for sumNumbers:

    public int sumNumbers(String str) {
    String[] arr = str.split(“[^0-9]”);
    int count = 0;
    for(String s : arr){
    if(s.equals(“”))
    continue;
    count += Integer.parseInt(s);
    }
    return count;
    }

    Thought using a regex split would be a time saver, and it was.

    Reply
  11. Nidhi Bhushan

    I see that you have used two for loops. Below is what I wrote with a single loop and I think it would work for all cases:

    public String sameEnds(String string)
    {
    int h = string.length()/2;
    while(h>=0)
    {
    if(string.substring(0,h).equals(string.substring(string.length()-h)))
    return string.substring(0,h);
    –h;
    }
    return “”;
    }

    Let me know if I missed out anything.
    Glad to comment on this site for the first time! hello to all folks there 🙂

    Reply
  12. Some Guy

    Using Regex negative look-ahead and negative look-behind to solve notReplace:

    public String notReplace(String str) {
    return str.replaceAll(“(?<!\\w)is(?!\\w)","is not");
    }

    Reply
    1. Gregor Ulm Post author

      Regular expressions are not part of Coding Bat. Recall that those exercises are for people to gain basic programming proficiency.

      Reply
  13. Rickyg

    Looks like sameEnds can be done with one for Loop. Also a few people have already commented about it using one for or while loop. Mine is almost the same as well. It should work as well.

    public String sameEnds(String string) {
    String newStr = "";
    for (int i=0; i<string.length()/2; i++)
    if (string.substring(0,i+1).equals(string.substring(string.length()-1-i)))
    newStr = string.substring(0,i+1);
    return newStr;
    }

    Reply
  14. Rickyg

    Mirror Ends can be done with one looping variable. I tried with while loop.

    public String mirrorEnds(String string) {
    int i = 0;
    while (i<string.length()){
    if (string.charAt(i)==string.charAt(string.length()-1-i)){
    i++;
    } else break;
    }
    return string.substring(0,i);
    }

    Reply
  15. Rickyg

    I liked your way of catching the end cases. However, I think your solution to NOTREPLACE looks too complicated. I did it this way.

    public String notReplace(String str) {
    str = "*"+str+"*";
    int i = 0;
    while (str.indexOf("is",i)>-1){
    int ind = str.indexOf ("is",i);
    if (!Character.isLetter(str.charAt(ind-1))&& (!Character.isLetter(str.charAt(ind+2)))){
    str = str.substring(0,ind)+"is not"+str.substring(ind+2);
    }
    i=ind+2;
    }
    return(str.substring(1,str.length()-1));
    }

    Reply
  16. Mike

    sameEnds with only one loop

    public String sameEnds(String string) {
    String temp = “”;
    for (int i=1; i < (1+string.length()/2); i++) {
    if (string.substring(0,i).equals(string.substring(string.length()-i, string.length()))) {
    temp = string.substring(0,i);
    }
    }
    return temp;
    }

    Reply
  17. WOJTEK

    My solution

    public String sameEnds(String string) {
    String result=””;
    for(int i=1; i<=string.length()/2; i++)
    if(string.endsWith(string.substring(0,i))) result = string.substring(0,i);
    return result;
    }

    Reply
  18. WOJTEK

    My solution

    public String mirrorEnds(String string) {
    String result = “”;
    int end = string.length()-1;
    int i = 0;
    while(i<=string.length()-1&&(string.charAt(i)==string.charAt(end-i))){
    result += string.charAt(i);
    i++;
    }
    return result;
    }

    Reply
  19. Mikhail

    //String-3 > notReplace solution with StringBuilder class

    public String notReplace(String str) {

    StringBuilder temp = new StringBuilder(” “);
    temp.append(str);
    temp.append(” “);

    for (int i = 1; i < temp.length() – 2; i++) {
    if ((temp.substring(i, i + 2).equals("is")
    && !Character.isLetter(temp.charAt(i – 1))
    && !Character.isLetter(temp.charAt(i + 2)))) {
    temp.replace(i, i + 2, "is not");
    }
    }
    return temp.toString().trim();
    }

    Reply

Leave a Reply to WOJTEK Cancel reply

Your email address will not be published. Required fields are marked *

Spammer prevention; the answer is an integer: * Time limit is exhausted. Please reload CAPTCHA.

This site uses Akismet to reduce spam. Learn how your comment data is processed.