Given this set
set<string> s = {"a","b","c"};
is it possible to implement next_permutation() to get all combinations, where elements to do not repeat and order matters?
No it is not possible. std::set is an associative container and maintains an strict weak ordering. std::next_permutation transforms the range it is given which would break the ordering.
If you need to get the permutations of the contents of the set I suggest you use a std::vector. You can copy the set into the vector and then get the permutation from that.
std::set<int> set_data;
//fill set
std::vector<int> temp(set_data.begin(), set_data.end());
do
{
// code goes here
}
while(std::next_permutation(temp.begin(), temp.end()));
Related
How do you remove elements from a vector of vectors that are identical to another vector but whose elements are not in the same indices?
For example:
std::vector<vector<int>> vectA = {{1,3,4}. {1,2,3}, {3,2,1};
I want it so that {3,2,1} is removed from vectA and it becomes:
vectA = {{1,3,4}, {1,2,3}}
Any idea how to proceed efficiently?
Sort the elements of each vector
Drop duplicates (this is an easy look-up)
If you need to retain the original element order, then build any correspondence you wish: parallel arrays of vectors (original and sorted), pairs of (unsorted, sorted) vectors, etc. Drop duplicates based on the sorted ones.
I trust that you can take it from here.
What you are describing is the behavior of std::set, ie. this solves your problem:
set<set<int>> input = {{1,3,4}, {1,2,3}, {3,2,1}};
// input is now {{1,2,3},{1,3,4}}
This works because a set is basically equal to a sorted vector with no duplicates.
If you really want to, you can now convert to std::vector:
vector<vector<int>> nums;
for(auto & s : input) nums.emplace_back(s.begin(), s.end());
std::unordered_map<std::string,std::string> mymap;
mymap.insert(std::make_pair("ELEMENTTYPE", "NEWINTERFACE"));
mymap.insert(std::make_pair("STYLEFILE", "Style_Light.txt"));
mymap.insert(std::make_pair("ELEMENTNAME", "IN1"));
mymap.insert(std::make_pair("POSITIONX", "0"));
mymap.insert(std::make_pair("POSITIONY", "0"));
mymap.insert(std::make_pair("SIZEX", "50"));
mymap.insert(std::make_pair("SIZEY", "50"));
I expected the map to have those elements in that order, but instead, it is :
-SIZEY
-ELEMENTTYPE
-STYLEFILE
-SIZEX
-POSITIONX
-POSITIONY
I am very confused; why is the std::unordered_map ordering my elements?
The term unordered in std::unordered_map means that the order is unspecified. You cannot rely on the order of an unordered_* container. All associative containers (containers which map a value to a key) will mess with the order of the elements because this order allows them to achieve better performance when searching by key, which is usually the goal of using a map.
If you want to control the order yourself, you can use std::vector<std::pair<std::string, std::string>>. You'll have a set of pairs, ordered the way you want, but you forfeit the fast find implementations associative containers provide.
You want a specific arbitrary order
std::unordered_map has no particular order that you can control
std::map sorts the keys according to a function
If you want something like python's OrderedDict in c++ here are some duplicate answers:
C++ dictionary/map with added order
A std::map that keep track of the order of insertion?
Perhaps you are trying to be too fancy, when all you really need is a basic struct object. It's just a variable and its members are just variables that you get when and how you want.
#include <vector>
#include <string>
enum elementtype_enum { NEWINTERFACE, OTHER };
struct my_element_type {
std::string name;
elementtype_enum type;
std::string style_file;
int positionx, positiony, sizex, sizey;
};
int main() {
std::vector<my_element_type> elements;
my_element_type e { "IN1", NEWINTERFACE, "Style_Light.txt", 0, 0, 50, 50 };
elements.push_back(e);
return 0;
}
By its very name, a std::unordered_map is unordered. The order of its elements is unspecified, and will be dependent on the hash of the Key values.
If the order of the elements is important to you, use std::map instead. By default, it uses the Key's operator< for ordering, but you can optionally provide a custom Compare type if you want to order the elements yourself.
Suppose I have a vector A = {1,1,1,0,0};
Is there any inbuilt function in vector header to find all the indices of vector where A is repeated?
suppose for 1, returning, { 0,1,2 }
for 0, {3,4}
If not, is there any time efficient way to do so?
If not, is there any time efficient way to do so?
Sort your vector and use std::equal_range to find iterators range, then convert them to indexes. If you cannot sort the vector, create vector of indexes, sort it and copy the range from it to result.
If the vector is or can be sorted, then you can use std::equal_range.
http://en.cppreference.com/w/cpp/algorithm/equal_range
I need suggestion to use STL containers in the best possible way to sort 3 sets of data
1. A ID (Integer)
2. First Value (String)
3. Second Value (String)
An example of the data structure is as below:
I want to use map as it is sorted at the time of insert and no need to execute a sorting algorithm separately. Since the ID can repeat it must be a multimap, and each data of a column is linked to each other so the rows will change in order to sort keeping the same values attached to a ID.
Sorting the ID and value is ok, but how do I sort 2 values as multimap can take only one value. From my thinking it will be multimap of a multimap or a struct of the data structure and then STL containers. But I want to make it as simple as possible. I need suggestion on how this can be achieved.
Thanks!
Having a map or a set makes sense if and only if you are going to do many insert/erase operations it. If the data structure is static, storing a vector and sorting it once is way more effective. That said, if I understand your question correctly, I think you don't need a map, but a multiset.
typedef pair<int, pair<string, string>> myDataType;
set<myDataType> mySet;
here, the operator < of pair will take care of the ordering.
If you don't want to refer to the id as elem.first, and to the strings as elem.second.first, and elem.second.second, then you can use a struct and overload operator < for it.
struct myType
{
int id;
string s1;
string s2;
};
bool operator < (const myType& t1, const myType& t2)
{
return make_tuple(t1.id, t1.s1, t1.s2) < make_tuple(t2.id, t2.s1, t2.s2);
}
You could just use a std::set<std::tuple<int, std::string, std::string>>. Tuples are lexicographically compared thus you would get the effect you want for free.
Live Demo
Elements in a multimap are sorted by the Key. You cannot 'sort' multimap. What you can do is to create vector of pairs<Key, Map<Key>::Interator> with elements fulfilling some logical condition and sort vector.
I have already two STL vectors. For instance:
vector<int> MyList;
MyList.push_back(10);
MyList.push_back(20);
MyList.push_back(30);
MyList.push_back(40);
MyList.push_back(50);
vector<int> MyListSub;
MyListSub.push_back(20);
MyListSub.push_back(30);
MyListSub.push_back(40);
And I want to get the number of elements which is in the MyListSub and isn't in MyList.
For this instance, result is "2"
You can use std::set_difference for this:
std::vector<int> diff;
std::set_difference(MyList.begin(), MyList.end(),
MyListSub.begin(), MyListSub.end(),
std::back_inserter(diff));
As #Jan points out, the vectors have to be sorted. If they are not, use std::sort to sort them:
std::sort(MyList.begin(), MyList.end());
Alternatively you can consider storing your elements in an std::set in the first place, thus they will already be sorted.