В 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