【问题标题】:How do I insert two values into a <list> or <vector> so that I can retrieve values later on?如何将两个值插入 <list> 或 <vector> 以便稍后检索值?
【发布时间】:2017-02-24 23:12:10
【问题描述】:

处理过的代码:

#include <algorithm>
#include <list>
#include <vector>

class key_value_sequences {
public:

    int size(int key);
    int * data(int key);
    void insert(int key, int value);

private:
    list< pair<int, vector<int> > > myList;

}; // class key_value_sequences

#endif

void key_value_sequences::insert(int key, int value){
    list< pair<int, vector<int> > >::iterator it;
    for(it = myList.begin(); it != myList.end(); ++it){
        if (it->first == key){
            it->second.push_back(value);
            return;
        }
    }
    vector<int> v;
    v.push_back(value);
    myList.push_back(make_pair(key, v));
    return;
};

int * key_value_sequences::data(int key){
    list< pair<int, vector<int> > >::iterator it;
    for(it = myList.begin(); it != myList.end(); ++it){
        if (it->first == key){
            return (it->second);
        }
    }
    vector<int> v;
    return v;
};

int key_value_sequences::size(int key){
    list< pair<int, vector<int> > >::iterator it;
    for(it = myList.begin(); it != myList.end(); ++it){
        if (it->first == key){
            return it->second.size();
        }
    }
    return -1;
};

我收到模板参数错误,但不知道为什么。看起来像这条线

std::list< pair<int, vector<int> > > myList;

正在抛出错误

 error: template argument 1 is invalid
 std::list< pair<int, vector<int> > > myList;
                                  ^
 error: template argument 2 is invalid
 error: expected unqualified-id before ‘>’ token
 std::list< pair<int, vector<int> > > myList;
                                    ^

我不知道为什么。

我也遇到了错误

/usr/include/c++/5/bits/stl_algobase.h:840:58: error: no type named ‘value_type’ in ‘struct std::iterator_traits<std::vector<int> >’
   typedef typename iterator_traits<_II2>::value_type _ValueType2;
                                                      ^
/usr/include/c++/5/bits/stl_algobase.h:845:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<std::vector<int> >’
         && __are_same<_ValueType1, _ValueType2>::__value);
         ^

迭代器的实例化为:

list<pair<int, vector<int>>>::iterator it;

编辑试用矢量哈希表:

   class key_value_sequences {
public:

int size(int key);


int* data(int key);


void insert(int key, int value);

private:
    vector<list<pair<int,int>>> hash_table;
    list<pair<int, vector<int>>>::iterator it;

    int hash(int value)
    {
        return abs(value%static_cast<int>(hash_table.size()));
    }

}; // class key_value_sequences

#endif // A3_HPP

void key_value_sequences::insert(int key, int value){

          list<pair<int,int>> &collisionlist = hash_table[hash(key)];


          for (std::pair<int,int> &test: collisionlist)
          {
              if (key == test.first)
              {
                  test.second = value; // update existing
                  return;
              }
          }

          collisionlist.push_back(pair<int,int>(key, value));
};

int* key_value_sequences::data(int key){

    for(it = hash_table.begin(); it != hash_table.end(); ++it){
        if (it->first == key){
            return &(it->second[0]);
        }
    }
    return nullptr;
};

int key_value_sequences::size(int key){

    for(it = hash_table.begin(); it != hash_table.end(); ++it){
        if (it->first == key){
            return it->second.size();
        }
    }
    return -1;
};

【问题讨论】:

  • 你要找的是std::map
  • 顺便说一句,您应该使用与string 不同的名称。要找出原因,请在您最喜欢的 C++ 参考资料中研究 string
  • 请贴出string的定义。
  • 您需要有一个与该类关联的数据结构,以便能够提取您添加到其中的任何值。在插入函数中实例化列表对类没有任何作用,因为退出函数时数据会丢失。添加一个私有列表,此时数据函数将能够遍历列表并打印数据。
  • @MattGalaxy 所以只需将std::list&lt;std::pair&lt;key,value&gt;&gt; myList; 移至私人位置,然后离开 push_back 行?我想我应该以某种方式为 push_back 创建一个循环,所以它不止一次。

标签: c++ string vector insert


【解决方案1】:

尝试在 cmets 中添加尽可能多的细节,但这成功地通过了我的所有测试。虽然我提到我将原始复制构造函数从 O(keys.length + vals.size) 减少到只是 O(vals.size)- 我撒了谎。

resize()vector 的长度呈线性关系,因此最好不要管它。

 #include <iostream>
 #include <vector>
 #include <list>

 using namespace std;

 class key_value_sequences{
    public:
        int size(int key);
        int * data(int key);
        void insert(int key, int value);
        key_value_sequences(){};                               //ctor
        key_value_sequences(const key_value_sequences &_rhs); //[heli]coptor
        ~key_value_sequences(){};                            //dtor
    private:
        vector <vector<int> *> keys;
          list <vector<int>  > vals;
};

