Say I have the following sorted array:
int[] numbers = {0, 0, 1, 2, 2, 2}.
How can I check if any sub-array of length 3 of numbers exists in the following 2-dimensional array:
int[][] sets = { {0, 0, 0}, {1, 1, 1}, {2, 2, 2} }
In this simple example, the last 3 elements of numbers are clearly contained as an array in sets, but in my actual program, sets will have far more 3 digit permutations of more numbers, but they will all remain length 3, and numbers will always be sorted.
If only the numbers less than ten are allowed, you have up to 1000 possible sequences of three numbers. Encode them as 100*ai+10*ai+1+ai+2, and store the index of the first such sequence in a 1001-element array.
In your case numbers would be translated into
0, 0, 1, 2, 2, 2
1 - 0
12 - 1
122 - 2
222 - 3
The first column is the index into 1001-element array; the second column is the value that gets placed at that index. The remaining positions of the 1001-element array are set to -1.
To see if numbers contain a three-element sequence construct 100*s0+10*s1+s2 number from them, and look it up in the 1001-element array. If you get -1, the sequence is not there; otherwise, you would get the starting index of the desired subsequence.
This is the problem I have:
http://codingbat.com/prob/p185204
Try and split an array into two of equal sum. If possible, return true, else return false.
This is my logic:
given {1, 2, 3, 4, 5, 6, 7}
{1, 2, 3, 4, 5, 6, 7} {}
{1, 2, 3, 4, 5, 6} {7}
{2, 3, 4, 5, 6} {7, 1}
{3, 4, 5, 6} {7, 1, 2}
{4, 5, 6} {7, 1, 2, 3}
{5, 6} {7, 1, 2, 3, 4}
{5, 6, 1} {7, 2, 3, 4}
{5, 6, 1, 2} {7, 3, 4}
true
but if there is no possible way to split it to get 2 equal sums, it'll go into an infinite recursion. Recursion is a requirement for this. All I need is a way to check if it's going into an infinite recursion and have it return false.
EDIT: here's some psuedo-code to hopefully help get what I'm trying to do across.
2ndArray.add(largest from 1stArray)
public attemptSplit(using 1stArray and 2ndArray)
if (1st array and 2nd array aren't equal)
get the smallest value from the array with larger sum,
and move it to the other array
else
attempSplit(using the two new arrays) //<-this is where the recursive part comes in
So, I have the base case for when it's true, that's easy. I need a base case for when it's false.
The answer to the title of your question is you cannot.
The answer to the body of your question is - you've got it wrong - you won't hit infinite recursion, you will just finish all possibilities. At that point you can return false having tried each one and found none satisfying your criteria.
All you need to do is work out an algorithm that will iterate through all possibilities. This can be done with something like:
for each entry -
move it to the other set
check to see if you have found an answer and if so report it and finish
recurse on your new smaller set
move it back
It is not possible to decide, with a program, whether another program will end or not.
More information can be found on it here: http://en.wikipedia.org/wiki/Halting_problem
As for the actual question: You will need to think up another approach.
Perhaps you can (for this problem only) decide that it is going into infinite recursion if your method has done a certain number of moves.
The typical approach to curbing rampant recursion is to include a depth argument to the function call and increment it each time you recurse.
The first thing your function should do is check that the depth has not crossed a limit that you think would be unlikely to happen except in the case of an infinite recursion trap.
Then you throw an exception or at least stop the tailspin before the stack overflows.
EDIT: The other responders are correct, however, that your algorithm is flawed and a correct solution to this problem would require no such failsafe.
You can't just evenly divide the numbers and rely on only the lowest to split.. Actually it could be that one of the larger elements need to switch with several of the smaller numbers in solutions. You need to be able to iterate over all the possible permutations!
So every element can either be in the first bucket or the second so you could have a number representing if one element is in either bucket 0 or bucket 1. An integer has 32 bits, but we need to reserve two bits. Thus this will work for an array with 0-30 elements:
/** Find how to split an array of integers
into two even groups.
#param lst array of elements to be split
#return the bitmask or -1 if no solution exist
**/
public static int findSplit( int[] lst )
{
int lstLen = lst.length;
int maxMask = 1 << lstLen;
for(int mask=0; mask < maxMask; mask++) {
int[] c = {0,0};
for(int i=0, curMask=mask; i < lstLen; i++, curMask>>=1 ) {
c[curMask&1]+= lst[i];
}
if( c[0] == c[1] )
return mask;
}
return -1;
}
This will not solve you problem since you are required to use recursion, but both for loops can easily be replaced with one helper function.
public attemptSplit(using 1stArray and 2ndArray)
if (1st array and 2nd array aren't equal)
get the smallest value from the array with larger sum,
and move it to the other array
else
attempSplit(using the two new arrays) //<-this is where the recursive part comes in
OK, that's more information, but it's still somewhat confusing. The way this is written, if the 1st array and 2nd array are equal (I assume you mean the sums), which is the "else" part of your pseudo-code, I think this is when you want to return true since you've found a solution--you wouldn't want to recurse again.
Maybe you meant something like this?
if (1st array and 2nd array aren't equal)
get the smallest value from the array with larger sum,
and move it to the other array
attempSplit(using the two new arrays)
else
return true
There's an obvious problem here, that there's nothing in your algorithm that ever returns false. But the less obvious problem is that this approach just won't work, if I understand what you're trying to do; it could recurse infinitely even when the result should be true. Try with {1, 3, 6, 7, 10, 11}; it looks like your approach is to pull out the largest number into your first set:
{1, 3, 6, 7, 10} {11}
Then if the two sets have different sums, determine which set has the larger sum, and move the smallest number from that set to the other. This will give
{3, 6, 7, 10} {11, 1}
{6, 7, 10} {11, 1, 3}
{7, 10} {11, 1, 3, 6} -- now the right-hand set has a larger sum
{1, 7, 10} {11, 3, 6}
{1, 3, 7, 10} {11, 6} -- now the left-hand set is larger
{3, 7, 10} {11, 1, 6}
{7, 10} {11, 1, 3, 6}
and you're in an infinite loop now. You never get 11 and 7 together in the same set, which you need to do to solve the problem. Perhaps I don't understand exactly what you're trying to do, and maybe you left some steps out; but I think your approach is faulty.
Here's an outline of how I'd approach it: I'm assuming all the array elements are positive integers. First of all, if the sum of the entire array is N, and you can split it into two parts with equals sums, each part will add to N/2. If N is odd, just give up. Otherwise, try to find a subset whose sum is N/2. You can do this with recursion by writing a recursive routine findSubset(S,M) which finds a subset of S whose sum is M. To do this: Assume S1, S2, S3, ... are the elements of S in order. If one of the elements equals M, then you've found a one-element subset. If M<=0 or all the elements of S are larger than M, or if S is empty, then fail. Else: try findSubset({S2,S3, ...}, M-S1); if that doesn't work, findSubset({S3,S4,...}, M-S2); if that doesn't work, findSubset({S4,S5,...},M-S3), and so on.
Sorry first time asking a question here.
If I have a 2D Array like this:
int[][] array2d = {{1, 2, 3}, {6, 7, 8}};
How do I add multiple 1D Arrays like this:
int[] array1d = {3, 2, 1};
int[] array1d2 = {8, 7, 6};
so that my original 2d array becomes this:
int[][] array2d = {{1, 2, 3}, {6, 7, 8}, {3, 2, 1}, {8, 7, 6}};
Note: this is for adding information from a JTextfield into a JTable whenever a button is pressed. So, the 2d array will be used as the data inside the table. If there is a better way to accomplish this I would appreciate it too. =)
Your array :
int[][] array2d = {{1, 2, 3}, {6, 7, 8}};
is fixed in size, so you would have to create a copy with enough capacity to hold the new values:
int[][] newArray = Arrays.copyOf(array2d, 4);
newArray[2] = array1d;
newArray[3] = array1d2;
To add your data to the JTable the arrays would have to be first converted to a non-primitive type such as an Integer array. One option is to use the Apache Commons:
model.addRow(ArrayUtils.toObject(array));
for each row of the array.
arrays are fixed size so to append it you need to resize the array look at java.util.Arrays.
then set the arrays location
arra2d[index] = array1d;
is there are reason you are not using
TableModel.addRow(dataArray);
?
So i am trying to understand multidimensional arrays a little better. So far, I understand there are 2 way to construct these arrays. One is
int[][] b = { { 1, 2 }, { 3, 4, 5 } };
The first array constructs row 0 with 2 columns ( column 0 and column 1). What i don't understand is why are these numbers chosen. Does it always have to be in numerical order, or do the numbers mean something more? If i were to create a new row would it start with 6? Would it just be better for me to construct it this way?
int[][] b = new int [2][];
b[0] = new int [2];
b[1] = new int [3];
Thanks for your help.
Those numbers are meant to be examples. You need not start your next row with "6" if it's not what your solution demands.
Either manner of construction is acceptable. You'd use the second one if you had to compute the values and didn't know them beforehand.
1, 2, 3, 4, and 5 are just data that got entered in this new array.
The array would look like this:
[
[1, 2]
[3, 4, 5]
]
so [0][0] = 1; [1][0] = 3, [1][2] = 5 etc
Those values are just chosen as example.
First: there is no multi-dimensional arrays in Java. There are only arrays containing arrays. Arrays of arrays if you prefer.
int[][] b = { { 1, 2 }, { 3, 4, 5 } };
constructs an array containing 2 arrays of int. The first array contains the numbers 1 and 2, and the second contains the numbers 3, 4 and 5. These numbers could be anything you want. The line declares and populates the array at the same time.
int[][] b = new int [2][];
b[0] = new int [2];
b[1] = new int [3];
constructs an array of arrays of ints, containing two null elements. Then, the first element of the outer array is initialized with an array of 2 ints, and the second element of the outer array is initialized with an array of 3 ints. All the ints are initialized to their default value: 0.
suppose I have arraylist of integers...is there a way that I can generate a random permutation/arrangement of the elements in the arraylist
so if the list is {1,2,3,4,5,6}
calling some method randomPermute() would change it to something random like
{1,3,2,6,5,4}
Collections.shuffle() does the job:
public static void shuffle(List<?> list) -
Randomly permutes the specified list using a default source of randomness. All permutations occur with approximately equal likelihood.
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle(java.util.List)
For example
ArrayList<Integer>anArrayList = new ArrayList<Integer>();
anArrayList.add(1);
anArrayList.add(2);
anArrayList.add(3);
anArrayList.add(4);
anArrayList.add(5);
System.out.println(anArrayList);
Collections.shuffle(anArrayList);
System.out.println(anArrayList);
Sample Output
[1, 2, 3, 4, 5]
[3, 5, 1, 2, 4]
You can use the Knuth shuffle: go through the positions 1 through n−1, and for each position i swap the element currently there with an arbitrarily chosen element from positions i through n, inclusive.
Edit: The answer by hooch is better. :)
A simple example:
ArrayList<MyObject> myObjects = new ArrayList<MyObject>();
//code -- load myObjects...
Collections.shuffle(myObjects);