Мне нужна помощь с проектом C ++. Что мне нужно сделать, это удалить данный элемент из массива указателей. Техника, которой я научился, состоит в том, чтобы создать новый массив с одним элементом меньше и скопировать все из старого массива в новый, за исключением указанного элемента. После этого я должен указать старый массив на новый.
Вот код того, что у меня уже есть:
Кстати, я работаю с пользовательскими структурами …
Data **values = null; // values is initialized in my insert function so it is
// populated
int count; // this keeps track of values' lengthbool remove(Data * x) {
Data **newArray = new Data *[count - 1];
for (int i = 0; i < count; i++) {
while (x != values[i]) {
newArray[i] = values[i];
}
count -= 1;
return true;
}
values = newArray;
return false;
}
До сих пор функция вставки работала и выводила заполненный массив, но когда я запускаю команду remove, все, что она делает — это уменьшает размер массива, но не удаляет нужный элемент. Я использую 0-й элемент каждый раз в качестве контроля.
Это вывод, который я получаю:
count=3 values=[5,6,7] // initial insertion of 5, 6, 7
five is a member of collection? 0
count=3 values=[5,6] // removal of 0th element aka 5, but doesn't work
five is a member of collection? 0
count=4 values=[5,6,5] // re-insertion of 0th element (which is stored in
five is a member of collection? 0 // my v0 variable)
Кто-нибудь может подтолкнуть меня в правильном направлении к завершению этого?
Во-первых, ваш код теряет память, как ничего хорошего! Затем вы копируете только первый элемент, и даже не то, что первый элемент окажется тем, который вы хотите удалить. Кроме того, когда вы возвращаетесь из своей функции, вы вообще не меняли свое внутреннее состояние. Вы определенно хотите сделать что-то вроде
Data** it = std::find(values, values + count, x);
if (it != values + count) {
std::copy(it + 1, values + count, it);
--count;
return true;
}
return false;
Тем не менее, если кто-то научил вас реализовать что-то вроде std::vector<T>
Принимая во внимание перераспределение на каждой операции, пришло время менять школы! Выделение памяти относительно дорого, и вы хотите их избежать. То есть при реализации чего-то вроде std::vector<T>
Вы действительно хотите реализовать это как std::vector<T>
! То есть вы сохраняете внутренний буфер потенциально большего количества элементов, чем есть, и помните, сколько элементов вы используете. Вставляя новый элемент, вы выделяете новый массив только в том случае, если в текущем массиве нет места (если это не сделать, это легко приведет к квадратичной сложности, даже если всегда добавлять элементы в конце). При удалении элемента вы просто перемещаете все конечные объекты на один и вспоминаете, что в массиве на один объект меньше.
Попробуй это:
bool remove(Data * x)
{
bool found = false;
// See if x is in the array.
for (int i = 0; i < count; i++) {
if (x != values[i]) {
found = true;
break;
}
}
if (!found)
{
return false;
}
// Only need to create the array if the item to be removed is present
Data **newArray = new Data *[count - 1];
// Copy the content to the new array
int newIndex = 0;
for (int i = 0; i < count; i++)
{
if (x != values[i])
newArray[newIndex++] = values[i];
}
// Now change the pointers.
delete[] values;
count--;
values = newArray;
return true;
}
Обратите внимание, что есть основополагающее предположение, что если x
присутствует в массиве, то он там только один раз! Код не будет работать для нескольких случаев, оставленных вам, учитывая, как это школьное упражнение.