В Java, изменить размер массива символов с нулевым символом

Следующий код (из "Взлома кода интервью", от Gaale Laakman), показывает, как удалить повторяющиеся символы в массиве символов без использования копии массива, чтобы избежать некоторого дополнительного использования памяти. Он перезаписывает последние символы в первом массиве со смещением. Поскольку последний массив меньше предыдущего, в позиции, следующей за последними символами, устанавливается нулевой символ, как если бы сказать, что массив останавливается на этом:

    str[tail] = 0;

Мне было интересно, если при этом изменяется переменная "длина" массива. Если нет, я не понимаю, почему этот пример работает. Или это просто пример, где мы проверяем, где находится нулевой символ, чтобы найти длину массива, и не используем соответствующую переменную длины?

Вот весь код:

    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;
    }

3 ответа

Решение

Массив имеет фиксированную длину при создании. В этом примере они хотят сэкономить некоторое время, всегда повторно используя один и тот же массив для каждой итерации. Поскольку невозможно уменьшить массив (так как длина определяется при создании), они используют обходной путь, они ставят ноль в том месте, где должен заканчиваться массив. Когда их цикл достигает нуля, он знает, что находится в концептуальном "конце" массива.

Это звучит как вопрос, который был переведен с C или C++. В этих языках вы используете нулевой символ для конца строки (который, в свою очередь, является char массив). В Java это не работает; массив никогда не меняет свою длину.

Если вызывающий знает, что этот нулевой символ вставлен, он, конечно, может использовать информацию и игнорировать символы после нулевого. Они не могут использовать len переменная, поскольку она существует только внутри метода и не существует, когда метод возвращается.

В Java вы обычно делаете:

str = Arrays.copyOf(str, tail);

Это создало бы новый массив правильной длины и скопировало бы все символы (это то, что пример кода стремился избежать).

Кстати, я получаю ArrayIndexOutOfBoundsException в соответствии str[tail] = 0; в конце, если дубликаты не были найдены. В этом случае tail равна длине массива и, следовательно, 1 позиции после последнего элемента.

Массивы неизменны, поэтому длина не изменяется, пустое пространство заполнено нулевыми значениями

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
Другие вопросы по тегам