i knew its a weird Idea to think about, i want to know if it is possible to reverse the mechanism of sorting, (i dont want to reverse the order).
for example lets say i have a random array of integers, then i sorted the array with quicksort method, now i want to go back and un-sort the array and get it back to the it was.
you may suggest i save a copy of the array, thats not what i want, think of it as a time line and have the ability to go backward or forward of sorting method.
and if it is possible please consider showing me the best way to do it with Delphi XE.
Thanks in advance.
It is not possible to unsort. You have to either:
create a separate array that holds a copy of the values and then sort that array so that you can preserve the original array.
create a separate array that holds pointers/indexes to the values in the original array, and then sort the second array using the values it refers to.
I usually use a function that given an array returns an array of the sorted indexes.
This way you will always have the original data and you will be able to access the data in a sorted way using something like:
for jIndex in ASortedIndexesArray do
ShowMessage(AOriginalArray[jIndex]);
Hope this helps.
Mirko
If you want to think of it as a time line and have the ability to go backward or forward of sorting method then organize it like a timeline - with records in a file. Save each step and you will be able to reproduce it.
If the array is of integers the indices will not help you as one index (a pointer) takes the same memory as one array element. If you lack RAM use a file to store and retrieve the array. If you use larger data structures you can create, store and retrieve indices as David suggested.
You could log the swapping actions that quicksort (or whatever sorting algorithm you use) does to a list and then go forward and backward in that list to undo/redo these actions. Not simple to implement, but doable.
Related
I have a Matlab struct:
a(1).x=54.23; a(1).y=2.3; a(1).col=32.221; a(1).id=1;
a(2).x=5.23; a(2).y=3.3; a(2).col=2.221; a(2).id=2;
... and so on. Now i want to access the struct in a having id 73. I can think of doing a for loop but the thing is i have to access elements of array a several times like this based on id. Wat is the fastest data structure available for this purpose? Python like dictionary may work but i am not sure ow to implement it. Pointing out some code examples would be very helpful.
Try this:
id=[a.id];
a(id==73)
It's not as efficient as a dictionary, but if it's fast enough for your purposes it's not worth looking further.
The a.id part evaluates to a comma-separated list of id values, which are concatenated in an array that you can then use for lookup.
I have an array of integers storing some userIDs. I basically want to prevent a user from performing an action twice, so the moment he has done it his userID enters this array.
I wonder whether it is a good idea to sort or not this array. If it is sorted, then you have A={min, ..., max}. Then, if I'm not wrong, checking if an ID is in the array will take log2(|A|) 'steps'. On the other hand, if the array was not sorted then you will need |A|/2 (in average) steps.
So sorting seems better to check if an element exists in the array (log(|A|) vs |A|), but what about 'adding' a new value? Calculating the position of where the new userID should be can be done at the same time you're checking, but then you will have to displace all the elements from that position by 1... or at least that's how I'd do it on C, truth is this is going to be an array in a MongoDB document, so perhaps this is handled in some other most-effective way.
Of course if the array is unsorted then adding a new value will just take one step ("pushing" it to the end).
To me, an adding operation (with previous checking) will take:
If sorted: log2(|A|) + |A|/2. The log2 part to check and find the place and the |A|/2 as an average of the displacements needed.
If not sorted: |A|/2 + 1. The |A|/2 to check and the +1 to push the new element.
Given that for adding you'll always first check, then the not sorted version appears to have less steps, but truth is I'm not very confident on the +|A|/2 of the sorted version. That's how I would do it in C, but maybe it can work another way...
O(Log(A)) is definitely better than O(A), but this can be done in O(1). The data structure you are looking for is HashMap, if you are going to do this in C. I haven't worked in C in a very long time so I don't know if it is natively available now. It surely is available in C++. Also there are some libraries which you can use in the worst case.
For MongoDB, my solution may not be the best, but I think that you can create another collection of just the userIDs and index the collection keyed on userIDs. This way when someone tries to do that action, you can query the user status quickest.
Also in MongoDB you can try adding another key called UserDidTheAction to your User's collection. This key's value may be true or false. Index the collection based on userID and probably you will have similar performance as the other solution, but at the cost of modifying your original collection's design (though it's not required to be fixed in MongoDB).
How do I efficiently find which array in a list of array has members.
The context is for message brokering. I have a list of queue and need to periodically push their content to consumers, but since the number of queues can be large, I want to quickly find out which ones have elements in them.
My only solution currently is to basically keep a separate list which keeps track of which array still has content in it, but was curious about alternatives, and it just bugs the hell out of me ;)
I am using javascript but am hoping for a more general idea of which algorihtm should I look into.
I'm going to make this language-agnostic and keep my answer short and simple.
Maintain a parallel data-structure: another set storing array IDs, but only those of arrays that are nonempty.
When you make a new (empty) array, add it to the first set only.
When you add to an array, add it to the second set iff it's not already there.
When you remove from an array, if the array is now empty, remove it from the second set.
When you delete an array, remove it from the the first set (and the second, if it's there).
If you're using a hashset for this second set, insertion and deletion times don't change. This is the most efficient thing one could ask for, and a hybrid datastructure of this ilk is necessary AFAICT.
You can then find all nonempty arrays by iterating over the second set.
i am using octave for my project as i cant afford a matlab license, however i have run into a significant roadblock and that is the lack of associative array data structures.
my problem is this:
i have some data in the form of cell arrays containing matrices with each cell array representing a potential solution to a problem. i also have a floating point number that represents the evaluated performance of that solution which i want to put into a map-like data structure with the floating point score as the key, in order to sort the solutions by their performance.
can anyone suggest a simple solution to this problem?
what i have thought about doing so far is making each element part of a two element cell array, with the evaluation score as the first element and the data as the second, and then put those arrays into another cell array, which i then apply some sorting algorithm to, sorting by array{i}{1}.. but this seems like a pretty clunky solution.
does octave have any functionality in this respect that i am just unaware of? or is my clunky solution the only way to achieve this?
any help would be greatly appreciated
thanks
How about keeping the cell array as it is, but create a matrix where the columns are the evaluation score and the index into the cell array. Then you can easily use sortrows on the evaluation score column and use the index to pull the solution from the cell array. I think this should be a simple solution that has the benefit of not rearranging your potentially large set of data.
I have an unsorted linked list. I need to sort it by a certain field then return the linked list to its previous unsorted condition. How can I do this without making a copy of the list?
When you say "return the linked list to its previous unsorted condition", do you mean the list needs to be placed into a random order or to the exact same order that you started with?
In any case, don't forget that a list can be linked into more than one list at a time. If you have two sets of "next"/"previous" pointers, then you can effectively have the same set of items sorted two different ways at the same time.
To do this you will need to either sort and then restore the list or create and sort references to the list.
To sort the list directly Merge Sort is most likely the best thing you could use for the initial sort, but returning them to their original state is tricky unless you either record your moves so you can reverse them or store their original position and resort them using that as the key.
If you would rather sort the references to the list instead you will need to allocate enough space to hold pointers to each node and sort that. If you use a flat array to store the pointers then you could use the standard C qsort to do this.
If this is an assignment and you must implement your own sort then if you don't already know the length of the list you could take advantage of having to traverse it to count its length to also choose a good initial pivot point for quicksort or if you choose not to use quicksort you can let your imagination go wild with all kinds of optimizations.
Taking your points in reverse order, to support returning to original order, you can add an extra int field to each list node. Set those values based on the original order, and when you need to return it to the original order, just sort on that field.
As far as the sorting in general goes, you probably want to use something like a merge-sort or possibly a Quick-sort.
You can make that data structure somewhat like this.
struct Elem {
Elem* _next;
Elem* _nextSorted;
...
}
Then you can use any algo for sorting the list (maybe merge sort)
If you want to keep your linked list untouched, you should add information to store the ordered list of elements.
To do so, you can either create a new linked list where each element points to one element of your original linked list. Or you can add one more field in the element of your list like sorted_next.
In any case, you should use a sequential algorithm like mergesort to sort a linked list.
Here is a C source code of mergesort for linked lists that you could reuse for your project.
I guess most of the answers have already covered the usual techniques one could use. As far as figuring out the solution to the problem goes, a trick is to look at the problem and think if the human mind can do it.
Figuring out the original random sequence from a sorted sequence is theoretically impossible unless you use some other means. This can be done by
a)modifying the linked list structure (as mentioned above, you simply add a pointer for the sorted sequence separately). This would work and maybe technically you are not creating a separate linked list, but it is as good as a new linked list - one made of pointers.
b)the other way is to log each transition of the sorting algo in a stack. This allows you to not be dependent on the sorting algorithm you use. For example when say node 1 is shifted to the 3rd position, you could have something like 1:3 pushed to the stack. The notation, of course, may vary. Once you push all the transitions, you can simply pop the stack to give take it back to the original pattern / any point in between. This is more like
If you're interested in learning more about the design for loggers, I suggest you read about the Command Pattern