I have a Double[] array that contains about 400k double values. I want to create a List<Double[3]> array out of it.
For example: we have a list of doubles [0.00332, 1.23112, 0.241321, 2.0001 ...]
We need to transform it into another structure like: [[0.00332, 1.23112, 0.241321], [2.0001, ..., ...], [...]]
I tried to come up with something but eventually understood that I have no idea how to do this in Java in more or less concise way. Can somebody help me?
public List<double[]> toListTuple(double [] array){
List<double []> ret = new ArrayList<double[]>() ;
double [] sublist = null;
for(int i = 0;i<array.length;i++){
if(sublist == null)
sublist = new double[3];
sublist[i%3] = array[i];
if(i%3==2) {
ret.add(sublist);
sublist = null;
}
}
if(sublist!=null){
ret.add(sublist); // This means some of the last elements weren't initialized
}
return ret;
}
double[] source = getValues();
List<Double[]> dest = new List<Double[]>;
for (int i = 0; i < source.length; i += 3)
{
dest.add(new double[] {source[i], source[i + 1], source[i + 2]});
}
If you can guarantee that 3 | source.length .
There's various methods, this one will pad the last element in the array with zeroes if the original length isn't divisible by 3
List<double[]> list = new ArrayList<double[]>();
for (int i=0; i<original.length; i+=3) {
list.add( Arrays.copyOfRange(original, i, i+3) );
}
Maybe something like this:
// Create a new list (in this example, an ArrayList) to hold the values
ArrayList<double[]> myList = new ArrayList<double[]>();
// Create a temporary subArray to hold the entries you'll store
// on each entry of the list
double[] subArray;
// Traverse your original array (in this example: "myOriginalArray"
for(int i = 0; i < myOriginalArray.length; i++) {
// If the entry of the original array is the first of each three,
// initialize the temporary array
if(i % 3 == 0)
subArray = new double[3];
// Store the entry of the original array in the temp array
subArray[i % 3] = myOriginalArray[i];
// If the entry you've just stored is the last of each three
// OR if the entry of the original array is the last one,
// add the temporary array to your list
if(i % 3 == 2 || i == myOriginalArray.length - 1)
myList.add(subArray);
}
You may try Google Guava:
Double[] doubles = {3.0, 9.1, -1.1, 0.5};
List<List<Double>> doubleLists = Lists.partition(Arrays.asList(doubles), 3);
This will get you [[3.0, 9.1, -1.1], [0.5]]
I think something like this should do it:
double[] values = ....
List<double[]> list = new ArrayList<>();
for(int i = 0; i < values.length; i += 3) {
double[] d = new double[3];
d[0] = values[i];
d[1] = values[i+1];
d[2] = values[i+2];
list.add(d);
}
public static void main(String [] args){
double[] doubleArray = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
ArrayList<double[]> doublelist = new ArrayList<double[]>();
double[] innerArray = {};
for(int i=0; i<doubleArray.length; i++){
if(i%3 == 0){
innerArray = new double[3];
}
innerArray[i%3] = doubleArray[i];
if(i%3 == 2 || i == doubleArray.length-1){
doublelist.add(innerArray);
}
}
}
Related
I want the numbers in the first array that do not repeat with the numbers in the second array to go to the third array
This is what I have done till now and it doesn`t work...please help
for(int i = 0; i < isir.length; i++)
{
for(int j = 0 ; j < isir2.length; j++)
{
if(isir[i] != isir[j])
{
for(int k = 0; k < sirdif1.length; k++)
{
sirdif1[k] = isir[i];
}
}
}
}
I am entering the numbers from console with Scanner function...
With using lists and steams:
Integer a1[] = {1,2,5,6,8};
Integer a2[] = {1,3,5,7,8};
List<Integer> result = new ArrayList<>();
// Add elements from first array which ist not in the second
Arrays.stream(a1).filter(_a -> !Arrays.asList(a2).contains(_a)).forEach(result::add);
// Add elements from second array which ist not in the first
Arrays.stream(a2).filter(_a -> !Arrays.asList(a1).contains(_a)).forEach(result::add);
result.forEach(System.out::println);
Output will be:
2
6
3
7
I'd probably use Sets for clarity.
public void test() {
Integer[] a1 = {1,2,3,4,5};
Integer[] a2 = {2,3,4};
// Treat them as Sets.
Set<Integer> s1 = new HashSet<>(Arrays.asList(a1));
Set<Integer> s2 = new HashSet<>(Arrays.asList(a2));
// Get the union of both.
Set<Integer> all = new HashSet<>(s1);
all.addAll(s2);
// Find the repeating ones.
Set<Integer> common = new HashSet<>(s1);
common.retainAll(s2);
// Non-repeating is.
Set<Integer> nonRepeats = new HashSet<>(all);
nonRepeats.removeAll(common);
System.out.println(nonRepeats);
}
I would suggest good naming conventions first..variables like sirdif1(i cant even imagine how this name was decided..) really make it hard for others to read/help
int a1[] ; // Initialize array1
int a2[] ; // Initialize array2
List<Integer> tempList = new ArrayList<Integer>();
for(int i = 0; i < a2.length; i++)
{
boolean found = false; // To be able to track if the int was found in both arrays
for(int j = 0; j < a1.length; j++)
{
if(a1[j].equals(a2[i]))
{
found = true;
break; // If it exist in both arrays there is no need to look further
}
}
if(!found ) // If the same is not found in both..
tempList.add(a2[i]); // .. add to temporary list
}
//Temporary array to combine both arrays;
int[] merged= new int[isir1.length + isir1.length];
//Copy isir1 into new temporary "merged" array;
System.arraycopy(isir1, 0, merged, 0, isir1.length);
//Copy isir2 into new temporary "merged" array;
System.arraycopy(isir2, 0, merged, isir1.length, isir2.length);
//Get the unique values of array "merged" and assign them to new array;
int[] sirdif1= IntStream.of(merged).distinct().toArray();
I have any amount of arrays of integers like:
[1,9]
[5]
[7]
And I want to combine them in such a way that I get sets of numbers like:
[1,5,7]
[9,5,7]
Another Example INPUT:
[1,9]
[3,5]
[7]
[10]
OUTPUT:
[1,3,7,10]
[9,3,7,10]
[1,5,7,10]
[9,5,7,10]
I have tried nesting "for" loops but I always seem to get lost and can't get the right iterators I need to pull the right numbers when building the final array. There can be any number of integers in each array, and any number of arrays.
I have tried something like this, but it seems like a deadend:
int[][] allIndexes = {{1, 9},{5},{7}};
List<Integer> dataset1 = new ArrayList<Integer>();
//int[] dataset2 = {};
int i = 0;
for (int[] indexSet : allIndexes){
if(indexSet.length > i){
dataset1.add(indexSet[i]);
}else{
dataset1.add(indexSet[0]);
}
i++;
}
System.out.println(dataset1.toString());
//System.out.println(dataset2);
Any help would be greatly appreciated. I tried searching for others, but I really am not sure if I am defining this correctly.
You need a variable number of nested loops to enumerate all cases. Thus, recursion is your friend here. The code below will do what you're asking.
public static void main(String[] args)
{
int[][] allIndexes = {{1, 9},{3,5},{7},{10}};
List<Integer> dataset1;
if( allIndexes.length > 0)
{
int[] firstIndexes = allIndexes[0];
for( int i = 0; i < firstIndexes.length; i++)
{
dataset1 = new ArrayList<Integer>();
dataset1.add( firstIndexes[i]);
foo( dataset1, allIndexes, 1);
}
}
}
public static void foo( List<Integer> dataset1, int[][] allIndexes, int index)
{
if( index < allIndexes.length)
{
int[] indexes = allIndexes[index];
for( int i = 0; i < indexes.length; i++)
{
List<Integer> dataset = new ArrayList<Integer>();
for( Integer integer : dataset1)
dataset.add( integer);
dataset.add( indexes[i]);
foo( dataset, allIndexes, index+1);
}
}
else
{
StringBuilder sb = new StringBuilder();
sb.append( "[");
for( int i = 0; i < dataset1.size() - 1; i++)
sb.append( dataset1.get( i) + ",");
sb.append( dataset1.get( dataset1.size()-1));
sb.append( "]");
System.out.println( sb.toString());
}
}
Edit seems uoyilmaz was faster with his answer
Edit2 fixed a typo
I think a recursive approach might be worth a try.
You have your first input array and all following input arrays.
You want to get all combinations of your following input arrays and combine each of them with every element from your first input array
[1,9] // first input array
[5] // following input arrays
[7] // following input arrays
.
void GetCombinations(int[][] arrays, int startIndex, LinkedList<LinkedList<Integer>> outLists) {
// startIndex to high
if (startIndex >= arrays.length) return;
int[] firstArray = arrays[startIndex]
LinkedList<LinkedList<Integer>> subLists = new LinkedList<LinkedList<Integer>>();
// get sub-results
GetCombinations(arrays, startIndex + 1, subLists);
// combine with firstArray
if (subLists.size() == 0) {
subLists.add(new LinkedList<Integer>());
}
for (int i = 0; i < subLists.size(); ++i) {
for (int j = 0; j < firstArray.length; ++j) {
LinkedList<Integer> temp = new LinkedList<Integer>(subLists.get(i));
temp.addFirst(firstArray[j]);
outLists.add(temp);
}
}
}
You then call the function with
int[][] yourInputArrays = { ... };
LinkedList<LinkedList<Integer>> outputLists = new LinkedList<LinkedList<Integer>>();
GetCombinations(yourInputArrays, 0, outputLists);
If you are new to programming, the recursive approach might not be intuitive at first, but it is definitely worth looking into it.
I am trying to read specific elements within lines of an ArrayList. For example, an array list called Combinations of size 3 with the following lines is being produced by my code:
Combinations =
[0, 1]
[0, 2]
[1, 2]
I would like to create a loop that will read each line of the array, each element of that line, and add strings to a new array depending on the values of that array line. What should I use in order to accomplish the following pseudocode in java?
Pseudocode would be as follows
For (int i = 0; i < Combinations.size(); i++)
If Combinations(Line i, First Element) = "0"
Then NewArray(i).add("Vial1,")
If Combinations(Line i, First Element) = "1"
Then NewArray(i).add("Vial2,")
If Combinations(Line i, First Element) = "2"
Then NewArray(i).add("Vial3,")
If Combinations(Line i, Second Element)= "0"
Then NewArray(i).add(+"Vial1")
If Combinations(Line i, Second Element)= "1"
Then NewArray(i).add(+"Vial2")
If Combinations(Line i, Second Element)= "2"
Then NewArray(i).add(+"Vial3")
The resulting ArrayList would then be:
NewArray =
[Vial1,Vial2]
[Vial1,Vial3]
[Vial2,Vial3]
Below is the code which I am using to generate my Arraylist
import java.util.*;
import org.apache.commons.math3.util.CombinatoricsUtils;
public class Combinations1 {
public static void main (String[] args){
ArrayList<Integer[]> combinations = new ArrayList();
Iterator<int[]> iter = CombinatoricsUtils.combinationsIterator(3, 2);
while (iter.hasNext()) {
int[] resultint = iter.next();
Integer[] resultInteger = new Integer[2];
for (int i = 0; i < 2; i++) {
resultInteger[i] = Integer.valueOf(resultint[i]);
}
combinations.add(resultInteger);
}
for (int i = 0; i < combinations.size(); i++) {
System.out.println(Arrays.deepToString(combinations.get(i)));
}}}
Your pseudocode is a bit of a mess. You seem to be wanting to turn what is currently an array of Integers into an array of Strings.
I think you want something like this:
ArrayList<String[]> NewArray = new ArrayList<String[]>();
for (Integer[] combination : combinations) {
String[] newCombination = new String[2];
if (combination[0].intValue() == 0) {
newCombination[0] = "Vial1";
}
... etc for other possible values
if (combination[1].intValue() == 0) {
newCombination[1] = "Vial1";
}
.. etc for other values
NewArray.add(newCombination);
}
Of course if your rule is exactly 0 -> Vial1, 1 -> Vial2 etc, you don't need to handle each case separately, but instead:
newCombination[0] = "Vial" + (combination[0].intValue() + 1);
and the same for the second element. If the rule is the same for both you could just iterate over the elements of the array too. Hopefully you can figure that out for yourself.
Do you mean something like this?
String[][] newArray = new String[combinations.size()][2];
for (int i = 0; i < combinations.size(); i++) {
Integer[] eachArray = combinations.get(i);
for (int j = 0; j < eachArray.length; j++){
int elem = eachArray[j];
if (elem==0 || elem==1 || elem==2){
newArray[i][j]="Vial"+(elem+1);
}
}
}
I am trying to add all the doubles between two <end> instances into an arraylist within an arraylist (at each index of <end> have the doubles between the <end>s, and so forth)
ArrayList<ArrayList<Double>> myArr = new ArrayList<ArrayList<Double>>();
int j = 0;
int nLine = 0;
while(scan.hasNext()) {
String line = scan.next();
//System.out.println(line);
if(!line.equals("<end>")) {
nLine = Double.valueOf(line);
ArrayList<Double> row = new ArrayList<Double>();
myArr.add(row);
row.add(j, nLine);
j=j++;
} else {
j=j++;
}
}
As it stands now the code is putting in a single double in a an array (as opposed to all of the ones between statements; thus the output looks like this:
[[1.4], [3], [15], [3.2], etc. etc.
where I want it to look like this:
[[1.4, 3, 15, 3.2], [5, 13.4], [954.3, etc....
The file it is scanning is essentially:
<end>
1.4
3
15
3.2
<end>
5
13.4
<end>
954.3
43 etc. etc. (infinitely)
My goal (eventually) is to tally how many doubles are in each arrayList index and make sure none of the doubles are exactly the same, and to make sure each of the row arrays have no more than 10 values in them.
So I have been stuck and any help is appreciated.
Thanks for any help.
ArrayList<ArrayList<Double>> myArr = new ArrayList<ArrayList<Double>>();
int nLine = 0;
ArrayList<Double> currArr = null;
while(scan.hasNext()) {
String line = scan.next();
if(!line.equals("<end>")) {
nLine = Integer.valueOf(line);
currArr.add(nLine);
} else {
if(currArr!=null) myArr.add(currArr);
currArr = new ArrayList<Double>();
}
}
if(currArr!=null) myArr.add(currArr);
In the middle of the code you're using Integer instead of Double. Not sure why so I left it. Code assumes the input always starts with <end>.
You could use a HashSet as a way to keep track of the duplicates (or better yet use an ArrayList of Sets instead to avoid the extra data structure)
Here's an example of generating a random # of ArrayLists without dups:
ArrayList<ArrayList<Integer>> myArr = new ArrayList<ArrayList<Integer>>();
HashSet<Integer> duplicates = new HashSet<Integer>();
Random random = new Random();
for(int x=0; x<3; x++) {
ArrayList<Integer> row = new ArrayList<Integer>();
myArr.add(row);
for(int y=0; y<3; y++) {
int randomInt = random.nextInt(100);
if(!duplicates.contains(randomInt)) {
row.add(0,randomInt);
duplicates.add(randomInt);
}
}
}
for(int i=0;i<myArr.size();i++)
{
System.out.println(myArr.get(i));
}
I have a list in a array, each entry either contains o: or g: in front of a word, like o:word or g:word. I want 2 functions, one to make an array with just the g:'s and one to make an array with just the o:'s
I also want the g:'s and o:'s to be pruned out of the result. I'm not sure how to do this without causing array out of bounds errors and such, so I was wondering if someone could give me an example.
Smells like homework.
String[] array = ...
ArrayList<String> gList = new ArrayList<String>();
ArrayList<String> oList = new ArrayList<String>();
for (String word : array) {
if (word != null)) {
if (word.startsWith("g:"))
gList.add(word.subString(2));
else if (word.startsWith("o:")
oList.add(word.subString(2));
}
}
One way is to use ArrayLists to create the new lists. If you need to have primitive arrays after you've got the two new lists, just use toArray() on them.
You would be better off working with ArrayLists (than arrays), because you don't know in advance what size the result will be. But you can make two passes, one to count the rows with the prefix of interest, and a second to populate the new array.
int n = 0;
for (int i = 0; i < array.size; i++)
if (array[i].startsWith(prefix))
n++;
String[] result = new String[n];
int j = 0;
for (int i = 0; i < array.size; i++)
if (array[i].startsWith(prefix))
result[j++] = array[i].substring(prefix.length());
Untried, but I think that ought to do the job.
Assuming that you can mess up the original array, and that you don't need to preserve the order, this should be quite fast:
String[] array = {"o:1","o:2","g:10","o:3","g:20","o:4","g:30","g:40","o:5"};
int low = 0;
int high = array.length - 1;
while(low <= high) {
if(array[low].startsWith("g:")) {
array[low] = array[low].substring(2);
low ++;
} else if (array[high].startsWith("o:")) {
array[high] = array[high].substring(2);
high --;
} else {
String temp = array[low].substring(2);
array[low] = array[high].substring(2);
array[high] = temp;
low++;
high--;
}
}
String[] gs = new String[low];
System.arraycopy(array, 0, gs, 0, low);
String[] os = new String[array.length - low];
System.arraycopy(array, low, os, 0, array.length - low);