Путаница с динамическим распределением массива

Я должен прочитать несколько значений от пользователя и сохранить их в массиве. Затем мне нужно создать массив, достаточно большой, чтобы хранить все эти значения. Используя некоторые функции, которые я написал, я сортирую /lsearch/bsearch через массив для заданных значений.

У меня уже написана моя программа и все, но для реализации статического массива. Я как-то запутался в том, где на самом деле использовать динамический массив.

Имеет смысл использовать его, когда пользователь начинает вводить значения, так как я не могу предположить, сколько значений он вводит, поэтому массив должен быть достаточно большим, чтобы его содержать. Также имеет смысл (вроде) использовать его, когда я создаю достаточно большой массив, который может содержать все значения (действует как копия первого массива).

Я не прошу никакого кода, все сделано, но на статическом подходе. Я просто пытаюсь визуализировать, где мне нужно использовать дарри здесь. Мои мысли:

  1. Когда пользователь впервые вводит значения
  2. Когда я копирую arr1 в новый arr2, он должен быть достаточно большим, чтобы вместить все значения arr1.

Я прав или нет в этом?

4 ответа

Начните с использования malloc или же calloc выделить массив некоторого известного начального размера и отслеживать текущую емкость в переменной.

Когда вы читаете значения в, если ваш массив недостаточно велик, то пользователь realloc удвоить размер массива.

Если вы не уверены, сколько записей вставлено во время выполнения, я предлагаю вам использовать структуру данных связанного списка. Это сэкономит ваше использование памяти.

Лучшее решение - не копировать весь массив каждый раз, когда пользователь вводит значение. Требования к malloc и free будут тяжелыми и будут ухудшаться с большими массивами.

Вы должны рассчитать размер вашего массива с "количеством элементов в качестве входных данных

int * array = newArray (10);

int * newArray (int size) {вернуть malloc(size * sizeof(int)); }

Имейте в виду, что int* это массив, так что вы все еще можете сделать array[3], Но, если вы централизуете хранилище с количеством используемых элементов и текущим размером, вы можете выделить несколько элементов и увеличиваться только при исчерпании доступных элементов.

struct DynamicIntArray {
  int used;
  int size;
  int* storage
};

void add(struct DynamicArray* array, int value) {
  if (used < size) {
    (*array).storage[used] = value;
    used++;
  } else {
    int newSize = size+10;
    int* newStorage = (int*)malloc(newSize*sizeof(int));
    int* oldStorage = (*array).storage;
    for (int i = 0; i < size; i++) {
       newStorage[i] = oldStorage[i];
    }
    (*array).storage = newStorage;
    (*array).size = newSize;
    free(oldStorage);
  }
}

с таким примером. Вы должны быть в состоянии написать newDynamicIntArray(...) функция и freeDynamicIntArray(struct DynamicIntArray* array) функции и любые другие методы, которые вам небезразличны.

Я думаю, что вы задаете неправильный вопрос.

Вопрос в том:
Является ли динамический массив (непрерывный блок памяти) надлежащей структурой данных для хранения и обработки данных в вашем приложении?

Существует только одно особенно полезное приложение для массивов, и оно является ассоциативным массивом, что означает, что сам индекс массива имеет значение и может использоваться для получения правильного содержимого, которое вы ищете, с усилием O(1).

Например, список участников дорожек может быть сохранен в массиве, где индекс массива равен номеру дорожки. Это идеальная структура данных, если вы хотите визуализировать имена участников на треке. Это ужасная структура данных, если вы хотите отсортировать имена всех участников в алфавитном порядке.

Но в соответствии с описанием вашего приложения индекс массива не имеет для вас значения. Это указывает на то, что массив не лучший выбор.

Другие вопросы по тегам