c++ set formation from two other sets - c++

I Have two sets of strings.
set<string> A;
set<string> B;
I will insert some elements into both the sets and some of the elements that I insert into them are common elements.
I can basically get the elements
Present in A and not in B
Present in B and not in A
using
std::set_difference
I can also get the common elements in both the sets by
using
std::set_intersection
How can I get the elements which and present only in A and only in B and put them in a different set?
Total idea is creating a set which will not have the common elements but all the elements in both the sets.
In mathematical language:
(A(UNION)B)-(A(intersection)B)

How about std::set_symmetric_difference? It seems to fit what you want.

You can use set_symmetric_difference

Related

C++ - Sort map based on values, if values same sort based on key

I came across a problem where I needed to store two values, one id and other its influence, and id should be randomly accessible. Also it should be sorted based on influence and if both influence are same , sort based on id. With these things in mind, I used map,but is there a way to actually do it ?
I tried below comparator and map but it gives error
struct cmp
{
bool comparator()(const pair<int,int>a,const pair<int,int>b)
{
if(a.second==b.second) return a.first<b.first;
else return a.second<b.second;
}
};
unordered_map<int,int,cmp>m;
From what I understand, you want a collection sorted by one value but quickly indexable by another. These two points are in contradiction. Sorting a collection by a key value makes it quicker to index by that key value. There is no easy way to make a collection quickly indexable in two different ways at the same time. Note that I say "quickly indexable" instead of talking about random access. That's yet a different concept.
In short, you need two collections. You can have a main one that stores influence-ID pairs and is sorted by influences, and a secondary one that stores IDs and maps them to the main collection. There are many options for that; here is one:
std::set<std::pair<int,int>> influences;
std::unordered_map<int, decltype(influences)::iterator> ids;
When inserting an influence-ID pair, you can insert into influence first and then take the iterator to that new element and insert it with the ID.
Another solution is to keep a main collection of influence-ID pairs but this time sorted by IDs (and binary search it when you need to get the influence from an ID), and maintain a array of permutation indices that tells you at what index an element of the main collection would be if it were sorted by influence. Something like this:
std::vector<std::pair<int,int>> influences;
// insert all elements sorted by ID
std::vector<decltype(influences)::size_type> sorted_indices;
// now sort by influences but modifying `sorted_indices` instead.
Relevant question
If the IDs are all from 0 to N, you can even just have influences indexed by ID:
std::vector<int> influences; // influences[id] is the influence value corresponding to id
This gives you random access.
The "correct" choice depends on the many other possible constraints you may have.

C++ efficient way to store and update sorted items

I have a operation that continuously generates random solutions (std::vector<float>). I evaluate the solutions against a mathematical function to see their usefulness (float). I would like to store the top 10 solutions all the time. What would be the most efficient way to do this in C++?
I need to store both the solutions(std::vector) and their usefulness (float). I am performing several hundred thousands of evaluations and hence I am in need of an efficient solution.
Edit:
I am aware of sorting methods. I am looking for methods other than sorting and storing the values. Looking for better data structures if any.
You evaluate the float score() function for current std::vector<T> solution, store them in a std::pair<vector<T>, float>.
You use a std::priority_queue< pair<vector<T>, float> > to store the 10 best solutions based on their score, and the score itself. std::priority_queue is a heap, so it allows you to extract its max value according to a compare function that you can set up to compare score_a < score_b.
Store the first 10 pairs, then for each new one compare it with the top of the heap, if score(new) > score(10th) then insert(new) into the priority_queue p, and p.pop_back() to get rid of the old 10th element.
You keep doing this inside a loop until you run out of vector<T> solutions.
Have a vector of pair, where pair has 1 element as solution and other element as usefulness. Then write custom comparator to compare elements in the vector.
Add element at last, then sort this vector and remove last element.
As #user4581301 mentioned in comments, for 10 elements, you dont need to sort. Just traverse vector everytime, or you can also perform ordered insert in vector.
Here are some links to help you:
https://www.geeksforgeeks.org/sorting-vector-of-pairs-in-c-set-1-sort-by-first-and-second/
Comparator for vector<pair<int,int>>

Implementation of non increasing list with STL C++

In a problem inputs are several lists of numbers,
Ex-
(1,5,4,3), (2,7,3,1,5), (1,9,1,7,3,7,2), (3,5,4,2,3).
where each list may appear twice.
In the final output distinct lists should be printed, in which elements in each list should be sorted in non increasing order, as well as lists should be sorted like that.
Is it possible to implement this whole thing with map in c++ ?
Output for the above example should be
9,7,7,3,2,1,1
7,5,3,2,1
5,4,3,3,2
5,4,3,1
Simply,set of unique lists where within each lists numbers again sorted in non increasing order.
std::set will definitely help you. You will get a unique sorted list as the resultant set if you insert your list into a std::set<int>
Edit:
std::set<std::multiset<int, std::greater<int>> myList;
Inner set going to sort in non increasing order and keeping duplicates elements, and outer set going to keep only unique list of inner list.

Find common elements in two Integer List

I have two given integer List:
alist : TList<Integer>; // eg. 1,2,3,4,5,6,7,8,9
blist : TList<Integer>; // e.g 1,2,3,4,5
Resultlist : TList<Integer>;
IgnoreList : TList<Integer>; // e,g, 1,2,3
What is a effective way to find the common elements on both lists, excluding elements from the ignore list. As I have to run this procedure over many items I need a effective and fast way of implementation for this problem.
Resultlist should be 4,5
I agree with Dmitry. Converting lists to hash sets and looking up in them would be fast irrespective of whether the lists are sorted.
Have a look at Delphi's TDictionary. TDictionary intersection is one quick way of finding common elements. Otherwise,
1) Create a TDictionary for blacklisted elements.
2) Create a TDictionary and insert elements from alist that are not present in blacklist-dictionary. This operation is fast because TDictionary are optimized for lookup.
3) finally, iterate over elements of blist and only output elements preent in alist-dictionary.
What you want for this is the list comparison algorithm. You take two sorted lists (make sure to sort them first if they aren't already) and two index variables, set both indices to 0, and start comparing values, advancing one index or the other if they aren't equal, or both indices of they are. By customizing the behavior of the algorithm when unequal or equal values are found, there are a lot of things you can do with this. What you want for here is, when equal values are found, insert the value into the output list.

How do I store this data set in C++ (which containers do I use)?

I have data represented as follows.
A-> B,C,D,E,F
B-> C,(D,E),F
D-> (E,F)
E-> (F,G)
F-> (G)
G-> NULL
Each letter represents a string. All letters/strings are in alphabetical order. The B-> means that B is a member of every element succeeding it. So for this example row B consists of the sets (B,C), (B,D,E) and (B,F). Each row can only contain strings higher in order then the row string. I have to arrange the data this way.
Should I use a sequence container like vector or an associative container like set.
I am building small clusters to make big clusters, so I will be iterating through all the data starting from the bottom up.
My guess would be a set of sets?
It seems a graph is what you are looking for, but the standard C++ library (STL) does not have such a data structure. The next best bet is multimap: a map is an 1:1 associated array, where as multimap is a 1:many associated array.
I'd say use a hashtable, where each string maps to a vector and in turn each vector element points to another vector.
So something like this:
"b" -> {{"a", "b"},{"d"},{"e"}}