how to sort a treemap using bubble sort? - sorting

27527-683
27525-1179
27525-1571
27525-1813
27525-4911
27526-1303
27526-3641
27525-3989
27525-4083
27525-4670
27526-4102
27526-558
27527-2411
27527-4342
this is the list of key where it is declared as string in a map
then i want to sort it in ascending order.
how can i use a bubble sorting method inside a map?
where the value of the key is a list.
in order to get :
27525-1179
27525-1571
27525-1813
27525-3989
27525-4083
27525-4670
27525-4911
27526-558
27526-1303
27526-3641
27526-4102
27527-683
27527-2411
27527-4342

You should be able to just perform an in-order traversal on your tree. Bu if you insist here is what you would do.
keyList = yourTreeMap.getKeys();
for(i = keyList.length-1; i > 0; i--)
for(j = 0; j < i; j++)
if (keyList[j] > keyList[j+1]) keyList.swap(j, j+1);
Since you don't specify a lnaguage, I present psuedocode.

In general you just use the same bubble sort algorithm as normal it's just your comparison condition that's tweaked here to look at both the key and the value to determine what is greater than what, that is compare the keys first and if they're equal then compare the values if the keys don't match then use the difference in the values to get your result of swap or don't swap. Bubble sort is bad efficiency-wise though if you're using this in a real world scenario.
Jon got the post in before me but basically what he wrote looks right except you'd want a complex condition for the if within the nested loop, like
if(key1<key2)
keyList.swap(i,j)
else if(keyList[key1]<keyList[key2])
keyList.swap(i,j)
of course as he also stated how these keys/values are actually extracted/used will depend on the language, which is lacking in the question or tags.

Related

Algorithm to find a set of words in a large list of words

I'm looking for the fastest algorithm that can find a set of words matching another set of words in a list of 9 million records.
Problem: I have a list with almost 100,000 sets of words and I need to search for a match of each of the word set in another list of 9 million sets of words.
My current solution goes like this, I read all the records (from a text file) and keep in memory (in form of an array, let's call it 'search list'). While building this array, I sort the set of words alphabetically and once all the word sets are added, I sort the whole list. I do the same with the other big list, let's call that 'data list'.
Now I iterate over each of elements in my search list and try to find a match. Once a match is found I remember the position at which it matched and the next search I do from the same position. This saves me from iterating the whole data list again and again for each element in the search list.
I assumed it to be super fast but unfortunately, it's not. It almost takes 15 to 20 mins to complete full iteration of the search list. This is not acceptable.
Here is a snippet of my code
int lastPointer = 0
for(int i=0; i<search list.size(); i++){
def this_matched_out = []
inmem_json_arr[i][0]
for(int j=lastPointer; j<data list.size(); j++){
if(data list[j].containsAll(search list[i])){
this_matched_out.add(data list[j])
lastPointer = j
}
}
if(this_matched_out.size()>0) - println "found a match for search "+list[i]
else println "No match found for "+list[i]
}
Can anybody suggest me a better algorithm or am I doing anything wrong here?
Use a hash table. A lookup takes O(1) time no matter how big your set of words is.

Accessing a Hash table as a Value-Sorted Range in D

If I have a hash-table File[string] _subs and want to access its values in a sorted way is there a better way than simply through
auto ssubs = new File[_subs.length]; // preallocate sorted subs
size_t ix = 0;
foreach (sub; _subs) {
ssubs[ix++] = sub; // set new reference to sub
}
ssubs.sort!((a, b) => (a.timeLastModified >
b.timeLastModified));
return ssubs;
I would suggest to skip the foreach-loop and use .values, like so:
auto ssubs = _subs.values.sort!((a, b) => (a.timeLastModified > b.timeLastModified));
I think it's better to not add dependencies between elements (like with a for-loop), when they don't need it. The reason for this is that it's easier to make the code parallel without it.
If you find yourself doing that operation often, consider trying a RedBlackTree from std.container. It's the usual sortedness vs. runtime complexity tradeoff: Whereas accessing and inserting elements into an unordered hashmap (hashset) like an AA is O(1), the same operations on an ordered map (set) like a RedBlackTree is O(log(n)).

Count frequency of items in array - without two for loops

Need to know is there a way to count the frequency of items in a array without using two loops. This is without knowing the size of the array. If I know the size of the array I can use switch without looping. But I need more versatile than that. I think modifying the quicksort may give better results.
Array[n];
TwoDArray[n][2];
First loop will go on Array[], while second loop is to find the element and increase it count in two-d array.
max = 0;
for(int i=0;i<Array.length;i++){
found= false;
for(int j=0;j<TwoDArray[max].length;j++){
if(TwoDArray[j][0]==Array[i]){
TwoDArray[j][1]+=;
found = true;
break;
}
}
if(found==false){
TwoDArray[max+1][0]=Array[i];
TwoDArray[max+1][1]=1;
max+=;
}
If you can comment or provide better solution would be very helpful.
Use map or hash table to implement this. Insert key as the array item and value as the frequency.
Alternatively you can use array too if the range of array elements are not too large. Increase the count of value at indexes corresponding to the array element.
I would build a map keyed by the item in the array and with a value that is the count of that item. One pass over the array to build the map that contains the counts. For each item, look it's count up in the map, increment the count, and put the new count back into the map.
The map put and get operations can be constant time (e.g., if you use a hash map implementation with a good hash function and properly sized backing store). This means you can compute the frequencies in time proportional to the number of elements in your array.
I'm not saying this is better than using a map or hash table (especially not when there are lots of duplicates, though in that case you can get close to O(n) sorting with certain techniques, so this is not too bad either), it's just an alternative.
Sort the array
Use a (single) for-loop to iterate through the sorted array
If you find the same element as the previous one, increment the current count
If you find a different element, store the previous element and its count and set the count to 1
At the end of the loop, store the previous element and its count

Array List looping for a duplicate value

I am looking if there is an "easy" or simple way to make an array of something, Lets say Icecreams.. this would be a class of icecream with various Attributes (ID, flavour, Size, scoops), i would like to run an array that gathers every ice cream ordered and then searches through this list for any duplicate values (2+ same size)
First idea i had was a for loop that creates the array than grabs the ice cream ID for the first instance, and checks its "flavour" against the array, if no duplicate is found the ID is increased by 1 (ID++) and then that Ice creams flavour is ran in the array, if a match is found i would set a Boolean to true.
Every approach i seem to take appears to be rather long winded and i haven't got one working as of yet. hoping some fresh/more experienced eyes would help on this.
In answer to below;
The XML would hold something like below
<iceCream id=1>
<flavour>chocolate</flavour>
<scoops>5</scoops>
</iceCream>
<iceCream id=2>
<flavour>banana</flavour>
<scoops>2</scoops>
</iceCream>
I would want to use drools (probably an array list?) to gather each icecream tag and allow me to check if any of the icecreams have the same flavour and output something (set a boolean to true) if a match is found, My understand was to make an array then run each icecream though the array by using its ID to identify it and inside each loop do ID +1 (int ID = 1) then in the lopp ID++. Aswell as search through the flavour childtag.
int ID = 0;
boolean match = false;
ArrayList iceCreams = new ArrayList($cont.getIceCreams());
for(iceCream $Flavour: (ArrayList<iceCream>)iceCreams)
{
ID++
if($Flavour.getFlavour().equals(icecream with id of (ID variable).getFlavour)
{
match = true;
}
}
if(match)
{etc etc etc}
Something along these lines if this helps?
1) If you have control over the first array creation, why dont you make sure that while insertion, you insert only the icecreams that are unique. So, while you are inserting into the array say ID=1, first iterate through the array and check if there is an icecream in the array with ID as 1, if not you put this into the array and do other stuff.
2) Searching part: now while inserting, make sure that you are doing so based on the ascending oder of IDs, so you can perform binary search for the same.
Note: I dont know drools, i have just posted a logic as per my understanding of the problem.
I don't know drools either, but I'll post the some pseudo code for what I think you are trying to accomplish:
for(i = 0; i < len(ice_cream_array); i++)
{
for(j = (i + 1); j < len(ice_cream_array); j++)
{
if (ice_cream_array[i] == ice_cream_array[j])
break from inner loop
else
there is no match
}
}
You may also want to look up bubble sorts and binary searches.

How to choose all possible combinations?

Let's assume that we have the list of loans user has like below:
loan1
loan2
loan3
...
loan10
And we have the function which can accept from 2 to 10 loans:
function(loans).
For ex., the following is possible:
function(loan1, loan2)
function(loan1, loan3)
function(loan1, loan4)
function(loan1, loan2, loan3)
function(loan1, loan2, loan4)
function(loan1, loan2, loan3, loan4, loan5, loan6, loan7, loan8, loan9, loan10)
How to write the code to pass all possible combinations to that function?
On RosettaCode you have implemented generating combinations in many languages, choose yourself.
Here's how we could do it in ruby :
loans= ['loan1','loan2', ... , 'loan10']
def my_function(loans)
array_of_loan_combinations = (0..arr.length).to_a.combination(2).map{|i,j| arr[i...j]}
array_of_loan_combinations.each do |combination|
//do something
end
end
To call :
my_function(loans);
I have written a class to handle common functions for working with the binomial coefficient, which is the type of problem that your problem falls under. It performs the following tasks:
Outputs all the K-indexes in a nice format for any N choose K to a file. The K-indexes can be substituted with more descriptive strings or letters. This method makes solving this type of problem quite trivial.
Converts the K-indexes to the proper index of an entry in the sorted binomial coefficient table. This technique is much faster than older published techniques that rely on iteration. It does this by using a mathematical property inherent in Pascal's Triangle. My paper talks about this. I believe I am the first to discover and publish this technique, but I could be wrong.
Converts the index in a sorted binomial coefficient table to the corresponding K-indexes. I believe it might be faster than the link you have found.
Uses Mark Dominus method to calculate the binomial coefficient, which is much less likely to overflow and works with larger numbers.
The class is written in .NET C# and provides a way to manage the objects related to the problem (if any) by using a generic list. The constructor of this class takes a bool value called InitTable that when true will create a generic list to hold the objects to be managed. If this value is false, then it will not create the table. The table does not need to be created in order to perform the 4 above methods. Accessor methods are provided to access the table.
There is an associated test class which shows how to use the class and its methods. It has been extensively tested with 2 cases and there are no known bugs.
To read about this class and download the code, see Tablizing The Binomial Coeffieicent.
It should not be hard to convert this class to the language of your choice.
To solve your problem, you might want to write a new loans function that takes as input an array of loan objects and works on those objects with the BinCoeff class. In C#, to obtain the array of loans for each unique combination, something like the following example code could be used:
void LoanCombinations(Loan[] Loans)
{
// The Loans array contains all of the loan objects that need
// to be handled.
int LoansCount = Loans.Length;
// Loop though all possible combinations of loan objects.
// Start with 2 loan objects, then 3, 4, and so forth.
for (int N = 2; N <= N; N++)
{
// Loop thru all the possible groups of combinations.
for (int K = N - 1; K < N; K++)
{
// Create the bin coeff object required to get all
// the combos for this N choose K combination.
BinCoeff<int> BC = new BinCoeff<int>(N, K, false);
int NumCombos = BinCoeff<int>.GetBinCoeff(N, K);
int[] KIndexes = new int[K];
// Loop thru all the combinations for this N choose K.
for (int Combo = 0; Combo < NumCombos; Combo++)
{
// Get the k-indexes for this combination, which in this case
// are the indexes to each loan in Loans.
BC.GetKIndexes(Loop, KIndexes);
// Create a new array of Loan objects that correspond to
// this combination group.
Loan[] ComboLoans = new Loan[K];
for (int Loop = 0; Loop < K; Loop++)
ComboLoans[Loop] = Loans[KIndexes[Loop]];
// Call the ProcessLoans function with the loans to be processed.
ProcessLoans(ComboLoans);
}
}
}
}
I have not tested the above code, but in general it should solve your problem.

Resources