【问题标题】:Inserting a String Alphabetically in List in C++在 C++ 中的列表中按字母顺序插入字符串
【发布时间】: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 语句的另一个条件应该是&amp;&amp; *add_itr &gt; *(前一个位置的数据字符串),但我不确定如何正确地遍历列表迭代器并写这个。

任何帮助将不胜感激!

【问题讨论】:

  • 学习使用std::lower_boundstd::upper_bound 而不是编写循环。这就是这些算法的目的,那就是告诉您将项目放置在排序容器中的什么位置。如果不是这样,那么请了解这些功能的作用。请注意,您的实现效率非常低 - 如果您想将一个项目放入已排序的容器中,然后使用二分搜索技术找到该位置,而不是一次在容器中迭代一个项目。
  • 我以前从未听说过其中任何一个,我一定会调查他们。我现在只是在学习迭代器,并试图弄清楚它们的递增和递减如何适用于列表和向量,并使用一个非常基本的程序来做到这一点。
  • 好吧,关键是如果你有一个值的容器在插入元素时会被排序,那么二进制搜索找到插入项目的正确位置平均比遍历整个列表。不管它是一个 STL 容器还是一个普通的值数组。如果插入点接近序列的末尾,并且容器中已经有 100 万个项目怎么办?如果这是一个学校项目,一位好老师会现在或希望以后向您提及。
  • 我明白了;我将如何进行二分搜索?
  • 转到std::lower_bound 链接。它显示了二进制搜索的实现。此外,std::list 无论如何都是一个糟糕的容器,因为无法直接访问某个项目(需要迭代该项目)。但同样,如果您在某些时候被要求以这种方式做事,而不是一一搜索,请不要感到惊讶。只是给你一个良好的开端。

标签: c++ list vector iterator


【解决方案1】:

首先,您应该开始使用 auto,因为它更易于阅读和遵循。所以不要声明

   std::vector<std::string>::iterator add_itr;

你可以直接使用:

for (auto add_itr = add.begin(); add_itr != add.end(); add_itr++){

现在对于解决方案,您不需要迭代列表data。只需迭代向量并将值插入到列表中。

【讨论】:

  • 我认为 OP 希望在插入新字符串后对容器进行排序。那么,可能是一个向量,然后是一个在更新列表上运行的排序?
  • Vishaal,我希望在插入字符串时对列表进行“排序”(不使用排序功能)。这不可能吗?
  • 阿曼,如果我只是插入值,我怎么知道字符串是按字母顺序排列在列表中的之前还是之后?
  • 更好的解决方案是根本不迭代,而是使用二分查找找到位置。
【解决方案2】:

C++ 中的迭代器是针对泛型编程。这意味着您可以编写一次集合处理算法,然后将其用于任意集合集合,只要它们支持迭代器概念

以下是如何以通用方式实现所需内容。

template<typename T, typename K>
void update(T& sortedValues, const K& valuesToAdd) {
    for (auto value : valuesToAdd) {
        auto position = std::lower_bound(sortedValues.begin(), sortedValues.end(), value);
        sortedValues.insert(position, value);
    }
}

当然,如果有必要,您始终可以更具体地了解集合类型。

注意:在预先排序的列表中,“jellyfish”应该在“llama”之前。

【讨论】:

    【解决方案3】:

    这很大程度上取决于底层数据结构,因为您使用std::list 来保存排序值,在这种情况下更喜欢使用std::list 的成员函数:

    void update(std::list<std::string>& data, const std::vector<std::string>& add){
        std::list<std::string> sortedAdd(std::begin(add), std::end(add));
        sortedAdd.sort();
        data.merge(std::move(sortedAdd));
    }
    

    【讨论】:

      【解决方案4】:

      由于我不想使用排序函数并且必须使用列表来解决这个特定问题,所以我只是创建了一个比原来少一个的新迭代器。

      for (add_itr = add.begin(); add_itr != add.end(); add_itr++){
           for (data_itr = data.begin(); data_itr != data.end(); data_itr++){
            std::list<std::string>::iterator dnew = data_itr;
            dnew--;
             if ((*add_itr < *data_itr) && (*add_itr > *dnew))
                data.insert(data_itr, *add_itr);
           }
         }
      

      我知道这不是最好的方法,但它适用于这个特定问题。感谢所有回答的人 - 我学到了很多东西!

      【讨论】:

        猜你喜欢
        • 2012-10-21
        • 1970-01-01
        • 2015-05-07
        • 1970-01-01
        • 2013-09-17
        • 2013-12-16
        • 2013-10-18
        • 2017-02-23
        • 1970-01-01
        相关资源
        最近更新 更多