Getting the 5 lowest values with their index from a 2D Array - java

Any ideas how to get the 5 minimum numbers from a 2D Array. I would like to know their index as well. I'm using Processing but I'm interested to find the correct way to do that.
For example: I have a 4x4 array with the following values:
3-72-64-4
12-45-9-7
86-34-81-55
31-19-18-21
I want to get the five lowest number in my Array which are 3,4,7,9,12. The problem is that I want to know their original index as well.
Example:
Array[0,0] = 3
Array[0,3] = 4
Array[1,3] = 7
Array[1,2] = 9
Is there any formula or good programming way to do that?

There is actually a very good practice that is suited for your case. It's called the 'merge sort algorithm'. It will sort your values and then you just need to output the first 5 values. Here's a link specifically for java. Have fun coding and testing it! I did :D

Well obviously you can just cycle through it and brute force with 2 for loops. Getting the original index makes it harder, as then you cant use sorts, which are faster. If it is sorted or if there is some kind of pattern, you can use a search (binary search) but from what you've given, as it looks as if the data is random, you can't really do much.
If you don't care about indexes, you can try sorts, such as merge sort mentioned by ERed or other types of sorts (I prefer quickSort). Basically you treat the 2D array as a 1D array and assume each subsequent level is just a continuation of the previous level (basically its all just one giant row broken into pieces).

Related

merging and sorting 2 sorted arrays with big o looking for clarification.

This is a school work. I am not looking for code help but since my teacher isn't helping I came here.
I am asked to merge and sort two sorted arrays following two cases:
When sizes of the two arrays are equal
When sizes of the two arrays are different
Now I have done case 2 which also does case 1 :/ I just don't get it how I could write a code for case 1 or how it could differ from case 2. array length doesn't connect with the problem or I am not understanding correctly.
Then I am asked to compute big(o).
I am not looking for code here. If anyone by any chance understands what my teacher is asking really please give me hints to solve it.
It is very good to learn instead of copying.
as you suggest, there is no difference between case 1 and 2 but the worst case of algorithms depend on your solution. So I describe my solution (no code) and give you its worst case.
You can in both case, the arrays must ends with infinity so add infinity to them. then iterate over all of elements of each array, at each time, pick the one which is smaller and put in in your result array (merge of tow arrays).
With this solution, you can calculate worst case easily. we must iterate both of arrays once, and we add a infinity to both of them, if their length is n and m so our worst and best case is O(m + n) (you do m + n + 2 - 1 comparison and -1 because you don't compare the end of both array, I mean infinity)
but why adding infinity add the end of array? because for that we must make a copy of array with one more space? it is one way and worst case of that is O(m + n) for copying arrays too. but there is another solution too. you can compare until you get at the end of array, then you must add the rest of array which is not compared completely to end of your result array. but with infinity, it is automatic.
I hope helped you. if there is something wrong, comment it.
Merging two sorted arrays is a linear complexity operation. This means in terms of Big-O notation it is O(m+n) where m and n are lengths of two sorted arrays.
So when you say the array length doesn't connect with the problem your understanding is correct. Irrespective of the lengths of two sorted arrays the merging of these arrays involves taking elements from each sorted array and comparing them and copying the one to new array(depending whether you want the merged sorted array in ascending or descending order) and incrementing the counter of the array from which you copied the element to new sorted array.
Another way to approach this question is to look at each array as having a head and a tail, and solving the problem recursively. This way, we can use a base case, two arrays of size 1, to sort through the entirety of the two arrays m and n. Since both arrays are already sorted, simply compare the two heads of each array and add the element that comes first to your newly-created merged array, and move to the next element in that array. Your function will call itself again after adding the element. This will keep happening until one of the two arrays is empty. Now, you can simply add what is left of the nonempty array to the end of your merged array, and you are done.
I'm not sure if your professor will allow you to use recursive calls, but this method could make the coding much easier. Runtime would still be O(m+n), as you are basically iterating through both arrays once.
Hope this helps.

the best sort 2D double arrays in java

I'm currently trying to sort a 2D Array into ascending use selection sort. but the result is not good.
i actually have a fairly large data like
double array[1000][1000]
but if we example use data like this :
arrays = 10.555 1.023 5.852
8.856 1.001 4.483
1.121 5.321 1.184
5.123 0.834 3.151
15.123 7.123 1.152
how to make a 2d array can be in sorting like this and can take on the index that has not previously sorting.
after array sorting :
arrays = 1.121 0.834 1.152
5.123 1.001 1.184
8.856 1.023 3.151
10.555 5.321 4.483
15.123 7.123 5.852
and can save index like this in 2d array like this.
save_index = 2 3 4
3 1 2
1 0 3
0 2 1
4 4 0
i want this code can use in large dataset like double array[1000][1000]. what's the solution?
Ok, it looks like you want to sort each column separately, so the following answer is if my assumption is correct.
To solve something like this, I wouldn't use selection sort. I would use insertion sort, (because it's faster) and have a couple nested loops that will only go over certain columns. (For example, the first time the loop runs, have it only go through the first column and the second time it runs, have it only go through the second column).
There are several sorting algorithms which are accepted in the literature. One of the fastest one is "Quick Sort" with its satisfying worst and average case performance. So you better to check it, instead of trying to implement a more effective algorithm. You can take a look at it here.

