Related
I have a function public static void sortedlist(int[] l, int r) that takes an array int[] l and returns a new array where every non-negative element in the list would be added with every element until the rth element.
So here is an example.
Lets say we have l = {1, 2, -3, 4, 5, 4}, and r = 3. In this case, we would:
Replace l[0] with l[0] + l[1] + l[2] + l[3].
Replace l[1] with l[1] + l[2] + l[3] + l[4].
Not do anything to l[2] because it is negative.
Replace l[3] with l[3] + l[4] + l[5]. (We can't go further than the end of the array.)
Replace l[4] with l[4] + l[5].
Not change the value of a[5] because there are no values after l[5]. So the sum is l[5] itself.
Thus, the result after calling `sortedlist` would be {4, 8, -3, 13, 9, 4}.
Here is my code so far:
public class Practice2 {
public static void sortedlist(int[] l, int r) {
int[] A;
int sum = 0;
for (int i = 0; i < l.length + r; i+=r) {
sum = sum +=
}
}
}
As you can see, I'm not done with the code because I'm stumped on how am I supposed to move forward from this point.
What I'm trying to do is create a new Array A and then add the new values that I've received from sum into Array A.
Any help would be greatly appreciated. Furthermore, if you could explain the logic behind a working code would be extremely beneficial for me as well.
Thank you :)
Try this.
public static void sortedlist(int[] l, int r) {
for (int i = 0, max = l.length; i < max; ++i)
if (l[i] >= 0)
for (int j = i + 1; j <= i + r && j < max; ++j)
l[i] += l[j];
}
and
int[] a = {1, 2, -3, 4, 5, 4};
sortedlist(a, 3);
System.out.println(Arrays.toString(a));
output:
[4, 8, -3, 13, 9, 4]
Please find the solution below and i have also provided some explanation regarding the logic behind it.
Note: I have unit tested it for few cases and it seems working fine.
1) r is less than array length
2) r is equals to array length
3) r is greater than array length
public class Test {
public static void main(String[] args) {
int[] input = new int[]{1, 2, -3, 4, 5, 4};
int r = 3;
sortedlist(input,r);
}
public static void sortedlist(int[] l, int r) {
List<Integer> list = new ArrayList<>();
int itr = 0;
for(int i = itr; i < l.length ; i++){//This loop is for iterating over the given array
int temp = 0;
int itr2 = Math.min(itr + r, l.length-1);//This function takes the minimum value and it helps when the (itr+r) > l.length, it will consider the (l.length-1)
if(l[i] > 0){// checking whether the selected value is -ve or not
for(int j = i; j <= itr2 ; j++){ // This loop is for calculating the addition over the selected range
temp = temp + l[j];
}
} else {// if it is-ve, assigning the same value to temp
temp = l[i];
}
list.add(temp);// storing the calculated value in a list of integers
itr++; // incrementing the main loop iterator
}
System.out.println(list);
}
}
Output:
[4, 8, -3, 13, 9, 4]
How would I change the size of a 2d array without rearranging the numbers in an array mainly using for loops and only built in methods?
For example, {{4,5,6,7,10}, {8,4,3,9,13}} to become {{4}, {5,6}, {7,10,8}, {4,3,9,13}}.
I tried making the 2d array into two separate parts then adding it back to a new 2d array. I'm not sure how I would create the second 2d array.
There are many ways to do this. Here is one that works for any triangular number
of elements that originate in a 2D array.
First, flatten them all into a single array.
int[] oneD = Arrays.stream(src).flatMapToInt(Arrays::stream).toArray();
Then reversing the length which should be k where k = n(n+1)/2 the
number of rows would be the following. And the 2D result is partially allocated.
int rows = (int)(Math.sqrt(2*oneD.length + .25) -.5);
int[][] dest = new int[rows][];
Now it's just a matter of copying from the oneD array to the destination.
for (int i = 0, s = 0, e = 1; i < rows; i++) {
dest[i] = Arrays.copyOfRange(oneD, s, e );
s = e;
e += i+2;
}
for (int[] arr : dest) {
System.out.println(Arrays.toString(arr));
}
Prints
[4]
[5, 6]
[7, 10, 8]
[4, 3, 9, 13]
If I understood your question, I recommend you use List<List<Integer>>, for example ArrayList, insted of pure arrays, and you can set your aggregations like this:
List<List<Integer>> matrix = new ArrayList<>();
List<Integer> values = new ArrayList<>();
// add {4,5,6,7,10} to array, result = {{4,5,6,7,10}}
values = new ArrayList<>(Arrays.asList(4,5,6,7,10));
matrix.add(values);
// add {8,4,3,9,13} to last array, result = {{4,5,6,7,10}, {8,4,3,9,13}}
values = new ArrayList<>(Arrays.asList(8,4,3,9,13));
matrix.add(values);
System.out.println("start="+ matrix);
// reset array or you can use another array to copy
matrix = new ArrayList<>();
values = new ArrayList<>(Arrays.asList(4));
matrix.add(values);
values = new ArrayList<>(Arrays.asList(5,6));
matrix.add(values);
values = new ArrayList<>(Arrays.asList(7,10,8));
matrix.add(values);
values = new ArrayList<>(Arrays.asList(4,3,9,13));
matrix.add(values);
System.out.println("end="+ matrix);
Output:
start=[[4, 5, 6, 7, 10], [8, 4, 3, 9, 13]]
end=[[4], [5, 6], [7, 10, 8], [4, 3, 9, 13]]
A possible not-recommended solution
Flatten the 2d array
Collect with grouping on summation sequence
It might be improved to use single atomic counter (i am unable to think)
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class ArrayResize {
public static void main(String[] args) {
Integer[][] input = new Integer[][] {{10, 11, 12 ,13, 14}, {15, 16, 17, 18, 19}};
AtomicInteger index = new AtomicInteger(0);
AtomicInteger group = new AtomicInteger(1);
Collection<List<Integer>> out = Arrays.stream(input)
.flatMap(i -> Arrays.stream(i)) // flatten
.collect(Collectors.groupingBy(i -> {
final int currentIndex = index.getAndIncrement();
return (group.get() * (group.get() + 1)) / 2 == currentIndex
? group.incrementAndGet() // increment group if index matches the summation of the range
: group.get(); // return the group
}))
.values();
System.out.println(out);
}
}
output has to be any Integer array
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class ArrayResize {
public static void main(String[] args) {
Integer[][] input = new Integer[][] {{10, 11, 12 ,13, 14}, {15, 16, 17, 18, 19}};
AtomicInteger index = new AtomicInteger(0);
AtomicInteger group = new AtomicInteger(1);
Integer[][] output = Arrays.stream(input)
.flatMap(i -> Arrays.stream(i)) // flatten
.collect(Collectors.groupingBy(i -> {
final int currentIndex = index.getAndIncrement();
return (group.get() * (group.get() + 1)) / 2 == currentIndex
? group.incrementAndGet() // increment group if index matches the summation of the range
: group.get(); // return the group
})).values().stream() // stream collection
.map(subgroup -> subgroup.toArray(new Integer[0])) // map subgroups to arrays
.collect(Collectors.toList()) // collect as list of arrays
.toArray(new Integer[0][0]); // convert to array
System.out.println(Arrays.deepToString(output));
}
}
Disclaimer
I would not write the above code in any of my production systems
At the current state, it will fail with parallel stream usage
Solution using index count
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ArrayResize {
public static void main(String[] args) {
Integer[][] input = new Integer[][] {{10, 11, 12 ,13, 14}, {15, 16, 17, 18, 19}};
List<Integer> flattened = Arrays.stream(input).flatMap(i -> Arrays.stream(i)).collect(Collectors.toList());
List<Integer[]> temporary = new ArrayList<>();
final int count = flattened.size();
int start = 0;
int range = 1;
while (start < count) {
temporary.add(flattened.subList(start, Math.min(start + range, count)).toArray(new Integer[0]));
start += range;
range++;
}
Integer[][] result = temporary.toArray(new Integer[0][0]);
System.out.println(Arrays.deepToString(result));
}
}
Here's one way to do it, using pure Java code (e.g. loops) and no methods at all.
static int[][] toTriangle(int[][] input) {
// Count number of values
int valueCount = 0;
for (int[] inputRow : input)
valueCount += inputRow.length;
if (valueCount == 0)
return new int[0][0];
// Determine number of result rows, and how many values that can store
int resultRowCount = 0, resultCount = 0;
for (int row = 0; resultCount < valueCount; row++) {
resultRowCount++;
resultCount += row + 1;
}
int oversize = resultCount - valueCount;
// Build result jagged array (last row is likely truncated)
int[][] result = new int[resultRowCount][];
for (int row = 0; row < resultRowCount - 1; row++)
result[row] = new int[row + 1];
result[resultRowCount - 1] = new int[resultRowCount - oversize];
// Copy values
int inputRow = 0, inputCol = 0;
for (int[] resultRow : result) {
for (int i = 0; i < resultRow.length; i++) {
while (inputCol == input[inputRow].length) {
inputRow++;
inputCol = 0;
}
resultRow[i] = input[inputRow][inputCol++];
}
}
return result;
}
Tests
test(new int[][] {{4,5,6,7,10}, {8,4,3,9,13}});
test(new int[][] {{1,2,3,4}, {}, {5,6,7}});
static void test(int[][] input) {
print("Input", input);
print("Result", toTriangle(input));
}
static void print(String label, int[][] arr) {
System.out.println(label + ":");
for (int[] row : arr) {
System.out.print(" [");
String sep = "";
for (int val : row) {
System.out.print(sep + val);
sep = ", ";
}
System.out.println("]");
}
}
Outputs
Input:
[4, 5, 6, 7, 10]
[8, 4, 3, 9, 13]
Result:
[4]
[5, 6]
[7, 10, 8]
[4, 3, 9, 13]
Input:
[1, 2, 3, 4]
[]
[5, 6, 7]
Result:
[1]
[2, 3]
[4, 5, 6]
[7]
Notice how the last row is truncated in length, since there are not enough values to fill a triangle. The second example also shows that it can handle empty sub-arrays in the input.
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;
}
public class EnoughIsEnough {
public static int[] deleteNth(int[] elements, int maxOccurrences){
int n = 0;
for(int b: elements){
for(int i =0 , i< elements.length;i++) {
if(elements[b] == elements[i]){
n++;
}
if (n > maxOccurrences) {
for(int k = b; k < elements.length -1 ; k ++) {
elements[k] = elements [k + 1];
}
}
}
}
return null;
}
}
Hey im a total programming newbie and only familiar with the very basics and I came a cross this problem:
I have to delete occurrences of an element if it occurs more than n times but I don't know if im getting close or not, I struggle to remove the occurrences out of the array and im not even sure if the code I wrote so far is accutally detecting them.
I would really appreciate if someone can help me to solve this problem.
Because of my low rank im not able to view solutions on code wars and googling this problem didn't bring me any closer because of to complex code I don't understand.
public class EnoughIsEnough {
public static int[] deleteNth(int[] elements, int maxOccurrences){
HashMap<Integer, Integer> occurence = new HashMap<>();
for(int i : elements) {
if(occurence.containsKey(i)) {
occurence.put(i, occurence.get(i) + 1);
} else {
occurence.put(i, 1);
}
}
List<Integer> al = new ArrayList<>();
for(int i : elements) {
if(occurence.get(i) < maxOccurrences) {
al.add(i);
}
}
int[] output = new int[al.size()];
for(int i=0;i<al.size(); i++) {
output[i] = al.get(i);
}
return output;
}
}
You need to remember which elements exceed the count so you don't add them to the returned array.
The best way to do that is to keep a frequency count of the elements in a map for easy referral.
int[] v = deleteNth(new int[] { 20, 37, 20, 21 }, 1); // return [20,37,21]
System.out.println(Arrays.toString(v));
v = deleteNth(new int[] { 1, 1, 2, 3, 3, 7, 2, 2, 2, 2 }, 3); // return [1, 1, 3, 3, 7, 2, 2, 2]
System.out.println(Arrays.toString(v));
Prints
[20, 37, 21]
[1, 1, 2, 3, 3, 7, 2, 2]
Here is the method. As numbers are added to the return list, the map records them by incrmementing a count associated with the number. If the count exceeds the maxOccurrences allowed, it is not added to the list when encountered.
public static int[] deleteNth(int[] elements,
int maxOccurrences) {
List<Integer> ret = new ArrayList<>();
Map<Integer, Integer> count = new HashMap<>();
for (int i : elements) {
count.compute(i, (k,v)-> v == null ? 1 : v + 1);
if (count.get(i) <= maxOccurrences) {
ret.add(i);
}
}
// here you could return the list or convert to an array (as I did) and return
// that.
return ret.stream().mapToInt(a->a).toArray();
}
I need to add an element to Array specifying position and value.
For example, I have Array
int []a = {1, 2, 3, 4, 5, 6};
after applying addPos(int 4, int 87) it should be
int []a = {1, 2, 3, 4, 87, 5};
I understand that here should be a shift of Array's indexes, but don't see how to implement it in code.
The most simple way of doing this is to use an ArrayList<Integer> and use the add(int, T) method.
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
// Now, we will insert the number
list.add(4, 87);
This should do the trick:
public static int[] addPos(int[] a, int pos, int num) {
int[] result = new int[a.length];
for(int i = 0; i < pos; i++)
result[i] = a[i];
result[pos] = num;
for(int i = pos + 1; i < a.length; i++)
result[i] = a[i - 1];
return result;
}
Where a is the original array, pos is the position of insertion, and num is the number to be inserted.
Jrad solution is good but I don't like that he doesn't use array copy. Internally System.arraycopy() does a native call so you will a get faster results.
public static int[] addPos(int[] a, int index, int num) {
int[] result = new int[a.length];
System.arraycopy(a, 0, result, 0, index);
System.arraycopy(a, index, result, index + 1, a.length - index - 1);
result[index] = num;
return result;
}
You must make a new array, use System.arraycopy to copy the prefix and suffix, and set that one slot to the new value.
If you prefer to use Apache Commons instead of reinventing the wheel, the current approach is this:
a = ArrayUtils.insert(4, a, 87);
It used to be ArrayUtils.add(...) but that was deprecated a while ago. More info here: 1
I smell homework, so probably an ArrayList won't be allowed (?)
Instead of looking for a way to "shift indexes", maybe just build a new array:
int[] b = new int[a.length +1];
Then
copy indexes form array a counting from zero up to insert position
...
...
//edit: copy values of course, not indexes
Unless I'm missing something, the question is not about increasing the array size. In the example the array size remains the same. (Like a bit shift.)
In this case, there is really no reason to create a new array or to copy it. This should do the trick:
static void addPos(int[] array, int pos, int value) {
// initially set to value parameter so the first iteration, the value is replaced by it
int prevValue = value;
// Shift all elements to the right, starting at pos
for (int i = pos; i < array.length; i++) {
int tmp = prevValue;
prevValue = array[i];
array[i] = tmp;
}
}
int[] a = {1, 2, 3, 4, 5, 6};
addPos(a, 4, 87);
// output: {1, 2, 3, 4, 87, 5}
Here is a quasi-oneliner that does it:
String[] prependedArray = new ArrayList<String>() {
{
add("newElement");
addAll(Arrays.asList(originalArray));
}
}.toArray(new String[0]);
org.apache.commons.lang3.ArrayUtils#add(T[], int, T) is deprecated in newest commons lang3, you can use org.apache.commons.lang3.ArrayUtils#insert(int, T[], T...) instead.
Deprecated this method has been superseded by insert(int, T[], T...) and may be removed in a future release. Please note the handling of null input arrays differs in the new method: inserting X into a null array results in null not X
Sample code:
Assert.assertArrayEquals
(org.apache.commons.lang3.ArrayUtils.insert
(4, new int[]{1, 2, 3, 4, 5, 6}, 87), new int[]{1, 2, 3, 4, 87, 5, 6});
Have a look at commons. It uses arrayCopy(), but has nicer syntax. To those answering with the element-by-element code: if this isn't homework, that's trivial and the interesting answer is the one that promotes reuse. To those who propose lists: probably readers know about that too and performance issues should be mentioned.
int[] b = new int[a.length +1];
System.arraycopy(a,0,b,0,4);
//System.arraycopy(srcArray, srcPosition, destnArray, destnPosition, length)
b[4]=87;
System.arraycopy(a,4,b,5,2);
b array would be created as {1, 2, 3, 4, 87, 5,6};
Try this
public static int [] insertArry (int inputArray[], int index, int value){
for(int i=0; i< inputArray.length-1; i++) {
if (i == index){
for (int j = inputArray.length-1; j >= index; j-- ){
inputArray[j]= inputArray[j-1];
}
inputArray[index]=value;
}
}
return inputArray;
}
System.arraycopy is more performant but tricky to get right due to indexes calculations. Better stick with jrad answer or ArrayList if you don't have performance requirements.
public static int[] insert(
int[] array, int elementToInsert, int index) {
int[] result = new int[array.length + 1];
// copies first part of the array from the start up until the index
System.arraycopy(
array /* src */,
0 /* srcPos */,
result /* dest */,
0 /* destPos */,
index /* length */);
// copies second part from the index up until the end shifting by 1 to the right
System.arraycopy(
array /* src */,
index /* srcPos */,
result /* dest */,
index + 1 /* destPos */,
array.length - index /* length */);
result[index] = elementToInsert;
return result;
}
And JUnit4 test to check it works as expected.
#Test
public void shouldInsertCorrectly() {
Assert.assertArrayEquals(
new int[]{1, 2, 3}, insert(new int[]{1, 3}, 2, 1));
Assert.assertArrayEquals(
new int[]{1}, insert(new int[]{}, 1, 0));
Assert.assertArrayEquals(
new int[]{1, 2, 3}, insert(new int[]{2, 3}, 1, 0));
Assert.assertArrayEquals(
new int[]{1, 2, 3}, insert(new int[]{1, 2}, 3, 2));
}
public class HelloWorld{
public static void main(String[] args){
int[] LA = {1,2,4,5};
int k = 2;
int item = 3;
int j = LA.length;
int[] LA_NEW = new int[LA.length+1];
while(j >k){
LA_NEW[j] = LA[j-1];
j = j-1;
}
LA_NEW[k] = item;
for(int i = 0;i<k;i++){
LA_NEW[i] = LA[i];
}
for(int i : LA_NEW){
System.out.println(i);
}
}
}
Following code will insert the element at specified position and shift the existing elements to move next to new element.
public class InsertNumInArray {
public static void main(String[] args) {
int[] inputArray = new int[] { 10, 20, 30, 40 };
int inputArraylength = inputArray.length;
int tempArrayLength = inputArraylength + 1;
int num = 50, position = 2;
int[] tempArray = new int[tempArrayLength];
for (int i = 0; i < tempArrayLength; i++) {
if (i != position && i < position)
tempArray[i] = inputArray[i];
else if (i == position)
tempArray[i] = num;
else
tempArray[i] = inputArray[i-1];
}
inputArray = tempArray;
for (int number : inputArray) {
System.out.println("Number is: " + number);
}
}
}