矢量中的字符串.并将它们按顺序放置

Strings in Vectors. and placing them in order

本文关键字:顺序 字符串      更新时间:2023-10-16

所以我将对象放置在向量中。我想在添加时按顺序删除它们。该对象的基础是

class myObj  {
  private:
     string firstName;
     string lastName;
  public:
     string getFirst;
     string getLast;    
}

我也有这些物体的矢量

vector< myObj > myVect;
vector< myObj >::iterator myVectit = myVect.begin();  

当我将一个新对象添加到向量中时,我想在插入之前找到它应该放在哪里。我可以通过对象值搜索向量吗?如何搜索?这是我第一次尝试

void addanObj (myObj & objtoAdd){
  int lowwerB = lower_bound(
                myVect.begin().getLast(), myVect.end().getLast(), objtoAdd.getLast()
                );
  int upperB = upper_bound(
               myVect.begin().getLast(), myVect.end().getLast(), objtoAdd.getLast()
               );

从那里开始,我计划使用lowwerB和upper B来确定在哪里插入条目。我需要做些什么才能让它发挥作用,或者有什么更好的方法来应对这一挑战?

----后续----

当我试图编译时出现的错误

 error C2440: 'initializing' : cannot convert from 'std::string' to 'int'
 No user-defined-conversion operator available that can perform this conversion, 
 or the operator cannot be called

编译器同时高亮显示lower_bound和upper_bound。我想这是指我把放在哪里

objtoAdd.getLast()

-----更多后续行动-----------------THis接近编译,但还不完全。我应该期望从下限和上限得到什么?它与我定义的迭代器不匹配,我不确定我应该期待什么。

void addMyObj(myObj myObjtoadd)
    vector< myObj>::iterator tempLB;
    vector< myObj>::iterator tempUB;
    myVectit= theDex.begin();
    tempLB  = lower_bound(
              myVect.begin()->getLast(), myVect.end()->getLast(), myObjtoadd.getLast()
              );
    tempUB = upper_bound(
             myVect.begin()->getLast(), myVect.end()->getLast(), myObjtoadd.getLast()
             );

您对std::lower_boundstd::upper_bound的调用不正确。前两个参数必须是定义要搜索的元素范围的迭代器,返回的值也是迭代器

由于这些算法将容器元素与第三个参数值进行比较,因此还需要提供正确的operator<函数来比较对象的lastNamestd::string。我添加了两个不同的比较函数,因为std::lower_boundstd::upper_bound以相反的顺序传递参数。

我认为我在这个代码中有正确的机制,它应该足够接近,让你明白这个想法。

class myObj {
    private:
        std::string firstName;
        std::string lastName;
    public:
        std::string getFirst() const { return firstName; }
        std::string getLast() const { return lastName; }
};
bool operator<(const myObj &obj, const std::string &value) // used by lower_bound()
{
    return obj.getLast() < value;
}
bool operator<(const std::string &value, const myObj &obj) // used by upper_bound()
{
    return value < obj.getLast();
}
int main()
{
    std::vector<myObj> myVect;
    std::vector<myObj>::iterator tempLB, tempUB;
    myObj objtoAdd;
    tempLB = std::lower_bound(myVect.begin(), myVect.end(), objtoAdd.getLast());
    tempUB = std::upper_bound(myVect.begin(), myVect.end(), objtoAdd.getLast());
}

所以这绝对不是最好的方法。原因如下:

矢量大小

默认向量以0个元素开始,但可以容纳一些数字;比如100。添加第101个元素后,它必须完全重新创建向量,复制所有数据,然后删除旧内存。如果做得足够多,这种复制可能会变得昂贵。

插入矢量

这将是一个更大的问题。因为向量只是一个连续的内存块,对象按插入顺序存储,所以假设您有以下内容:

[xxxxxxxzzzzzzzz            ]

如果你想加上"y",它属于x和z之间,对吗?这意味着你需要把所有的z移到1个地方。但是,因为您正在重用同一块内存,所以需要一次只使用一块。

[xxxxxxxzzzzzzz z           ]
[xxxxxxxzzzzzz zz           ]
[xxxxxxxzzzzz zzz           ]
...
[xxxxxxx zzzzzzzz           ]
[xxxxxxxyzzzzzzzz           ]

(空格是为了清楚起见-以前的值没有明确清除)

正如您所看到的,这是为您的"y"腾出空间的许多步骤,对于大型数据集来说,这将非常非常缓慢。

更好的解决方案

正如其他人所提到的,std::set听起来更适合您的需求。std::set将自动排序所有插入的元素(使用树数据结构以更快地插入),并允许您在log(n)时间内按姓氏查找特定的数据成员。它通过使用bool myObj::operator(const & _myObj) const来了解如何对不同的对象进行排序。如果你简单地定义这个操作符来比较this->lastName < _myObj.lastName,你就可以更快地插入到集合中。

或者,如果您真的想使用vector:而不是边走边排序,只需将所有项目添加到vector中,然后在所有插入完成后执行std::sort对它们进行排序。这也将在n log(n)时间内完成,但由于矢量插入问题,应该比当前方法快得多。