【发布时间】:2018-08-01 21:03:48
【问题描述】:
我正在尝试将字符串值的样本向量按字母顺序插入到预先排序的列表中(并且不使用/编写排序函数)。我正确地得到了部分代码,其中一个字符串将被插入到列表中。但是,由于我对迭代器不太熟悉,所以我的 if 语句是不完整的,并且字符串会在之后连续推送所有满足条件的值。
#include <iostream>
#include <list>
#include <vector>
#include <string>
std::list<std::string> update(std::list<std::string>& data, std::vector<std::string> add){
std::vector<std::string>::iterator add_itr;
std::list<std::string>::iterator data_itr;
for (data_itr = data.begin(); data_itr != data.end(); data_itr++){
for (add_itr = add.begin(); add_itr != add.end(); add_itr++){
//this condition is incomplete
if (*add_itr < *data_itr)
data.insert(data_itr, *add_itr);
}
}
return data;
}
void print(const std::string &label, const std::list<std::string> &data) {
std::cout << label;
for (std::list<std::string>::const_iterator itr = data.begin();
itr != data.end(); itr++) {
std::cout << " " << *itr;
}
std::cout << std::endl;
}
int main() {
std::list<std::string> data;
data.push_back("antelope");
data.push_back("catfish");
data.push_back("giraffe");
data.push_back("llama");
data.push_back("jellyfish");
data.push_back("whale_shark");
data.push_back("zebra");
std::vector<std::string> add;
add.push_back("tiger");
add.push_back("llama");
add.push_back("elephant");
print ("before:",data);
update(data,add);
print ("after: ",data);
}
我在想 if 语句的另一个条件应该是&& *add_itr > *(前一个位置的数据字符串),但我不确定如何正确地遍历列表迭代器并写这个。
任何帮助将不胜感激!
【问题讨论】:
-
学习使用std::lower_bound 或
std::upper_bound而不是编写循环。这就是这些算法的目的,那就是告诉您将项目放置在排序容器中的什么位置。如果不是这样,那么请了解这些功能的作用。请注意,您的实现效率非常低 - 如果您想将一个项目放入已排序的容器中,然后使用二分搜索技术找到该位置,而不是一次在容器中迭代一个项目。 -
我以前从未听说过其中任何一个,我一定会调查他们。我现在只是在学习迭代器,并试图弄清楚它们的递增和递减如何适用于列表和向量,并使用一个非常基本的程序来做到这一点。
-
好吧,关键是如果你有一个值的容器在插入元素时会被排序,那么二进制搜索找到插入项目的正确位置平均比遍历整个列表。不管它是一个 STL 容器还是一个普通的值数组。如果插入点接近序列的末尾,并且容器中已经有 100 万个项目怎么办?如果这是一个学校项目,一位好老师会现在或希望以后向您提及。
-
我明白了;我将如何进行二分搜索?
-
转到
std::lower_bound链接。它显示了二进制搜索的实现。此外,std::list无论如何都是一个糟糕的容器,因为无法直接访问某个项目(需要迭代该项目)。但同样,如果您在某些时候被要求以这种方式做事,而不是一一搜索,请不要感到惊讶。只是给你一个良好的开端。