2016-09-10 4 views
2

Мой профессор дал нам этот код, который создает отсортированный массив int и хочет, чтобы мы преобразовали его в список отсортированных массивов со строками. Это назначение при обслуживании и должно отражать исходный код. Таким образом, я не могу использовать метод size, Collections.sort() или что-либо, что не отражает исходный код.Проблема с преобразованием упорядоченного массива int в список упорядоченных массивов

Мы дали

OrderedIntList() { 
    a = new int[10]; 
} 

    public void insert(int v) { 
    if(c == 0) { 
     a[0]= v; 
     c++; 
    } else { 
     int j = 0; 
     for (int i = 0; i < c; i++, j++) { 
      if(v < a[i]) 
       break; 
     } 
     for (int i = c; i > j; i--) { 
      a[i] = a[i - 1]; 
     } 

     a[j]= v; 
     c++; 
    } 
} 

Это то, что я придумал, чтобы преобразовать его в список массива

 stringList() { 
    list = new ArrayList<String>(10); 
} 

    public void insert(String element) { 
    if(c == 0) { 
     list.add(0, element); 
     c++; 
    } else { 
     int j = 0; 
     for (int i = 0; i < c; i++, j++) { 
      if(element.compareTo(list.get(i)) == -1) 
       break; 
     } 
     for (int i = c; i > j; i--) { 
      list.set(i, list.get(0)); 
     } 

     list.set(j, element); 
     c++; 
    } 
} 

Он продолжает бросать исключение на

list.set(i, list.get(0)); 

Когда Отладка Я вижу, что ArrayList.class бросает исключение, потому что индекс равен размеру. Я не могу придумать решение. Любая помощь будет оценена.

+3

Краткий ответ: вам нужно использовать метод 'add', чтобы увеличить размер списка. Вы не можете сделать это, просто набрав «set» на элементах, которые вы еще не вставили. –

+1

Что сказал @David Уоллес, даже если set разрешил это, ваша строка list.set (i, list.get (0)); не совпадает с [i] = a [i-1], вы делаете что-то вроде [i] = a [0]. Итак, у вас есть две ошибки. Также я просто предполагаю, что вы неверно истолковываете, что list = new ArrayList (10); в этом случае он не составляет список из 10 строк, он просто использует число 10 в качестве «подсказки», чтобы установить начальную емкость (которая не является размером) до 10 –

+0

@ben, это не «подсказка». Это фактический размер. В соответствии с [javadoc] (https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html#ArrayList-int-): *** Создает пустой список с указанным начальным емкость *** – Bohemian

ответ

1

Одно решение вашей проблемы вместо

stringList() { 
    list = new ArrayList<String>(10); 
} 

сделать

stringList() { 
    list = new ArrayList<String>(10); 
    for(int i = 0; i < 10; i++){ 
     list.add(""); 
    } 
} 

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

+0

@Bohemian, вы правы в том, что нет необходимости сначала заполнять структуру данных. Однако предложенное мной изменение является правильным. Я полагаю, вы хотите предложить альтернативный подход, который не форпопирует структуру данных и не добавляет элементы в хвост списка во время вставки вместо использования set(). Это будет работать, потому что это сортировка вставки, однако то, что я предложил, также должно работать. –

3

Интересным аспектом этого задания является то, что массивы и списки имеют существенное различие в поведении: массивы имеют фиксированный размер wh Списки ile расширяются по мере добавления элементов. Для списков добавление элементов в любом месте, кроме конца, является вставкой и автоматически перемещает элементы вправо, чтобы освободить место. Это не происходит с массивом, поэтому это нужно сделать вручную в коде, который вы рефакторинг.

Итак, на мой взгляд, правильный минимальный рефакторинг массива в список состоит в том, чтобы превратить set в insert, а затем удалить код, который раньше использовался для переключения элементов. Это больше не требуется для списка:

public void insert(String element) { 
    if (c == 0) { 
     list.add(element); 
     c++; 
    } else { 
     int j = 0; 
     for (int i = 0; i < c; i++, j++) { 
      if (element.compareTo(list.get(i)) < 0) 
       break; 
     } 
     list.insert(j, element); 
     c++; 
    } 
} 

Для списков, добавление в пустой список такой же, как вставка в положении 0. Так специально для обработки пустого списка является совершенно ненужным. Но это может быть не «отражение исходного» кода.

Еще одна тонкая разница заключается в том, что этот код не вызывает ошибки, если вставлено более 10 элементов. Чтобы правильно отразить поведение исходного кода, вам нужно будет специально добавить тест для этого.

if (c == MAX_SIZE) 
    throw new ArrayIndexOutOfBoundsException(c); 

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

+0

@Bohemian, как этот ответ не имеет значения? Скорее, у арраиста есть достаточно возможностей для хранения всех элементов, но этот ответ стоит, несмотря на этот факт. –

+0

@spinter конец длинной недели ... Вы правы! – Bohemian