'CodingBat - Java - Warmup-2 - "stringYak" algorithm

I'm presently trying to understand a particular algorithm at the CodingBat platform.

Here's the problem presented by CodingBat:

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

Example outputs:

stringYak("yakpak") → "pak"

stringYak("pakyak") → "pak"

stringYak("yak123ya") → "123ya"*

Here's the official code solution:

public String stringYak(String str) {
  String result = "";
  
  for (int i=0; i<str.length(); i++) {
    // Look for i starting a "yak" -- advance i in that case
    if (i+2<str.length() && str.charAt(i)=='y' && str.charAt(i+2)=='k') {
      i =  i + 2;
    } else { // Otherwise do the normal append
      result = result + str.charAt(i);
    }
  }
  
  return result;
}

I can't make sense of this line of code below. Following the logic, result would only return the character at the index, not the remaining string.

result = result + str.charAt(i);

To me it would make better sense if the code was presented like this below, where the substring function would return the letter of the index and the remaining string afterwards:

result = result + str.substring(i);

What am I missing? Any feedback from anyone would be greatly helpful and thank you for your valuable time.



Solution 1:[1]

String concatenation

In order to be on the same page, let's recap how string concatenation works.

When at least one of the operands in the expression with plus sign + is an instance of String, plus sign will be interpreted a string concatenation operator. And the result of the execution of the expression will be a new string created by appending the right operand (or its string representation) to the left operand (or its string representation).

String str = "allow";
char ch = 'h';
Object obj = new Object();
    
System.out.println(ch + str);      // prints "hallow"
System.out.println("test " + obj); // prints "test java.lang.Object@16b98e56"

Explanation of the code-logic

That said, I guess you will agree that this statement concatenates a character at position i in the str to the resulting string and assigns the result of concatenation to the same variable result:

result = result + str.charAt(i);

The condition in the code provided by coding bat ensures whether the index i+2 is valid and then checks characters at indices i and i+2. If they are equal to y and k respectively. If that is not the case, the character will be appended to the resulting string. Athowise it will be discarded and the indexed gets incremented by 2 in order to skip the whole group of characters that constitute "yak" (with a which can be an arbitrary symbol).

So the resulting string is being constructed in the loop character by characters.

Flavors of substring()

Method substring() is overload, there are two flavors of it.

A version that expects two argument: the starting index inclusive, the ending index, exclusivesubstring(int, int).

And you can use it to achieve the same result:

// an equivalent of result = result + str.charAt(i);

result = result + str.substring(i, i + 1);

Another version of this method, that expects one argument will not be useful here. Because the result returned by str.substring(i) will be not a string containing a single character, but a substring staring from the given index, i.e. encompassing all the characters until the end of the string as documentation of substring(int) states:

public String substring(int beginIndex)

Returns a string that is a substring of this string. The substring begins with the character at the specified index and extends to the end of this string.

Examples:

 "unhappy".substring(2) returns "happy"
 "Harbison".substring(3) returns "bison"
 "emptiness".substring(9) returns "" (an empty string)

Side note:

  • This coding-problem was introduced in order to master the basic knowledge of loops and string-operations. But actually the simplest to solve this problem is by using method replaceAll() that expects a regular expression and a replacement-string:
return str.repalaceAll("y.k", "");

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1