简体   繁体   中英

How do I insert two values into a <list> or <vector> so that I can retrieve values later on?

Code worked on:

#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;
};

I am getting errors for template arguments, and can't figure out why. It looks like this line

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

is throwing errors

 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;
                                    ^

I can't figure out why.

I'm also stuck with errors

/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);
         ^

The instantiation of the iterator is:

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

Edit trying out vector hashtable:

   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;
};

Tried adding as much detail as I could in the comments, but this successfully passed all tests on my end. While I mentioned I reduced the original copy constructor from O(keys.length + vals.size) to just O(vals.size) - I lied.

resize() is linear in the length of the vector - so it's best to leave that alone.

 #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
    }
}

To answer the title of your question, you can use the push_back methods of std::list and std::vector to put items into those containers.

The items will stay in the container until the container is deleted, the items are deleted or your program stops executing.

To find items in your containers, you can search using a loop. The std::list and std::vector both support iterators for iterating through the container. Items in a std::vector can be retrieved using array syntax.

It sounds to me like you need a multimap. A map is a container that allows you to insert key / value pairs, where keys can be used to look up values. A multimap allows you to have multiple values associated with a single key.

For example:

    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;
    }

If my assumption was wrong and you really did want to use a list / vector, then you would need to create them as a list / vector of pairs. Then to find items you would iterate the entire list and check each pair to see if it matched your criteria.

For example:

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;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM