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.
Related
I have the following problem and would like to see if somebody could tell me if I'm on the right track with my approach:
I want to do a "rolling window" kind of computation on two linked lists and for that I need them to be sorted by magnitude. If I just have one linked list, writing the corresponding mergesort is not the problem. However, now I'm wondering how I should go about the fact that I have two linked lists where I want to have the corresponding elements from list 1 and list 2 move together as I sort by the magnitude of list 1. If this is not entirely clear, this is what I mean:
In list 1, I want to do a sort by magnitude, so basically just rearrange the pointers. Whenever I move element "n" in one list, however, I also need to move the corresponding element "n" in the other list to the same position as the element from the other one.
Would my approach of using mergesort for this be the right way to go or does anyone know a better approach? I am having a hard time imagining how I would go about reordering the second list while mergesorting the first one since the second list is not necessarily going to be sorted by magnitude anymore and I need the individual elements to correspond to each other.
Thanks!
Marc
Just create a list of pairs of corresponding elements, and then sort the list by the first element of the pair.
I have a dynamically allocated array containing structs with a key pair value. I need to write an update(key,value) function that puts new struct into array or if struct with same key is already in the array it needs to update its value. Insert and Update is combined in one function.
The problem is:
Before adding a struct I need to check if struct with this key already existing.
I can go through all elements of array and compare key (very slow)
Or I can use binary search, but (!) array must be sorted.
So I tried to sort array with each update (sloooow) or to sort it when calling binary search funtion.....which is each time updating
Finally, I thought that there must be a way of inserting a struct into array so it would be placed in a right place and be always sorted.
However, I couldn't think of an algorithm like that so I came here to ask for some help because google refuses to read my mind.
I need to make my code faster because my array accepts more that 50 000 structs and I'm using bubble sort (because I'm dumb).
Take a look at Red Black Trees: http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
They will ensure the data is always sorted, and it has a complexity of O ( log n ) for inserts.
A binary heap will not suffice, as a binary heap does not have guaranteed sort order, your only guarantee is that the top element is either min or max.
One possible approach is to use a different data structure. As there is no genuine need to keep the structs ordered, there is only need to detect if the struct with the same key exits, so the costs of maintaining order in a balanced tree (for instance by using std::map) are excessive. A more suitable data structure would be a hash table. C++11 provides such in the standard library under obscure name std::unordered_map (http://en.cppreference.com/w/cpp/container/unordered_map).
If you insist on using an array, a possible approach might be to combine these algorithms:
Bloom filter (http://en.wikipedia.org/wiki/Bloom_filter)
Partial sort (http://en.cppreference.com/w/cpp/algorithm/partial_sort)
Binary search
Maintain two ranges in the array -- first goes a range that is already sorted, then goes a range that is not yet. When you insert a struct, first check with the bloom filter if a matching struct might already exist. If the bloom filter gives a negative answer, then just insert the struct at the end of the array. After that the sorted range does not change, the unsorted range grows by one.
If the bloom filter gives a positive answer, then apply partial sort algorithm to make the entire array sorted and then use binary search to check if such an object actually exists. If so, replace this element. After that the sorted range is the entire array, and the unsorted range is empty.
If the binary search has shown that the bloom filter was wrong, and the matching struct is not there, then you just put the new struct at the end of the array. After that the sorted range is entire array minus one, and the unsorted range is the last element in the array.
Each time you insert an element, binary search to find if it exists. If it doesn't exist, the binary search will give you the index at which you can insert it.
You could use std::set, which does not allow duplicate elements and places elements in sorted position. This assumes that you are storing the key and value in a struct, and not separately. In order for the sorting to work properly, you will need to define a comparison function for the structs.
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.
I'm using Queue Abstract Data Type which is based on Singly Linked List. I want to sort the data which Queue keeps in 3 ways: First with merge sort, second with quick sort, third with heap sort. So is there anyone can help about this?
Ordinarily a queue is sorted by insertion order - items are sorted by the order in which they were inserted into the queue. It appears you want to break that essential quality of a queue.
I'm only going to cover merge sorting with this answer. Hopefully others will cover the other algorithms or you can derive them yourself.
A single linked list can be treated as a list of lists simply by knowing when one list ends and another begins. For a merge sort you need to start with sorted lists - if each list has a length of 1, it is sorted simply because no other order is possible. Merging two linked lists into one is easy - you take the smallest item from each of two lists and link it into a new list, until both lists are exhausted. So for the first pass, you break the list into sublists of length 1, and combine them into sublists of length 2. The second pass you merge the sublists of length 2 into sublists of length 4. Each pass doubles the size of the sorted sublists. You're finished when the size of the sorted sublist is greater or equal to the size of your entire list.
I have been trying out to figure out a way to find intersection of N lists in c++.
The method that is clicking me is sort, merge and iterate.
Is there any other way too ?
Please share your suggestions.
Sort each list using std::sort (or if it's an std::list, use std::list::sort) then compute the intersections using std::set_intersection iteratively (apply it to the first two lists, then to the result and the third list, then to the result and the fourth list, and so on).
A solution using unsorted lists would be messier. Presumably, you'd have an 'answer' list, initially empty. Then you'd identify two lists, and step through one; for each element, you'd scan the other list to see if it is present in that list - storing the element in the answer if there's a match. Then you'd create a new empty answer list, and step through another of the original lists, searching through the previous answer list for a matching element, and adding to the new answer list. Repeat ad nauseam.
This is not particularly efficient.
For the 'sort, merge, and iterate' solution, working with pairs of lists, is also not as effective as simultaneously iterating through the N sorted lists in parallel, only selecting elements that appear in all lists as part of the answer.