Is there a way i could return in an array the common elements of 2 or more arrays? I know having some of the methods under lists could do it but is there a way to do it by only using arrays? I made my own get and length btw since i am creating a an array called OrderedIntList.
Example would be:
1,3,5
1,6,7,9,3
1,3,10,11
Result: 1,3
I tried this and it outputs the common elements between two arrays and not all.
I know there's something wrong but i do not how to make it work like it suppose to work :(
//returns the common elements of inputted arrays
public static OrderedIntList common(OrderedIntList ... lists){
int[] list = new int[10];
for(int x = 1; x <= lists.length -1; x++){
for(int q = 0; q < lists[0].length()-1; q++) {
for(int z = 0; z < lists[x].length(); z++) {
if (lists[0].get(q)==lists[x].get(z)){
list[q] = lists[0].get(q);
}
}
}
}
OrderedIntList newlist = new OrderedIntList(list);
return newlist;
}
This can be an easy algorithm to solve it...
1) Instantiate an instance variable of type array called
"commonElements" pointing to the elements of the first Array. At the
beginning these are your common elements.
2) Create a method call getCommonElements(int[] commonElements,
int[] newList). This method manipulates the commonElements array to leave
it with only the common elements between the two. (p.s Use a temporary
array to achieve this if you find it easier)
3) Iterate over all the arrays present in "lists" starting from the
second array.
4) call the method at point 2 for each array .
All the difficult part for you it's to implement a method that given 2 arrays finds the common elements!
You can use
org.apache.commons.collections.CollectionUtils.intersection(java.util.Collection a, java.util.Collection b)
to get the intersection of two lists (elements presents in both lists)
And to pass your array as a Collection: java.util.Arrays.asList(Object[] a);
But working on arrays is tedious, at best. You should consider why you don't want to use a Collection...
As a partial answer, you're probably doing too much work by fully reimplementing an OrderedIntList the way you're doing, since ArrayList and friends already come with sorting baked in via the Collections class.
import java.util.Collections;
public class OrderedIntList extends ArrayList<Integer> {
#override // to effect sorted inserts
public void add(Integer i) {
this.add(i);
Collections.sort(this);
// done.
}
}
Wanting to do this for pure arrays is a nice exercise, but then you'll be better of implementing sorting properly with a quick sort (you can't websearch for a java implementation of that without getting a million results) or an insert sort (equally websearchable), and follow the same recipe.
any time you push a number into the array:
guess where the number goes (although that's optional),
insert the number,
resort your array if you know your guess wasn't perfect.
Related
I was using Arrays.sort() function to sort 2d array (int[][] array). Since I want to sort it base on the first element. For example, {{2,3},{1,4}} base on 1st element the array will be {{1,4},{2,3}}. So I override the compare function.
Arrays.sort(arr, new Comparator<int[]>() {
#Override
public int compare(int[] o1, int[] o2){
if(o1[0] < o2[0]){
return -1;
} else if (o1[0] > o2[0]) {
return 1;
} else {
return 0;
}
}
})
I know this sort work. But I don't understand how this compare work.
I was thinking the
new Comparator<int[]>
should be
new Comparator<int[][]>
since this is 2d array. and inside of compare function should be compare
o1[0][0] and o2[0][0]
Can anyone help me understand it?
Also this is using Arrays.sort, can I use Collections.sort? what is different between it?
Thanks
Remember that a "2D array" doesn't actually exist in Java, so what you're really dealing with is "an array of int[]" (there's nothing inherently preventing each of those int[] from being a different length).
So: when you sort, you're comparing individual elements of that "array of int[]" with each other, and because each element is an int[], your Comparator is for int[], too.
You are passing the array in the sort method and giving it a comparator. Arrays.sort will use iterator to pass into compare method. So compare method is checking element at arr[0].compare(arr[1]) sorts these 2 and goes to next iterator. same concept applies using 2d array. You are just passing 2 arrays and telling compare who should be placed where.
An assignment we have to do in school is alphabetically sort two different ArrayLists into a final arraylist that contains both of the lists elements lexicographically
For example...
ArrayList sent1 contains in alphabetical order [., adam, mark]
ArrayList sent2 contains in alphabetical order [., betsy, kyle, william]
ArrayList sent3 must contain all of the elements in both ArrayLists in alphabetical order.
I just can't seem to figure out how to do it. My instructor mentioned using a while loop, but I don't just understand how to code the process. Combining sent1 and sent2 into sent3 and then using Collections.sort(sent3) would make the process so much easier and more compact, but the goal of the lab is to practice the using of compareTo().
If each source list is already sorted, just look at the first element in each list, add the "lower" (alphabetically first) to the output list, and repeat.
It's pretty simple;
List<String> sent3 = new ArrayList<String>(sent1);
sent3.addAll(sent2);
Collections.sort(sent3, new Comparator<String>() {
public int compare(String a, String b) {
return a.compareTo(b); // usage here!
}
}
What you are looking for is to use 2 iterators and just merge these 2 lists.
I'll give you some pseudo code.
ArrayList sent1, sent2, sent3;
int i1, i2;
i1 = i2 = 0;
while (i1 < sent1.length() && i2 < sent2.length())
{
if (sent1[i2].compareTo(sent2[i1])
{
sent3.add(sent1[i2]);
i2++;
}else
{
sent3.add(sent1[i1]);
i21+;
}
}
while(i1 < sent1.length()) sent3.add(sent1[i1++]);
while(i2 < sent2.length()) sent3.add(sent2[i2++]);
Here each time will add to my sent3 the minimum of the first items in sent1 and sent2. And when I get one of this lists empty, I will just append the rest of other elements into the sent3.
I think that you can do this:
copy array1 and array2 to array3; then, sort array3. you don't know how to sort using compareTo() ? Check is java documentation.
I am working on a sudoku solving program and I need an arraylist that holds the numbers 1 thru 9 for each of the squares on the 9x9 board. Each of these arraylists correspond to the possible numbers that could go in that square, if a number can not go in that square, it is removed from the list.
I want to be able to pull up the arraylist of the current square it is working on, like for example if I wanted to remove the number 7 from the arraylist corresponding to square (3,5)
arrayOfLists[3][5].remove(Integer.valueOf(7));
However I can't figure out how to do this. When I try to create the array I am getting this error on the line where I declare my array of arraylists
Cannot create a generic array of ArrayList
Here is my code:
//create arraylist
ArrayList<Integer> nums = new ArrayList<Integer>();
//fill arraylist with numbers 1-9
for (int i = 1; i < 10; i++) {
nums.add(i);
}
//create 9x9 array of arraylists
ArrayList<Integer>[][] array = new ArrayList<Integer>[9][9];
//fill each element of array with arraylist of numbers 1-9
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
array[i][j] = nums;
}
}
}
Am I doing this incorrectly or is it not possible to create an array of arraylists? If it is not possible, how should I do this then?
Anytime I see a list of lists, alarm bells start ringing. The situations where you actually want such a thing are rare indeed, and this is not one of them.
You've got a fixed board consisting of 9 fixed squares, columns and rows, each position of which may take a number 1-9.
Use an array for all of these concepts, because they are fixed in size and you need direct access to each element - collections offer no benefit and would be a hindrance. Use logic (possibly sets) to ensure numbers are used only once in each zone.
Use a bit field instead of an array list. That is, use an integer where bits 1-9 represent the possibilities of the numbers. Testing, adding, removing a single number is O(1), and it has a fixed memory size. Encapsulate the integer in its own object that knows the operations.
A few things:
1) In your for loop, array[i][j] = nums; This is going to result in the same object in each element of the array. If you call remove() on one element of the array, it's going to affect all the others. You want to build a separate list object for each element.
2) Program to interfaces; declare nums as a List as opposed to ArrayList.
3) Use a List of Lists as opposed to any array of Lists.
List<List<List<Integer>>> list = new ArrayList<List<List<Integer>>>();
for(int i = 0; i<9; i++){
List<List<Integer>> row = new ArrayList<List<Integer>>();
for(int j = 0; j<9; j++){
List<Integer> nums = new ArrayList<Integer>();
for (int k = 1; k < 10; k++) {
nums.add(i);
}
row.add(nums);
}
list.add(row);
}
// You can still get an element by index
int x = list.get(3).get(1).remove(6);
But this is kind of unwieldy. You might want to consider writing a class that represents the board. That way you'll at least have operations that better abstract this.
You could completely remove the use 2d stuff and keep a single list by giving each square a unique number from 1...81. So if you are working with 3,5 cell that means it's the 9*2+5 = 23rd item in the list. That will greatly simplify the list manipulation. You could use a single method to give the unique cell index given the (3,5) kind of reference
OK, I'm going to post this as an answer since it seems to work for me and I haven't yet seen any pitfalls.
private static class IntegerArrayList extends ArrayList<Integer> {
IntegerArrayList () { super(); }
IntegerArrayList (Collection<? extends Integer> c) { super(c); }
IntegerArrayList (int initialCapacity) { super(initialCapacity); }
}
Now you can say something like
IntegerArrayList[][] array = new IntegerArrayList[9][9];
and elements like array[1][2] will inherit all the ArrayList methods (array[1][2].remove(something) works fine). I made the class private static thinking you could nest it in some other class if that's the only place you'll use it, but you can make it public if you like. Also, I copied all three constructors from ArrayList; you could eliminate unneeded ones but I don't see a compelling reason to.
I think the issue is that new ArrayList<Integer>[9][9] is prohibited because it would create an array that wouldn't do type checking (because of "type erasure"). But I think adding your own non-generic type that inherits from ArrayList<Integer> restores the type safety.
But I'm not a generic expert, and it wouldn't surprise me if someone more knowledgeable than I spots a problem with this solution. But it seemed to work fine for me, with no compiler warnings about unchecked type stuff or anything.
(P.S. I'm posting this as a possible general solution to a problem that gets asked a lot. But in reality, for this particular problem, I might just use a fixed-size array of boolean instead of an ArrayList, like others, or I might even do bit-diddling on integers if speed is a real issue.)
I have 2 arrays of data in Java. Based on the order of first array I have to sort the next array.
E.g -
String[] Array1 = {"EUROPE","MIDDLEEAST","OTHERs","AUSTRALIA"};
String[] Array2 = {"MIDDLEEAST","EUROPE","AUSTRALIA","OTHERs","ASIA","EUROPE"};
My output should look like:
{"EUROPE","EUROPE","MIDDLEEAST","OTHERs","AUSTRALIA","ASIA"}
What is the best way to do it?
To sort you need to define a sorting order so given element A and B, you can determine easily if A should go before or after B in the sorted list.
This concept is formalized with the concept of a Comparator in Java.
In this case the sorting order is defined by the order of the elements in a list. The simplest approach is given A and B to find each of them in the original list, note the index found, and compare the indexes to find out which one goes first.
Depending on the size of your data this might be too slow. You can then create a HashMap<String,Long> which holds the index of a given string in Array1. Here it would hold "DEF"->0, "ABC"->1, "XYZ"->2.
May be this:
1) Sort both of them.
2) Create blank result table
3) Take first elem from sorted Array2 and put it to result table with the original index of the first elem on sorted Array1
3) Repeat the step 3 on the second element and so on.
The computational complexity would be like sorting method used: O(nlogn) for quicksort
You can definitely do this in O(n log n). But the best approach depends on what is more important: quick, clean code or not allocating extra memory.
If you don't care about using extra memory, you can allocate a separate array, where each element is a pair:
public class Pair implements Comparable {
...
}
Then you would sort the array of pairs using Arrays.sort(Object[]).
If you don't want to allocate quite so much space, you can use an auxiliary array that contains the indexes in Integer form:
final String[] array1 = ...;
final String[] array2 = ...;
assert array1.length == array2.length;
Comparator<Integer> c = new Comparator<Integer> {
int compare(Integer a, Integer b) {
return array1[a].compareTo(array1[b]);
}
};
Integer[] aux = new Integer[array1.length];
for (int i = 0; i < aux.length; ++i) { aux[i] = i; }
Arrays.sort(aux, c);
String[] result = new String[array1.length];
for (int i = 0; i < aux.length; ++i) {
result[i] = array2[aux[i]];
}
If you are trying to do the entire thing in-place and not allocate additional memory, then you will need to implement one of the n-log-n sort algorithms yourself...
There are (at least) two ways to sort one array and reorder a second array so corresponding elements still match. Both require constructing a third array and writing a custom comparison function.
Method 1
Define a custom object that contains one element of each array. (In your case, it might be a two-element String array.) Write a comparator (or implement Comparable) for the custom object that simply compares the elements from the first array. Build an array of the custom objects from the two input arrays, sort the third array, and then extract the results.
This is the method most commonly recommended for this problem.
Method 2
Construct an array of Integer indexes initialized to 0, 1, 2, ..., n-1 (where n == Array1.length). Sort the index array using a comparator that compares indexes by comparing the Array1 elements that they index.
The second method will be faster and will not require as much object construction.
Two other ideas:
Could these values be an enum rather than a set of strings? The natural order of an enum is the order of declaration, so Arrays.sort() would just work.
Helper code exists in Guava's Ordering.explicitOrder(List):
String[] explicitOrder = {"EUROPE", "MIDDLEEAST", "OTHERs", "AUSTRALIA"};
String[] toSort = ...
Comparator<String> comparator = Ordering.explicit(Arrays.asList(explicitOrder));
String[] sorted = Arrays.sort(toSort, comparator);
I was wondering what the simplest way would be to implement an array who's rank is specified at runtime.
The example I am working on stores a array of boolean values for lattice points, and I want the user to be able to chose how many spatial dimensions the model uses at runtime.
I've looked at the Array.newInstance() method:
dimensionOfSpace = userInputValue; // this value comes from GUI or whatever
int latticeLength = 5; // square lattice for simplicity
int[] dimensions = new int[dimensionOfSpace];
for(int i = 0; i < l.length; i++) l[i] = length;
Object lattice = Array.newInstance(boolean.class, dimensions);
But accessing these values in any sort of way seems to require horribly slow methods such as recursively using Array.get until the returned value is no longer an array, i.e. using isArray().
Am I missing an obvious solution here? I would love to be able to access the values in a way similar to foo[i][j][k].
Looks like what you are looking for is for some way to declare how many dimensions an array has at runtime. I don't know how this could be done using a multidimensional ArrayList, or any multidimensional structure where you have to specify the dimensionality at compile time.
The only answer I see is to use a simple linear array wrapped in a class that converts multidimensional coordinate to and from the its position in the underlying array. This is basically how languages such as C stores multidimensional arrays by using one contiguous chunk of memory.
The code would look something like this:
import java.util.*;
class MultiArray<T>{
private int[] dimensions;
private Object[] array;
public MultiArray(int ... dimensions){
this.dimensions=dimensions;
//Utils.product returns the product of the ints in an array
array=new Object[Utils.product(dimensions)];
}
public void set(T value, int ... coords){
int pos=computePos(coords);
array[pos]=value;
}
public T get(int ... coords){
int pos=computePos(coords);
return (T)(array[pos]);
}
private int computePos(int[] coords){
int pos=0;
int factor=1;
for (int i=0;i<coords.length;i++){
pos+=factor*coords[i];
factor*=dimensions[i];
}
return pos;
}
}
class Main{
public static void main(String args[]){
MultiArray<Integer> m=new MultiArray<Integer>(new int[]{5,4,3});
Random r=new Random();
for(int i=0;i<5;i++)
for(int j=0;j<4;j++)
for(int k=0;k<3;k++)
m.set(r.nextInt(),i,j,k);
for(int i=0;i<5;i++){
for(int j=0;j<4;j++){
for(int k=0;k<3;k++)
System.out.print(m.get(i,j,k)+" ");
System.out.println("");
}
System.out.println("\n");
}
}
}
class Utils{
public static int product(int...a){
int ret=1;
for (int x:a) ret*=x;
return ret;
}
}
Checkout Java Collections. It contains a class called ArrayList that grows in size as needed.
One dimensional
List<Boolean> a = new ArrayList<Boolean>();
Two Dimensional
List<List<Boolean>> b = new List<List<Boolean>>();
Three Dimensional
List<List<List<Boolean>>> c = new List<List<List<Boolean>>>();
And you'd access the item as c.get(i).get(j).get(k) instead of c[i][j][k] as in a 3d array. Or even better, wrap it in your own Class, and use a get() method there. So it becomes:
c.get(i, j, k);
Edit:
To have a multi-dimensional list of depth N, remove the Boolean type indictor and simply create lists as
List level1 = new ArrayList();
List level2 = new ArrayList();
List level3 = new ArrayList();
level1.add(level2);
level2.add(level3);
and so on..
I'm going to use the term 'rank' to mean the 'number-of-dimensions' in your array. So a vector has rank 1, a matrix has rank 2 and so on. You've already accepted an answer that by your own admission is not quite what you want. Here's an alternative to settling for less:
Recall that computer memory is essentially linear and that what a compiler does when it gives you arrays is actually take care of transforming an index expression into a linear address. This is simplest to think about if you assume that all arrays are in contiguous memory, not always true. Suppose that you make a declaration such as ARRAY_OF_TYPE[10][10][10], ie it has 1000 elements. Then the element at position [3][5][4] is (my arrays are indexed from 1 not 0 -- change the sums that follow if you want to) at location baseAddress+354*size_of_element_of_TYPE.
I expect you know where I'm going on this by now ...
At run time your program prompts for a list of integers from the user. Each integer specifies the size of one of the dimensions of the array, the number of integers specifies the rank of the array. Your program does some multiplications and you allocate a vector of the right length. OK, you have to write the indexing and de-indexing functions, but these should be fairly straightforward.
et voila you have an array whose rank is established at run time.
I did a quick google search for "java tensor" which came up with DJEP, could that be something which fits your bill?