key_value_sequences::key_value_sequences(const key_value_sequences &_rhs){
    keys.resize(_rhs.keys.size());         //resize new kvs key vector to old size
    auto it = _rhs.vals.begin();

    while (it != _rhs.vals.end()){
        vals.push_back(*it);            //push back value vector to list
        keys[(*it)[0]] = &vals.back(); //use the prepended key value of value vector
        ++it;                         //            to reestablish ref in key vector
    }
}

void key_value_sequences::insert(int key, int value){
    if (key > -1 && key + 1 > keys.size()){    //if key index is valid & > key vector size
        keys.resize(key+1, new vector<int>);  //resize the vector to make room

        vector<int> v;
        vals.push_back(v);                 //push back new value vector to list
        vals.back().push_back(key);       //create key @ front of list for the [heli]coptor
        vals.back().push_back(value);    //push back initial value
        keys[key] = &vals.back();       //update reference in key vector
    }
    else if (key > -1){
        keys[key]->push_back(value); //index already exists, push back value to value vector
    }

    return;
}

int * key_value_sequences::data(int key){
    if (key + 1 > keys.size() || key < 0){
        return nullptr;
    }
    else{
        return &keys[key]->at(1);   //if index is valid: return second element of value vector
    }                              //in order to account for the prepended key
}

int key_value_sequences::size(int key){
    if (key < 0 || keys[key]->empty() || key + 1 > keys.size()){
        return -1;
    }
    else{
        return keys[key]->size() - 1; //if index is valid: return size - 1 to account for key
    }
}

【讨论】:

  • 当使用std::mapstd::set 时,OP 应该有一个唯一的密钥。很多对都有 0 作为键。
  • @ThomasMatthews - 在进一步研究定义之后,它似乎假设每个键都有一个映射值。我已经编辑了我的答案以表明我打算提出什么建议。
  • @MattGalaxy 地图和无序地图有什么区别?我以前使用过地图,所以我想我对如何实现它有了更好的理解。
  • @Gman maps 实际上对容器进行了排序,因此您可以迭代它们,同时期望知道下一个值可能是什么。例如,如果您有键 '0' - '1' - & '2',那么它们将按该顺序组织。与无序地图相反。在这种地图中,容器按照您添加的顺序添加,例如推回向量。
  • 根据list::insert方法,第一个参数是列表中要插入之前的位置。所以 OP 在列表的前面插入值,除了 1。
【解决方案2】:

在我看来你需要一个多地图。映射是一个容器,允许您插入键/值对,其中键可用于查找值。多重映射允许您将多个值与单个键关联。

例如:

    std::multimap<int, int> myMap;

    myMap.insert( std::make_pair( 0, 8 ) );
    myMap.insert( std::make_pair( 0, 5 ) );
    myMap.insert( std::make_pair( 0, 7 ) );
    myMap.insert( std::make_pair( 1, 15 ) );

    // equal_range() returns a pair of iterators pointing to the first item
    // in the list for the specified key, and one past the final item containing
    // the key.
    auto searchResultIteratorPair = myMap.equal_range( 0 );

    // Print out the values found
    for( auto it = searchResultIteratorPair.first; it != searchResultIteratorPair.second; it++ )
    {
        std::cout << "Value: " << it->second << std::endl;
    }

如果我的假设是错误的,并且您确实想要使用列表/向量,那么您需要将它们创建为对的列表/向量。然后要查找项目,您将迭代整个列表并检查每一对以查看它是否符合您的条件。

例如:

std::list< std::pair<int, int> > myList;

    myList.push_back( std::make_pair( 0, 8 ) );
    myList.push_back( std::make_pair( 0, 5 ) );
    myList.push_back( std::make_pair( 0, 7 ) );
    myList.push_back( std::make_pair( 1, 15 ) );

    int searchValue = 0;
    for( auto it = myList.begin(); it != myList.end(); it++ )
    {
        if( it->first != searchValue )
            continue;

        std::cout << "Value: " << it->second << std::endl;
    }

【讨论】:

  • 仅供参考,insert(0,5) 中的 0 是位置,而不是值。
  • @aatwo 我实际上只能使用列表/向量。这与您的示例有何不同?
  • @ThomasMatthews 我现在意识到我只想使用 list/vector,因为 map/unordered_map 的实现有点太直接了,我正在尝试使用不同的结构。
  • @aatwo 我将我写的内容添加到原始帖子中。我在想我将 for 循环放在数据类中?
【解决方案3】:

要回答您的问题的标题,您可以使用std::liststd::vectorpush_back 方法将项目放入这些容器中。

项目将保留在容器中,直到容器被删除、项目被删除或您的程序停止执行。

对于容器中的find 项目,您可以使用循环进行搜索。 std::liststd::vector 都支持 iterators 用于通过容器迭代std::vector 中的项目可以使用数组语法进行检索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    相关资源
    最近更新 更多