保持两个排序的向量通过指针连接

Keeping two sorted vectors linked by pointers

本文关键字:向量 连接 指针 排序 两个      更新时间:2023-10-16

(是的,这是一个家庭作业)

我试图创建一个简单的数据库,其中一个人是由名称+地址组合或由唯一的帐号识别。我需要能够快速添加/删除/访问有关一个人的信息时,提供了一个acc号码或名称+地址。

我已经创建了一个没有帐户的版本(使用重载操作符<在数据库中搜索与lower_bound),现在我试图添加帐户功能。>

这是我得到的:

struct SPerson
{
    string s_name, s_addr;
    int s_income, s_expense;
    SAccount * s_accountPtr;
    SPerson ( const string &, const string & );  // constructor
};
struct SAccount
{
    string s_account;
    SPerson * s_personPtr;
    SPerson ( const string & );   // constructor
};

这个想法是有一个帐户向量和一个人员向量,并将它们与指针联系起来。似乎很简单,直到我遇到这些问题:

  • 如果我创建一个对象,并插入到一个矢量,该对象的副本被创建和插入吗?还是原来的物体?
  • 当我插入一些东西时,向量中对象的地址会发生什么?
  • 我能让它工作吗?

    bool CDatabase::Birth ( const string & name, const string & addr, const string & account )
    {
        SPerson personToAdd = SPerson ( name, addr );
        SAccount accountToAdd = SAccount ( account );
        SPiter = lower_bound ( SPeople.begin ( ), SPeople.end ( ), personToAdd );
        SAiter = lower_bound ( SAccounts.begin ( ), SAccounts.end ( ), AccountToAdd );
        if ( ( SPiter -> s_name == name &&
           SPiter -> s_addr == addr ) ||
           SAiter -> s_account == account ) return false;
        personToAdd.s_accountPtr = & accountToAdd;   // this is proabably very wrong
        accoutToAdd.s_personPtr = & personToAdd;
        SPeople.insert ( SPiter, personToAdd );   // does this mess up the pointers?
        SAccounts.insert ( SAiter, accountToAdd );
        return true;
    

    }

//我很抱歉,我的代码格式是杀了我,尽快修复

If I create an object and insert it into a vector, does a copy of that object get created and inserted? Or is it the original object?

如果您使用push_backinsert,则会进行复制。如果您不想要副本,请使用emplace_back。在vector对象的末尾以外的任何位置插入元素都是低效的,因为它会移动插入点之后的所有元素,或者更糟的是移动所有元素。

What happens with the addresses of objects in a vector when I insert something into it?

它们可能改变,也可能不改变,这取决于vector的大小和插入的位置。因此,使用指向向量元素的原始指针可能不是一个好主意。一旦你在中间插入了一些东西,或者vector超出了它的容量,你所有的指针可能都指向了无意义的对象。

Can I even make this work somehow?

是的,只需使用句柄而不是原始指针。如果您被允许使用不同的数据结构,如std::map std::unordered_set来检索帐户/人员,而不必通过向量和比较句柄。

在我看来,你试图在SAccountSPerson之间完成某种relationship,更具体地说是one-to-one关系,所以,我建议你模拟数据库系统的实际行为。

你可以像这样设置你的SAccount类:

struct SAccount
{
    string s_account;
    int person_id;            // Since id is unique.
    SAccount ( const int );   // constructor
};

这样每个account都包含一个人的id

编辑:更新

struct SPerson
{
    static id=0;
    string s_name, s_addr;
    int s_income, s_expense;
    int pid, account_id;
    SPerson ( const string &, const string & , int account_id, person_id=++Sperson::id);  // constructor
};
struct SAccount
{
    static id=0;
    string s_account;
    int aid, person_id;
        SPerson ( const string & , int person_id, int account_id=++SAccount::id);   // constructor
};
对于静态属性,您关心的是自动生成id

一个简单的解决方案是在向量中保留指向人员和帐户的指针。即使这意味着在实现数据库时要更加谨慎,但它可以极大地简化从向量中插入和删除对象的设计和性能。

现在有一千人会争论,至少要使用引用计数智能指针,我仍然反对在这种特殊情况下使用它们:-)。

首先,我想感谢你的回答(再一次在SO上,我通过问一个原始的问题发现了大约一百万新的东西),但我决定不使用任何解决方案-我去了这个:

我保持了people向量的排序,每次我在那里插入一个新的人,我也在相同的索引下向SAccounts插入一个新帐户(因此,这个没有排序)。这样,当给定O(log n)的人员信息时,我可以访问帐户。另一种方式,给定帐户信息,搜索是线性的,但我被告知线性搜索仍然足够快。

我在实施上面提到的系统时遇到了一些问题,但这不是这个问题的主题,我会发布另一个问题来讨论这个问题。:)