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.