1

While I was creating a program to compress a string I ran into this strange problem, I will paste the code snippets with their outputs, I would like someone to clearly explain why this is happening.

The first code snippet: here if same letter appears consecutively, then the successive occurrences of the letter is replaced by the total count of same letters. Ex: aaabbb should be written as a3b3.

public static String compress(String str){
    String compressed = "";
    char prev = str.charAt(0);
    int count = 1;
    for (int i = 1; i < str.length(); i++) {
        char curr = str.charAt(i);
        if (curr == prev) { // in case curr is equal to prev
            count++;
        } else { // in case curr is not equal to prev
            //compressed=compressed+prev+count;
            compressed+=prev+count;    // Shorthand used here
            count=1;
            prev=curr;
        }
    }
    compressed=compressed+prev+count; // Shorthand not used
    System.out.println(compressed);
    return compressed;
}

the output for this above code when inputted with aabbccaabbccaabbccaabb is 99100101991001019910010199b2, observe the last two elements of the output, this is because outside the loop, shorthand is not used. If I write the expression as compressed = compressed +prev+count inside the loop, I'll get the intended output.

I thought this output is because the operation is messing with the address of the String. But the next code confused me again.

    String prev= "abc";
    String curr = "def";
    String result="";

    result+=prev+curr;
    System.out.println(result);

I think this is because the right hand operation is performing an ASCII addition, I cannot come to a conclusion, can anyone clarify.

I am sleep deprived and hence I am not able to come to a conclusion, hence asking someone to clarify my trivial doubt.

Vij
  • 85
  • 11

4 Answers4

2

It has nothing to do with the reference. When you did prev+count ascii value of the character in prev is added with the integer count. In this case :

ascii of "a" is 97, and it occurred twice... so 97 +2 = 99 ..
ascii of "b" is 98, and it occurred twice... so 98 +2 = 100 ..
ascii of "c" is 99, and it occurred twice... so 99 +2 = 101 ..
that's why the output is 99100101991001019910010199100

try this : compressed+=(""+prev)+count; // Shorthand used here

In this case, or in compressed+=""+prev+count case, since the operation happens from left to right, the + operator is applied on a string ("") and char(prev) and behaves like append and also returns a string. The resulting string is then appened with another int (prev)

A better way is using a StringBuilder

raj
  • 3,769
  • 4
  • 25
  • 43
  • yes with just ""+prev+count will resolve the issue, but my doubt is why is it actually behaving so with += ? Do you have an explanation? – Vij Jul 23 '14 at 09:33
  • Raj, yes that is it. Thanks for the answer. As I said, sleep deprivation didn't help my cause. Yes, I have written this same program using stringbuilder and append method as well, was just trying out using String. – Vij Jul 23 '14 at 09:37
1

Take a look at this subject and at JLS 15.18.1 section :

You see this behavior as a result of the combination of operator precedence and string conversion.

JLS 15.18.1 states:

If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.

Therefore the right hand operands in your first expression are implicitly converted to string: string = string + ((char)65) + 5;

For the second expression however string += ((char)65) + 5; the += compound assignment operator has to be considered along with +. Since += is weaker than +, the + operator is evaluated first. There we have a char and an int which results in a binary numeric promotion to int. Only then += is evaluated, but at this time the result of the expression involving the + operator has already been evaluated.

Community
  • 1
  • 1
ssssteffff
  • 964
  • 4
  • 16
0

Whenever you add a char to an int in java first it converts the character into its equivalent ASCII value and then adds it to the integer

eg suppose the following scenario ,

char c = 'a'; // ASCII value of 'a' is 97

int i = c + 5 ; // result will be 97 + 5 = 102

I think this answers your first half question

Now the Second part ,

Whenever you use the shorthand operator in Java the expression at right hand side is evaluated first.

Hence , for expresion

result += prev + curr it is evaluated as

result = result + (prev + curr);

Therefore ,

result+=prev+curr; // Here first it appends "abc" with "def" and then the resultant "abcdef" is appended to as result .
Shubhang Malviya
  • 1,525
  • 11
  • 17
  • Ya agree with you shubhang, the second expression has no conflict because both the operands are of the same datatype and they are String. In the first expression since there is Character and integer, ASCII conversion is happening – Vij Jul 23 '14 at 10:01
0

you can convert your charater value "prev" to string and than append count to it.

compressed += Character.toString(prev) + count;

Vishal
  • 1
  • 1