2012-03-01 4 views
0

Im работает над программой, которая вводит данные книги в структуру и удаляет элемент по запросу пользователя. Тем не менее, мне трудно понять, как лучше удалить запрошенную книгу. Вы думаете, что Im возглавил в правильном направлении?C++ удаление 1 элемента динамического массива?

struct Data{      //struct of data 
    string title; 
    string author; 
    string publisher; 
}; 

void remove (Data *ptr, string title, string author, string publisher, int num) 
{ 
    string book_rem; 
    cout << "What book do you want to remove?" << endl; 
    getline (cin, book_rem); 

    for (int i=0;i<num;i++) 
    { 
     if (ptr[i].title == book_rem) // check for equality 
      { 
       for (int j = 0; j < num; j++) //shift over elements in new array 
       ptr[j] = ptr[j+1]; 
       ptr[j-1] = 0; 
      } 
     else 
      { 
      cout << "book not found!" << endl; 
      } 
    } 
} 

Я знаю, что моя логика выключен? .. но мой учитель сказал, что я был close..if у вас есть какие-либо хорошие ресурсы или ссылки пожалуйста, отправьте их таким образом эти указатели меня немного запутался на лучший способ, чтобы получить это было сделано.

+3

Почему бы не использовать std :: vector? Вся работа уже выполнена для вас. – Lalaland

+0

ah we havent dove в векторы только что:/я посмотрю их вверх thnx – gamergirl22

+1

для (int j = num; j srbhkmr

ответ

2

Ну в цикле for вы отмечаете, что книга не была найдена сразу после первого if (ptr[i].title == book_rem). Что, если книга присутствует как 2-й элемент или после этого.

Вы должны разделить работу на две части следующим образом:

  • Поиск для книги.
  • Удалите его, если найден, в противном случае напечатайте «Not Found».

Он то, что это может выглядеть как внутри цикла:

for (int i = 0 ; i < num ; i++) { 
    if (ptr[i].title == book_rem) // check for equality 
    { 
     break; 
    } 
} 

И затем вне цикла, проверьте, если книга была найдена, и сделать необходимый материал:

if (i < num) {// Book was found as i is less than size. 
    /* 
     You don't have to shift over elements in the array. 
     I'm assuming your list isn't sorted, so you can just transfer 
     the last element in the array to the position pointed by i, and 
     then decrement the size by 1. 
    */ 
    // Copy all the elements from ptr[num-1] to ptr[1]. 
    num = num - 1; 
} 
else { 
    cout << "book not found!" << endl; 
} 
+0

thnx я попробую его – gamergirl22

1
void remove (Data *ptr, int & num) 
{ 
    string book_rem; 
    cout << "What book do you want to remove?" << endl; 
    getline (cin, book_rem); 

    for (int i = 0; i < num; i++) 
    { 
     if (ptr[i].title == book_rem) // check for equality 
     { 
      for (int j = j; j + 1 < num; j++) //shift over elements in new array 
      { 
       ptr[j] = ptr[j+1]; 
      } 
      num--;  // this will modify the original 
      return; 
     } 
    } 
    cout << "book not found!" << endl; 
} 
  • 2-й, 3-й и 4-й параметры не используются в любом месте, так что я удалил их
  • Передача num по ссылке позволяет изменять исходный
  • Вам нужно перенести все элементы мимо удаленные один, так j должен начинаться i
  • Вы получите доступ к массиву по индексу j+1, поэтому условие должно быть j+1 < num
  • Обратный оператор будет выйти из функции, если элемент был удален
  • Если функция достигает последнюю строку, это означает, что совпадение не было найдено
+0

Если заказ не важен, вы можете просто переместить 'ptr [num-1]' в 'ptr [i]'. Это намного быстрее, чем смещение всех элементов после удаленной. – tom

+0

спасибо, что я обязан – gamergirl22

1

Вместо того, чтобы изобретать колесо, я предложил бы использовать зЬй: : list, рассматривая задачу, которую вы выполняете. Список (в отличие от вектора) позволяет внутренне эффективно удалять и вставлять элементы. Однако, в отличие от вектора, память, которую использует список, не является непрерывной, то есть элементы не гарантируются «рядом» в памяти. Если вы постоянно удаляете и добавляете элементы, список лучше, тогда как если вам нужно постоянно обращаться к элементам «случайно», вам, скорее всего, будет лучше с помощью вектора.

Вы можете удалить элемент из списка легко: используйте list::erase, чтобы удалить элемент через итератор и list::remove, чтобы удалить элемент по значению (что кажется вам подходящим). Более подробную информацию можно найти здесь: http://www.cplusplus.com/reference/stl/list/

+0

thnx я изучу это – gamergirl22

1

Вместо того, чтобы писать свой собственный контейнер, используйте std::map (название книги книги автору + издателю), std::set или std::list. Или, по крайней мере, используйте std::find_if, чтобы найти книгу.С std::set в контейнере может храниться только одна комбинация названия + автор + издатель. С std::map вы сможете быстро найти издателя/автоответчика по названию, с std::list вы сможете быстро вставлять/удалять книги (и сможете иметь дубликаты в контейнере).

1

Вы можете просто заменить вместо копирования.

void swap(Data &d1, Data &d2) 
{ 
    std::swap(d1.title, d2.title); 
    std::swap(d1.author, d2.author); 
    std::swap(d1.publisher, d2.publisher); 
} 


void updateIndexes(int oldId, int newId) 
{ 
    // update all indexes that use oldId to newId here 
} 

void remove (Data *ptr, int & num) 
{ 
    string book_rem; 
    cout << "What book do you want to remove?" << endl; 
    getline (cin, book_rem); 

    for (int i = 0; i < num; ++i) 
    { 
     if (ptr[i].title == book_rem) 
     { 
      swap(ptr[i], ptr[num-1]); 
      --num; 
      updateIndexes(num, i); // optional updating of indexes if any 
      return; 
     } 
    } 
    cout << "book not found!" << endl; 
} 
+0

ах, я его сейчас получаю. так что, когда вы скажете, что обновить все индексы, так это и через цикл? также d1 и d2 были бы моими динамическими волнами, если бы они были правильными? thnx снова. – gamergirl22

+0

Нет, вы только 'updateIndexes()', если где-то вы сохранили индекс элемента в 'num-1', но теперь он переместился в' i'. Поэтому вам нужно обновить их до 'i'. Если вы не сохранили такой индекс, то 'updateIndexes' вообще не требуется. – devil

Смежные вопросы