0

The following code (from "Cracking the code interview", from Gaale Laakman), shows how to remove duplicate characters in a char array without using a copy of the array to avoid some extra memory use. It re-writes the final characters in the first array with an offset. Since the final array is smaller than the previous one, a null character is set at the position following the final characters, as if to say the array stops there:

    str[tail] = 0;

I was wondering if by doing this the variable "length" of the array gets changed. If not, I don't understand why this example works. Or is this just an example where we would check where is the null character to find the length of the array and don't use the length variable in question?

Here is the whole code:

    public static void removeDuplicates(char[] str) {
        if (str == null) return;
        int len = str.length;
        if (len < 2) return;
        int tail = 1;
        for (int i = 1; i < len; ++i) {
            int j;
            for (j = 0; j < tail; ++j) {
                if (str[i] == str[j]) break;
            }
            if (j == tail) {
                str[tail] = str[i];
                ++tail;
            }
        }
        str[tail] = 0;
    }
sarah vb
  • 149
  • 2
  • 12
  • 1
    Please post code as text, not an image. We would like to be able to copy it in whole or in part. – Ole V.V. Mar 01 '17 at 11:42
  • I voted down. I assume it is an idea of some "academic egghead" and from programming "cave ages" (C or even before that)... Absolutely useless exercise (especially in Java) with enough very bad side-effects. – Vadim Mar 01 '17 at 11:42
  • 1
    to Ole V.V, thanks for the comment, done in edit. – sarah vb Mar 03 '17 at 08:35
  • To Vodem, the code doesn't seem correct for java indeed. I suppose the aim of the exercise is to think memory optimization, for in case the string is very long... but you're right it isn't really realistic – sarah vb Mar 03 '17 at 08:54

3 Answers3

3

It sounds like a question that has been translated from C or C++. In those langauges you use a null character for the end of a string (which in turn is a char array). In Java this does not work; the array never changes its length.

If the caller knows that this null character is inserted, they can use the information of course, and ignore characters after the null. They cannot use the len variable since this only lives inside the method and does not exist when the method returns.

In Java you would usually do:

str = Arrays.copyOf(str, tail);

This would create a new array the right length and copy all the characters (which is what the code example aimed at avoiding).

By the way, I get an ArrayIndexOutOfBoundsException in the line str[tail] = 0; in the end if no duplicates were found. In this case tail is equal to the length of the array and therefore 1 position beyond the last element.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • You're right about the exception. Strangely, a bit further in the book there is an example where the array grows in size (replace spaces by '%20'). And the autor defines values of the array out of bound again. Maybe we don't use same version of java... – sarah vb Mar 03 '17 at 08:34
  • 1
    This has been so in all versions of Java. It sounds mostly like poor translation from C or C++, but there could be other explanations. – Ole V.V. Mar 03 '17 at 08:36
2

An array has a fixed length on creation. In the example they want to save some time by always re-using the same array for every iteration. As it is not possible to shrink the array (as the length is determined on creation), they use a work around, they put a zero at the place where the array should end. When their loop reaches the zero, it knows it is at the conceptual 'end' of the array.

rdhaese
  • 139
  • 8
1

Array are immutable so the length does not change the empty space is filled with null values

public class MainClass {

public static void main(String[] args) {
char[] org={'a','b','b','c'};
System.out.println(org.length);
System.out.println(org);
removeDuplicate(org);
System.out.println(org.length);
   System.out.println(org);

}
public static void removeDuplicate(char[]str){
if(str==null)return;
int len=str.length;
if(len<2)return;
int tail=1;
for(int i=1;i<len;++i){
    int j;
    for(j=0;j<tail;++j){
        if(str[i]==str[j])break;
    }
    if(j==tail){
    str[tail]=str[i];
    ++tail;
    }
}
   str[tail]=0;
  }
 }

**Results**
   4
  abbc
   4
  abc
Joe ONeil
  • 130
  • 1
  • 6
  • Just nitpicking, an array is not immutable in the usual sense of the word since you can overwrite the elements. You are correct, the length cannot be changed. – Ole V.V. Mar 01 '17 at 11:43
  • 1
    since it only puts one null character in the array, the output of 'abbbc' is 'abcc'. This means the println function doesn't consider the null character as the end of the string. – sarah vb Mar 03 '17 at 08:03