2012-03-01 66 views
0

我正在處理在結構中輸入書籍數據的程序,並根據用戶的請求刪除元素。但是,我很難找出刪除所需書籍的最佳方法。你認爲我是否朝着正確的方向前進?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 2012-03-01 05:31:30

+0

嗯,我們還沒有對向量做過什麼:/我會查找他們thnx – gamergirl22 2012-03-01 05:32:04

+1

for(int j = num; j srbhkmr 2012-03-01 05:35:56

回答

2

那麼在for循環中,您標記的是在第一個if (ptr[i].title == book_rem)後沒有找到該書。如果該書作爲第二元素或之後出現,該怎麼辦?

你應該將你的工作分爲兩個部分如下:

  • 這本書搜索。
  • 如果找到它,請將其刪除,否則請打印「未找到」。

他可能是什麼樣子的循環中:

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 2012-03-01 06:09:54

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
  • 如果元素被刪除
  • 如果函數到達最後一行return語句將退出功能,它意味着沒有找到匹配
+0

如果順序不重要,您可以簡單地將'ptr [num-1]'移動到'ptr [i]'。這比移除所有元素後要快得多。 – tom 2012-03-01 06:01:27

+0

謝謝,我有責任 – gamergirl22 2012-03-01 06:07:47

1

而是重新發明輪子,我建議使用一個std: :列表,考慮你正在執行的任務。列表(而不是矢量)可以實現內部高效的元素移除和插入。但是,與矢量不同,列表消耗的內存不是連續的,也就是說,元素不能保證在內存中「並排」。如果你不斷刪除和添加元素,列表是一個更好的選擇,而如果你需要不斷地訪問元素「隨機」,你可能會更好地使用矢量。

您可以輕鬆地從列表中刪除元素:使用list::erase通過迭代器刪除元素,並按值刪除元素(這看起來適合您)。更多信息可以在這裏找到:http://www.cplusplus.com/reference/stl/list/

+0

thnx我會研究這個 – gamergirl22 2012-03-01 06:14:27

1

使用std::map(作者+出版商的地圖書標題),std::setstd::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 2012-03-01 08:02:37

+0

不,你只有'updateIndexes()'如果你在'num-1'存儲了元素的索引,但現在它已經移動到'i'。所以你需要將這些更新爲'i'。如果你沒有保留任何這樣的索引,那麼'updateIndexes'根本就不需要。 – devil 2012-03-01 15:25:39