c ++删除动态数组的1个元素?

时间:2012-03-01 05:30:01

标签: c++ pointers struct

我正在处理一个在结构中输入书籍数据的程序,并根据用户的请求删除一个元素。但是,我很难找出删除所需书籍的最佳方法。你认为我朝着正确的方向前进吗?

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;
           }
    }
}

我知道我的逻辑是关闭的?但是我的导师说我很接近..如果你有任何好的资源或链接,请以这种方式发送这些指针让我对完成它的最佳方法感到有些困惑。 / p>

5 个答案:

答案 0 :(得分:2)

for循环中,您正在标记在第一个if (ptr[i].title == book_rem)之后未立即找到该书。如果这本书作为第二个元素或之后存在怎么办。

您应该将您的工作分为以下两部分:

  • 搜索这本书。
  • 如果找到则删除它,否则打​​印“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;
}

答案 1 :(得分: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;
}
  • 第二,第三和第四个参数不在任何地方使用,所以我删除了它们
  • 通过引用传递num允许您修改原始
  • 您需要将所有元素移到已移除的元素之后,因此j必须从i开始
  • 您可以在索引j+1访问数组,因此条件应为j+1 < num
  • 如果元素被删除,则return语句将退出该函数
  • 如果函数到达最后一行,则表示未找到匹配项

答案 2 :(得分:1)

考虑到你正在执行的任务,我建议使用std :: list,而不是重新发明轮子。列表(与向量相对)可以在内部有效地删除和插入元素。但是,与向量不同,列表消耗的内存不是连续的,也就是说,元素不能保证在内存中“并排”。如果你不断删除和添加元素,列表是一个更好的选择,而如果你需要不断地随机访问元素,你可能会更好地使用向量。

您可以轻松地从列表中删除元素:使用list::erase通过迭代器删除元素,使用list::remove按值删除元素(这似乎适合您)。可以在此处找到更多信息:http://www.cplusplus.com/reference/stl/list/

答案 3 :(得分:1)

使用std::map(地图书标题为作者+发布商),std::setstd::list,而不是编写自己的容器。或者至少使用std::find_if来查找该书。使用std::set只能将标题+作者+发布者的一个组合存储在容器中。使用std::map,您将能够按标题快速找到发布者/授权者,std::list您可以快速插入/删除图书(并且可以在容器中复制)。

答案 4 :(得分: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;
}