Recursive Knapsack in Java

I have read many variations of the Knapsack problem, but the version I am tasked with is a little different and I don't quite understand how to solve it.
I have an array of integers that represent weights (ie. {1,4,6,12,7,2}) and need to find only one solution that adds up to the target weight.
I understand the basic algorithm, but I cannot understand how to implement it.
First, what is my base case? Is it when the array is empty? The target has been reached? The target has been over-reached? Or maybe some combination?
Second, when the target is over-reached, how do I backtrack and try the next item?
Third, what am I supposed to return? Should I be returning ints (in which case, am I supposed to print them out?)? Or do I return arrays and the final return is the solution?
Think carefully about the problem you are trying to solve. To approach this problem, I am
considering the inputs and outputs of the Knapsack algorithm.
Input: A set of integers (the knapsack) and a single integer (the proposed sum)
Output: A set of integers who add up to the proposed sum, or null.
In this way your code might look like this
public int[] knapsackSolve(int[] sack, int prospectiveSum) {
//your algorithm here
}
The recursive algorithm is straightforward. First compute the sum of the sack. If it equals
prospectiveSum then return the sack. Otherwise iterate over sack, and for each item initialise a new knapsack with that item removed. Call knapsackSolve on this. If there is a solution, return it. Otherwise proceed to the next item.
For example if we call knapsackSolve({1,2,3},5) the algorithm tries 1 + 2 + 3 = 5 which is false. So it loops through {1,2,3} and calls knapsackSolve on the sublists {2,3},{1,3} and {1,2}. knapsackSolve({2,3},5) is the one that returns a solution.
This isn't a very efficient algorithm although it illustrates fairly well how complex the Knapsack problem is!
Basically the Knapsack problem is formulated as (from Wikipedia): "Given a set of items, each with a mass and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. For your problem we are interested in weights only. So you can set all values to 1. Additionally we only want to know if the target weight can be reached exactly. I guess you are allowed to use a weight only once and not multiple times?
This problem can be solved nicely with dynamic programming. Are you familiar with that principle? Applying dynamic programming is much more elegant and quicker to program than backtracking. But if you are only allowed to do backtracking use the approach from user2738608 posted above.

Iterating over Permutations of an Array

I'm working on some java code for some research I'm working on, and need to have a way to iterate over all permutations of an ArrayList. I've looked over some previous questions asked here, but most were not quite what I want to do, and the ones that were close had answers dealing with strings and example code written in Perl, or in the case of the one implementation that seemed like it would work ... do not actually work.
Ideally I'm looking for tips/code snippets to help me write a function permute(list, i) that as i goes from 0 to list.size()! gives me every permutation of my ArrayList.
There is a way of counting from 0 to (n! - 1) that will list off all permutations of a list of n elements. The idea is to rewrite the numbers as you go using the factorial number system and interpreting the number as an encoded way of determining which permutation to use. If you're curious about this, I have a C++ implementation of this algorithm. I also once gave a talk about this, in case you'd like some visuals on the topic.
Hope this helps!
If iterating over all permutations is enough for you, see this answer: Stepping through all permutations one swap at a time .
For a given n the iterator produces all permutations of numbers 0 to (n-1).
You can simply wrap it into another iterator that converts the permutation of numbers into a permutation of your array elements. (Note that you cannot just replace int[] within the iterator with an arbitrary array/list. The algorithm needs to work with numbers.)

Persisting large array for faster access

I have a 5 dimensional array, where all indicies range from 2-14. It contains all the possible permutations of a 5 number sequence.
This array holds 525720 permutations, which takes quite a while to compute. (5-7 seconds on my Macbook pro). It should be used as a lookup table, to access a value in constant time, or more specific, the value of a certain poker-hand:
array[2][3][4][5][7] // 1
array[5][5][5][5][14] // 2000
Is there a faster way to create this array? I was thinking about persisting the array in some way, and then load it each time my program starts - but is there any efficient ways to do this?
I'm not very familiar with persistence. I dont really know if it's worth it for me, to load it from disk, instead of create it each time. I know about Hibernate, but this seems like a bit of a overkill, just to persist a single array?
Write it out via MappedByteBuffer. Create a big enough file, map it, get an asIntBuffer(), put in your numbers.
Then you can map it later and access it via IntBuffer.get(obvious-math-on-indices).
This is much faster the serialization.
Not a direct answer to your original question, but...
If you are trying to do fast poker-hand evaluations, you want to make sure you read through The Great Poker Hand Evaluator Roundup.
Particularly: Cactus Kev's Poker Hand Evaluator.
I was involved in long-running discussion about running the fastest possible 5- and 7-hand poker evaluations where most of this stuff comes from. Frankly, I don't see how these evaluations are going to any faster until you can hold all C(52,5) or 2,598,960 hand values in a look-up table.
I would start by collapsing your dimensions for indexing:
assuming you have a set of indexes (from your first example, allowed values are 2 to 14):
i1 = 2
i2 = 3
i3 = 5
i4 = 6
i5 = 7
and created your array with
short array[] = new short[13 * 13 * 13 * 13 * 13];
...
then accessing each element becomes
array[(i1 - 2) * 13 * 13 * 13 * 13 + (i2 - 2) * 13 * 13 * 13 + (i3 - 2)
* 13 * 13 + (i4 - 2) * 13 + (i5 - 2)]
This array will take much less memory since you don't need to create an additional layer of objects along each dimension, and you can easily store the entire contents in a file and load it in one list.
It will also be faster to traverse this array because you will be doing 1/5 the array lookups.
Also the tightening up of the number of elements in each dimension will save significant memory.
To keep your code clean this array should be hidden inside an object with a get and set method which takes the five indexes.
What you probably want to do, if the computation of the array is too expensive, is serialize it. That basically places a binary copy of the data onto a storage medium (e.g. your hard disk) that you can very quickly load.
Serialization is pretty straightforward. Here's a tutorial that specifically addresses serializing arrays.
Since these values will presumably only change if your algorithm for evaluating a poker hand changes, it should be fine to just ship the serialized file. The file size should be reasonable if the data you are storing in each array element is not too large (if it's a 16-bit integer for example, the file will be around 1MB in size).
I'm not convinced that your number-of-poker-hand permutations is correct but, in any case...
You can make your array initialization approximately 120-times faster by storing every permutation of a given poker hand at once. That works because the "value" of a poker hand is not affected by the order of the cards.
First calculate the value for the a hand. Say you have five cards (c1, c2, c3, c4, c5):
handValue = EvaluateHand(c1, c2, c3, c4, c5);
// Store the pre-calculated hand value in a table for faster lookup
hand[c1][c2][c3][c4][c5] = handValue;
Then assign the handValue to all permutations of that hand (i.e. the order of the cards doesn't change the handValue).
hand[c1][c2][c3][c5][c4] = handValue;
hand[c1][c2][c4][c3][c5] = handValue;
hand[c1][c2][c4][c5][c3] = handValue;
hand[c1][c2][c5][c3][c4] = handValue;
hand[c1][c2][c5][c4][c3] = handValue;
:
etc.
:
hand[c5][c4][c3][c2][c1] = handValue;
A few things:
If this is for poker hands, you can't just store 2-14. You also need to store the suit as well. This really means you need to store 0-51. Otherwise you have no way of knowing if array[2][3][4][5][6] is a straight or a straight flush.
If you don't actually need to store the suits for your application, and you really want to do it in an array, use indexes of 0-12, not 2-14. This would allow you to use a 13×13×13×13×13 (371,293 member) array, instead of a 15×15×15×15×15 (759,375 member) array. Whenever you access the array, you'd just need to subtract 2 from each index. (I'm not sure where you got your 525,720 count...)
First of all, thanks for your enthusiasm!
So the straight forward approach seems to just serialize it. I think I'll try this at first, to test the performance, and see if its sufficient. (Which I guess it is).
About the MappedByteBuffer... Is it correctly understood, that this makes it possible to load a fraction of the serialized array? So I load the values I need at run-time, instead of loading the whole array at startup?
#Jennie
The suits are stored in a different array. I'm not sure this is the best way to go, since there's lots of stuff to consider about this particular problem. A flush is basically a high-card hand, with a different value... So There's no real reason for me to store the same permutations (high cards) twice, but this is the way to do it for now. I think the way to go is a hash-function, so I can convert high-card values to flush-values easily, but I have not given this many thoughts.
About the indicies, you're of course right. This is just for now. It's easier for me to test the value for "2 3 4 5 6", by just putting in the card-values for now... Later, I'll cut of the array!

Categories