Related
I have 3 arrays of random length. I want to create a new array that stores the largest value from comparing those 3 arrays at each index.
int size1=x.length;
int size2=y.length;
int size3=z.length;
int size=0;
if (size1>=size2 && size1>=size3)
size=size1;
else if (size2>=size1 &&size2>=size3) {
size=size2;
}
else if (size3>=size1 && size3>=size2) {
size=size3;
}
int[] largest= new int[size];
int[] x= {1, 4, 6}; // random array length from 1-5 and hypothetically each array hold these values
int[] y= {2, 4};
int[] z= {5, 6, 7, 8, 9};
// ideally after some sort of an algorithm largest[] should hold {5, 6, 7, 8, 9}
I initially thought of a for loop, but my loop will eventually throw me a out of bound exception, because of the random size length nature of the arrays and x/y/z won't hold a value at index [i]. Any other ways?
for (int i=0;i<size;i++) {
if (x[i]>y[i]) && t1[i]>t3[i]) {
largest[i]=x[i];
}
else if (y[i]>x[i]) && y[i]>z[i]) {
largest[i]=y[i];
}
else if (z[i]>x[i]) && z[i]>y[i]) {
largest[i]=z[i];
}
}
There are several ways of doing this. Here's one that avoids a ton of conditional statements at the cost of more memory.
int size = Math.max(x.length, Math.max(y.length, z.length));
int[] nooX = new int[size];
int[] nooY = new int[size];
int[] nooZ = new int[size];
// Copy over the values from x to the new array
for(int i = 0; i < x.length; i++){
nooX[i] = x[i];
}
// ... Copy paste the above and do the same for arrays nooY and nooZ
int[] largest = new int[size];
// ... Copy paste your code, using nooX, nooY, and nooZ instead of x, y, and z
A simpler approach without creating extra arrays to equalize size:
public static int[] getMaxValues(int[] x, int[] y, int[] z) {
int size = Math.max(x.length, Math.max(y.length, z.length));
int[] max = new int[size];
for (int i = 0; i < size; i++) {
int xi = i < x.length ? x[i] : Integer.MIN_VALUE;
int yi = i < y.length ? y[i] : Integer.MIN_VALUE;
int zi = i < z.length ? z[i] : Integer.MIN_VALUE;
max[i] = Math.max(xi, Math.max(yi, zi));
}
return max;
}
Test:
int[] x= {4, 4, 6}; // random array length from 1-5 and hypothetically each array hold these values
int[] y= {2, 10};
int[] z= {3, 6, 7, 8, 9};
System.out.println(Arrays.toString(getMaxValues(x, y, z)));
Output:
[4, 10, 7, 8, 9]
Update
Defining a couple of functions allows to create the following implementation using Stream API that would be able to handle non-hardcoded number of arrays:
private static int getAtIndex(int[] arr, int i) {
return i < arr.length ? arr[i] : Integer.MIN_VALUE;
}
private static int getMax(IntStream values) {
return values.max().getAsInt();
}
// use Supplier to be able to use stream of the arrays twice
public static int[] getMaxValues(Supplier<Stream<int[]>> arrs) {
return IntStream.range(0, getMax(arrs.get().mapToInt(arr -> arr.length)))
.map(i -> getMax(arrs.get().mapToInt(arr -> getAtIndex(arr, i))))
.toArray();
}
Test:
int[] maxValues = getMaxValues(() -> Stream.of(x, y, z)); // supply stream of arrays
System.out.println(Arrays.toString(maxValues));
I think we should think this way
array1 = 1, 2, 3, 4, 6, 7
array2 = 3, 4, 5, 6, 23, 4
array3 = 5, 5, 32, 3, 2, 43, 56
Like a matrix
1 2 3 4 6 7
3 4 5 6 23 4
5 5 32 3 2 43 56
We need is the greatest value in every column.
largestArr = 5, 5, 32, 6, 23, 43, 56 <-- Like this
I hope this code is the answer to your problem.
public static int[] largestColumnsArr(int arr1[], int arr2[], int arr3[]) {
int[][] arr = {arr1, arr2, arr3};
//The size of the largest sized array
int size = Math.max(arr3.length, Math.max(arr2.length, arr1.length));
int[] largestArr = new int[size];
/*
Takes the largest value in each column and assigns it to the array
If it is try catch, if the size of the arrays is exceeded, the program exit is blocked.
*/
for (int i = 0; i < size; i++) {
int largestColumnValue = 0;
try {
for (int j = 0; j < arr.length; j++) {
if (largestColumnValue < arr[j][i]) {
largestColumnValue = arr[j][i];
}
}
} catch (Exception e) {
}
largestArr[i] = largestColumnValue;
}
return largestArr;
}
I want to evenly distribute a list into a given number of sublists.
For example, I have a list with elements 1 to 10 and I want 3 lists. These should look like:
SL1 -> {1, 2, 3, 4}
SL2 -> {5, 6, 7}
SL3 -> {8, 9, 10}
Important: What each list contains is not relevant, i.e. SL1 could have {1, 5, 7, 10}. The most important thing is that there are 2 lists with size 3 and 1 list with size 4.
I have tried several things, including the Iterables.partition but that won't help.
The only thing I've come up with that works is:
public Iterable<List<Integer>> distributeEvenlyQueryListIntoLists(final LinkedList<Integer> bigList, final Integer numberOfSublists) {
List<List<Integer>> result = new ArrayList<>();
// Creates as many lists as needed
for (int i = 0; i < numberOfSublists; i++) {
result.add(new ArrayList<>());
}
while (bigList.iterator().hasNext()) {
for (int i = 0; i < numberOfSublists; i++) {
if (!bigList.iterator().hasNext()) {
break;
}
result.get(i).add(bigList.poll());
}
}
return result;
}
The passed bigList does not have to be a LinkedList, it can be any Iterable.
I especially hate the first loop where I create the sublists.
Thanks!
Just distribute them in a round-robin pattern:
public <T> List<List<T>> partition(Iterable<T> iterable, int partitions){
List<List<T>> result = new ArrayList<>(partitions);
for(int i = 0; i < partitions; i++)
result.add(new ArrayList<>());
Iterator<T> iterator = iterable.iterator()
for(int i = 0; iterator.hasNext(); i++)
result.get(i % partitions).add(iterator.next());
return result;
}
A sample run with this code:
List<String> l = Stream.iterate(0, i->i + 1).limit(25).map(i->Integer.toString(i)).collect(Collectors.toList());
System.out.println(partition(l, 4).toString());
Produces
[[0, 4, 8, 12, 16, 20, 24], [1, 5, 9, 13, 17, 21], [2, 6, 10, 14, 18, 22], [3, 7, 11, 15, 19, 23]]
The basic idea is to add a single element to each list in the result set roundwise. This way it's guaranteed that the difference in the number of elements between two lists never exceeds 1.
As an alternative you could use guavas implementation of Iterables.partition, which takes a slightly different approach.
If you hate creating sublists, that implies you're looking for a fast solution. If you have the original List, and you plan on not altering the original List, consider List.subList().
int subSize = bigList.length() / numSubs;
int numBigSubs = 0; // # of subs that need to be one bigger
if (bigList.length() % numSubs > 0) {
subSize++;
numBigSubs = bigList.length() % numSubs;
}
int from = 0;
int to = subSize;
List<List<Integer>> subList = new ArrayList<List<Integer>>(numSubs);
for (int i = 0; i < numSubs; i++) {
List<Integer> newSub = bigList.subList(from, to);
subList.add (newSub);
from = to;
to += subSize;
if (i >= numBigSubs && numBigSubs > 0) to--;
}
Note: I wrote this without testing - if it fails, I apologize, and hope someone will edit it to work.
Again, the big upside to this is that it should be wicked fast - all the sublists are simply views into the larger one. The downside is that if you change the list, all bets are off.
You can use org.apache.commons.collections4.ListUtils to create equal size sublists.
List<String> bigList = ...
int batchSize = 1000;
List<List<String>> smallerLists = ListUtils.partition(bigList, batchSize);
Here is the program task:
Write a method called collapse that accepts an array of integers as a parameter and returns a new array containing the result of replacing each pair of integers with the sum of that pair.
For example, if an array called list stores the values
{7, 2, 8, 9, 4, 13, 7, 1, 9, 10}
then the call of collapse(list) should return a new array containing:
{9, 17, 17, 8, 19}.
The first pair from the original list is collapsed into 9 (7 + 2), the second pair is collapsed into 17 (8 + 9), and so on. If the list stores an odd number of elements, the final element is not collapsed.
For example, if the list had been {1, 2, 3, 4, 5}, then the call would return {3, 7, 5}. Your method should not change the array that is passed as a parameter.
Here is my currently-written program:
public static int[] collapse(int[] a1) {
int newArrayLength = a1.length / 2;
int[] collapsed = new int[newArrayLength];
int firstTwoSums = 0;
for (int i = 0; i < a1.length-1; i++) {
firstTwoSums = a1[i] + a1[i+1];
collapsed[collapsed.length-1] = firstTwoSums;
}
return collapsed;
}
I pass in an array of {7, 2, 8, 9, 4, 13, 7, 1, 9, 10} and I want to replace this array with {9, 17, 17, 8, 19}.
Note:{9, 17, 17, 8, 19} will be obtained through the for-loop that I have written.
Currently, I am having trouble with adding the integers I obtained to my "collapsed" array. It'd be a great help if you could help me or at least give me some guidance on how to do this.
Thanks in advance!
First you have to understand what is going on.
You have an array of certain size where size can either be even or odd. This is important because you are using a1.length/2 to set the size for new array, so you will also have to check for odd and even values to set the size right else it won't work for odd sized arrays. Try a few cases for better understanding.
Here's a way of doing it.
public static int[] collapseThis(int[] array) {
int size = 0;
if(isEven(array.length))
size = array.length/2;
else
size = array.length/2+1;
int[] collapsedArray = new int[size];
for(int i=0, j=0; j<=size-1; i++, j++) {
if(j==size-1 && !isEven(array.length)) {
collapsedArray[j] = array[2*i];
}
else {
collapsedArray[j] = array[2*i]+array[2*i+1];
}
}
return collapsedArray;
}
private static boolean isEven(int num) {
return (num % 2 == 0);
}
Using
collapsed[collapsed.length-1] = firstTwoSums;
The sum of your numbers will be always be put in the same index of the collapsed array, because collapsed.length - 1 is a constant value.
Try creating a new variable starting at zero, that can be incremented each time you add a sum to collapsed. For instance,
int j = 0;
for(...) {
...
collapsed[j++] = firstTwoSums;
}
I think this is a convenient answer.
public static void main(String[] args){
int[] numbers = {1,2,3,4,5};
int[] newList = collapse(numbers);
System.out.println(Arrays.toString(newList));
}
public static int[] collapse(int[] data){
int[] newList = new int[(data.length + 1)/2];
int count = 0;
for (int i = 0; i < (data.length / 2); i++){
newList[i] = data[count] + data[count + 1];
System.out.println(newList[i]);
count = count + 2;
}
if (data.length % 2 == 1){
newList[(data.length / 2)] = data[data.length - 1];
}
return newList;
}
i would combine the cases for the array with either odd or even elements together as below:
public static int[] collapse(int[] a1) {
int[] res = new int[a1.length/2 + a1.length % 2];
for (int i = 0; i < a1.length; i++)
res[i/2] += a1[i];
return res;
}
public static int[] collapse(int[] a1) {
int newArrayLength = a1.length / 2;
int[] collapsed;
if(a1.length%2 == 0)
{
collapsed = new int[newArrayLength];
}
else
{
collapsed = new int[newArrayLength+1];
collapsed[newArrayLength] = a1[a1.length-1];
}
int firstTwoSums = 0;
for (int i = 0; i < newArrayLength; i++) {
firstTwoSums = a1[i*2] + a1[i*2+1];
collapsed[i] = firstTwoSums;
}
return collapsed;
}
I modified your code and you may try it first.
I'm trying to figure out how to get the frequency of items within a list. When I approach this problem I typically, in the past, did:
int occurrences = Collections.frequency(list, 0);
It works when my list is a List<Integer> list. Is there a way to do this if I'm using int[] list? When I try collections, my list gets converted and then my code breaks. I can convert my code if needed, but was wondering, if there was a way to get the frequency from int[] instead.
You can (1) write your own linear-time frequency method, or (2) convert to an array of boxed int types and use Arrays.asList with Collections.frequency.
int[] arr = {1, 2, 3};
Integer[] boxedArr = new Integer[arr.length];
for(int i = 0; i < arr.length; i++)
boxedArr[i] = arr[i];
System.out.println(Collections.frequency(Arrays.asList(boxedArr), 1));
You could create a List from the int[], but otherwise, you just have to write your own.
int[] l = //your data;
List<Integer> list = new List<Integer>();
for(int i : l)
list.add(i);
int o = Collections.frequency(list, 0);
Or Arrays.asList(l); to make it shorter.
int occurrences = Collections.frequency(Arrays.asList(list), 0);
Or if you are against converting it to a list:
int occurrences = 0;
for (int i = 0; i < list.length; i++)
{
if(list[i] == X) // X being your number to check
occurrences++;
}
You can do this way as well.
List<Integer> intList = Arrays.asList(new Integer [] {
2, 3, 4, 5, 6,
2, 3, 4, 5,
2, 3, 4,
2, 3,
2
});
System.out.println(" count " + Collections.frequency(intList, 6));
i have array values as like
String[] value = {"1","2","3", "4","5","6","7","8","9","10"};
suppose if i pass value "5" to tat array, it should be ordered as like
{"5","6","7","8","9","10",1","2","3","4"};...
how to do?plz anyone help?
thank u
What you need is called rotation. You can use Collections.rotate() method. Convert the array to a list and pass it to the method. This will rotate the array in place since the list is backed by the array:
String[] value = {"1","2","3", "4","5","6","7","8","9","10"};
Collections.rotate(Arrays.asList(value), 5);
The above code will rotate the array by a distance of 5. The resulting value array:
[6, 7, 8, 9, 10, 1, 2, 3, 4, 5]
Your question has two interpretations:
Rotate 5 steps, or
rotate the array so that 5 is the first element (regardless of where it is in the array).
Here is a solution for both alternatives:
import java.util.Arrays;
public class Test {
public static String[] rotateArray(String[] arr, int n) {
String[] rotated = new String[arr.length];
System.arraycopy(arr, n-1, rotated, 0, arr.length-n+1);
System.arraycopy(arr, 0, rotated, arr.length-n+1, n-1);
return rotated;
}
public static String[] rotateArrayTo(String[] arr, String head) {
for (int i = 0; i < arr.length; i++)
if (arr[i].equals(head))
return rotateArray(arr, i + 1);
throw new IllegalArgumentException("Could not find " + head);
}
public static void main(String[] args) {
String[] value = {"1","2","3","4","5","6","7","8","9","10"};
// Rotate so that it starts at 5:th element
value = rotateArray(value, 5);
System.out.println(Arrays.toString(value));
// Rotate so that it starts with element "7"
value = rotateArrayTo(value, "7");
System.out.println(Arrays.toString(value));
}
}
Output:
[5, 6, 7, 8, 9, 10, 1, 2, 3, 4]
[7, 8, 9, 10, 1, 2, 3, 4, 5, 6]
(ideone.com link)
first find the index of the entered value from the array..
and then in a loop move from the index to the final position.. and store these values in a new array.
after that, in the same result array, store the values from index 0 to the index of the entered value - 1.
You really don't need to store the values in a different array. Just find the index [say idx] of the value passed. And then start a loop from the start of the array and swap the values starting from idx.
For example -
idx = [some-value]
while [idx < arr.length]
temp = arr[i]
arr[i] = arr[idx]
arr[idx] = t
idx += 1
i += 1
Update:
I stand corrected by #aioobe. I simply worked out something for the 5th index - my bad. Here's something that works, if in case, you want to stay away from library functions -
private void slideLeft(String[] arr)
{
String t = arr[arr.length - 1];
String temp = null;
int next = -1;
for (int i = arr.length - 1; i >= 0; i--)
{
next = ( i == 0 ) ? arr.length - 1 : i - 1;
temp = arr[next];
arr[next] = t;
t = temp;
}
}
you'll need to call this method the number of times you need to shift the array members.
note: O(n^2) alert. not suitable for large shifts/arrays.