Suppose, I have an array like
[1,2,3,4,5,6,7,8,9,10,11,12]
Are there any standard methods to transform it to the table with N columns?
For example, if N=3:
[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
or if N=4:
[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
etc.
With Java 8, you can use an IntStream to generate the corresponding indexes that you'll give to Arrays.copyOfRange.
I answered a sort of a similar question and you can find the logic there but here's it's slightly modified to take the array as parameter:
static List<int[]> partitionIntoList(int[] arr, int pageSize) {
return IntStream.range(0, (arr.length + pageSize - 1) / pageSize)
.mapToObj(i -> Arrays.copyOfRange(arr, i * pageSize, min(pageSize * (i + 1), arr.length)))
.collect(toList());
}
static int[][] partitionIntoArray(int[] arr, int pageSize) {
return IntStream.range(0, (arr.length + pageSize - 1) / pageSize)
.mapToObj(i -> Arrays.copyOfRange(arr, i * pageSize, min(pageSize * (i + 1), arr.length)))
.toArray(int[][]::new);
}
Note that if pageSize does not partition perfectly the input's size, the remaining elements are added in the last int array.
For example,
partitionIntoArray(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 4);
outputs:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
and if you take a page size of 5, the two last elements will be added to a third array:
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12]]
Hope it helps! :)
Just using for loops:
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12};
int n = 3;
int m = (int) Math.ceil( ( (double) array.length ) / n );
int[][] table = new int[m][n];
int k = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (k < array.length) {
table[i][j] = array[k];
k++;
}
}
}
The output should be what you are asking for.
Not really but you can create one easily using some math and a loop:
public int[][] getTable(int[] arr, int n) {
int[][] table = new int[(int)Math.ceil(arr.length / (float)n)][n];
for (int i = 0, row = 0, column = 0; i < arr.length; i++) {
if (i % n == 0 && i != 0) {
row++;
column = 0;
}
table[row][column++] = arr[i];
}
return table;
}
We could do it this way :
int n = 5; // what ever size you want to break it with
int[] bytes = {1,2,3,4,5,6,7,8,9,10,11,12};
int length = bytes.length;
int counter = 0;
int newSize = length % n == 0 ? length/n : (length/n)+1;
int[][] newArray = new int[newSize][n];
for (int i = 0; i < length - n + 1; i += n)
newArray[counter++] = Arrays.copyOfRange(bytes, i, i + n);
if (length % n != 0)
newArray[counter] = Arrays.copyOfRange(bytes, length - length % n, length);
Related
I would like to know how could I take in a negative value for d in the following code. This means, how could I traverse the array backwards and rotate its elements.
catchArray(int [] arr, int d)
{
int [] bArr = new int[arr.length];
for(int i = 0; i < bArr.length; i++)
{
bArr[(i + d) % bArr.length] = arr[i];
}
return bArr;
}
This is my answer for LeetCode Rotate Array assignment. Thank you in advance.
Just normalize "d" at the start of the program. If it's negative, then correct it.
Let's say the array length is 10 and d is -1. You'd get the same rotation if length was 10 and d was 9. That's all the adjustment at the start of the function is doing.
catchArray(int [] arr, int d)
{
d = d % arr.length;
if (d < 0)
{
d += arr.length;
}
int [] bArr = new int[arr.length];
for(int i = 0; i < bArr.length; i++)
{
bArr[(i + d) % bArr.length] = arr[i];
}
return bArr;
}
If the array is e.g. size 10, then a -1 rotation is the same as a +9 rotation.
In Java, the % remainder operator will return a negative value, if the quotient is negative, e.g. -12 % 10 and -2 % 10 will both return -2.
So, to get a normalized rotation value, we do this:
MIN_VALUE <= d <= MAX_VALUE
d % size -> -size < d < size
+ size -> 0 < d < size * 2
% size -> 0 <= d < size (normalized range)
Combined:
d = (d % arr.length + arr.length) % arr.length
That normalizes d to rotate less than one full round to the right.
static int[] catchArray(int[] arr, int d) {
d = (d % arr.length + arr.length) % arr.length;
int[] bArr = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
bArr[(i + d) % arr.length] = arr[i];
}
return bArr;
}
Tests
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, -8)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, -2)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, -1)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 0)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 1)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 2)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 8)));
Output
[4, 5, 1, 2, 3]
[3, 4, 5, 1, 2]
[2, 3, 4, 5, 1]
[1, 2, 3, 4, 5]
[5, 1, 2, 3, 4]
[4, 5, 1, 2, 3]
[3, 4, 5, 1, 2]
I wrote a method for finding and deriving the largest number of increasing (decreasing) elements of the matrix, going in a row. But it seems that the code is not quite good.
private void findLargestIncreasingAndDecreasingElements() {
int[][] matrix = getMatrix();
int[] oneArray = new int[matrix.length * matrix.length];
int r = 0;
int min = 0;
int max = 0;
int h = 0;
int m = 0;
int h1 = 0;
for (int[] x : matrix) {
int c = 0;
for (int z : x) {
oneArray[c++] = z;
}
}
for (int i = 0; i < oneArray.length - 1; i++) {
if (oneArray[i] < oneArray[i + 1]) {
r += 1;
if (r > max) {
max = r;
h = i + 1;
}
} else {
r = 0;
}
if (oneArray[i] > oneArray[i + 1]) {
m += 1;
if (m > min) {
min = m;
h1 = i + 1;
}
} else {
m = 0;
}
}
System.out.println("Maximum sequence of increasing numbers:");
int[] l = new int[max + 1];
System.arraycopy(oneArray, (h - max), l, 0, (max + 1));
System.out.println(java.util.Arrays.toString(l) + " " + (max + 1));
System.out.println("Maximum sequence of decreasing numbers:");
int[] t = new int[min + 1];
System.arraycopy(oneArray, (h1 - min), t, 0, (min + 1));
System.out.println(java.util.Arrays.toString(t) + " " + (min + 1));
}
Maybe someone knows how to make the algorithm better?
Sometimes incorrect output. For example:
{{-3, -3, 3, -5, 2}, {1, -2, 5, -2, -1}, {5, -3, -4, 2, 5}, {4, 4, -2, 3, 5}, {-2, 5, 4, 0, 0}}
outputs incremental:[-2, 5]
although there is [-2, 3, 5]
In the code that flattens the matrix, c gets reset on each pass through the outer loop, so only the final row of the matrix actually makes it into oneArray. Moving the int c = 0; line out of the loop will allow the whole matrix to get copied into oneArray so your code can find sequences outside the final row.
Need assistance with programming issue.
Must be in Java. Cannot use any libraries (Arraylist, etc.).
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0}
int[] b = {0, 2, 11, 12, 5, 6, 8}
Have to create an object referencing these two arrays in a method that merges them together, removes duplicates, and sorts them.
Here's my sort so far. Having difficulty combining two arrays and removing duplicates though.
int lastPos;
int index;
int temp;
for(lastPos = a.length - 1; lastPos >= 0; lastPos--) {
for(index = 0; index <= lastPos - 1; index++) {
if(a[index] > a[index+1]) {
temp = a[index];
a[index] = a[index+1];
a[index+1] = temp;
}
}
}
a method that merges them together, removes duplicates, and sorts them.
I suggest you break this down into helper methods (and slightly tweak the order of operations). Step 1, merge the two arrays. Something like,
static int[] mergeArrays(int[] a, int[] b) {
int[] c = new int[a.length + b.length];
for (int i = 0; i < a.length; i++) {
c[i] = a[i];
}
for (int i = 0; i < b.length; i++) {
c[a.length + i] = b[i];
}
return c;
}
Step 2, sort the new array (your existing sort algorithm is fine). Like,
static void sortArray(int[] a) {
for (int lastPos = a.length - 1; lastPos >= 0; lastPos--) {
for (int index = 0; index <= lastPos - 1; index++) {
if (a[index] > a[index + 1]) {
int temp = a[index];
a[index] = a[index + 1];
a[index + 1] = temp;
}
}
}
}
Finally, remove duplicates. Step 3a, count unique values. Assume they're unique, and decrement by counting adjacent (and equal) values. Like,
static int countUniqueValues(int[] c) {
int unique = c.length;
for (int i = 0; i < c.length; i++) {
while (i + 1 < c.length && c[i] == c[i + 1]) {
i++;
unique--;
}
}
return unique;
}
Then step 3b, take the unique count and build your result with the previous methods. Like,
public static int[] mergeDedupSort(int[] a, int[] b) {
int[] c = mergeArrays(a, b);
sortArray(c);
int unique = countUniqueValues(c);
int[] d = new int[unique];
int p = 0;
for (int i = 0; i < c.length; i++) {
d[p++] = c[i];
while (i + 1 < c.length && c[i] == c[i + 1]) {
i++;
}
}
return d;
}
Then you can test it with your arrays like
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 8, 5, 7, 9, 6, 0 };
int[] b = { 0, 2, 11, 12, 5, 6, 8 };
int[] c = mergeDedupSort(a, b);
System.out.println(Arrays.toString(c));
}
And I get
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12]
Merge Two Arrays without Duplicates and Sort it (No libraries used).
Using an object.
public class MergeRemoveDupSort {
public int[] mergeRemoveDupSortIt(int[] a, int[] b) {
int [] c = mergeIt(a,b);
int [] d = removeIt(c);
int [] e = sortIt(d);
return e;
}
private int[] mergeIt(int[] a, int[] b) {
int[] c = new int[a.length + b.length];
int k=0;
for (int n : a) c[k++]=n;
for (int n : b) c[k++]=n;
return c;
}
private int[] removeIt(int[] c) {
int len=c.length;
for (int i=0;i<len-1;i++)
for (int j=i+1;j<len;j++)
if (c[i] == c[j]) {
for (int k=j;k<len-1;k++)
c[k]=c[k+1];
--len;
}
int [] r = new int[len];
for (int i=0;i<r.length;i++)
r[i]=c[i];
return r;
}
private int[] sortIt(int[] a) {
for(int index=0; index<a.length-1; index++)
for(int i=index+1; i<a.length; i++)
if(a[index] > a[i]){
int temp = a[index];
a[index] = a[i];
a[i] = temp;
}
return a;
}
public void printIt(int[] a) {
System.out.print("[");
for (int i=0;i<a.length;i++){
System.out.print(a[i]);
if (i!=a.length-1) System.out.print(",");
else System.out.print("]");
}
}
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0};
int[] b = {0, 2, 11, 12, 5, 6, 8};
MergeRemoveDupSort array = new MergeRemoveDupSort();
int [] r = array.mergeRemoveDupSortIt(a, b);
array.printIt(r);
}
}
You should use IntStream like this.
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0};
int[] b = {0, 2, 11, 12, 5, 6, 8};
int[] merged = IntStream
.concat(IntStream.of(a), IntStream.of(b))
.distinct()
.sorted()
.toArray();
System.out.println(Arrays.toString(merged));
Assuming that array a and array b are sorted, the following code will merge them into a third array merged_array without duplicates :
public static int[] get_merged_array(int[] a, int[] b, int a_size, int b_size)
{
int[] merged_array = new int[a_size + b_size];
int i = 0 , j = 0, x = -1;
for(; i < a_size && j < b_size;)
{
if(a[i] <= b[j])
{
merged_array[++x] = a[i];
++i;
}
else
{
if(merged_array[x] != b[j])
{
merged_array[++x] = b[j]; // avoid duplicates
}
++j;
}
}
--i; --j;
while(++i < a_size)
{
merged_array[++x] = a[i];
}
while(++j < b_size)
{
merged_array[++x] = b[j];
}
return merged_array;
}
Hope this may help, all the best :)
try{
int[] a = {1, 2, 3, 4, 8, 5, 7, 9, 6, 0};
int[] b = {0, 2, 11, 12, 5, 6, 8};
int[] c = new int[a.length+b.length];
int[] final = new int[a.length+b.length];
int i = 0;
for(int j : final){
final[i++] = -1;
}
i = 0;
for(int j : a){
c[i++] = j;
}
for(int j : b){
c[i++] = j;
}
boolean check = false;
for(int j = 0,k = 0; j < c.length; j++){
for(int l : fin){
if( l == c[j] )
check = true;
}
if(!check){
final[k++] = c[j];
} else check = false;
}
} catch(Exception ex){
ex.printStackTrace();
}
I prefer you to use Hashset for this cause it never allow duplicates
and there is another method in java 8 for arraylist to remove duplicates
after copying all elements to c follow this code
List<Integer> d = array.asList(c);
List<Integer> final = d.Stream().distinct().collect(Collectors.toList());
final.forEach(System.out::println());
This code is lot much better than previous one and you can again transform final to array like this
int array[] = new int[final.size()];
for(int j =0;j<final.size();j++){
array[j] = final.get(j);
}
Hope my work will be helpful .
Let me restate your question.
You want a program that takes two arbitrary arrays, merges them removing any duplicates, and sorts the result.
First of all, if you have access to any data structure, there are much better ways of doing this. Ideally, you would use something like a TreeSet.
However, assuming all you have access to is arrays, your options are much more limited. I'm going to go ahead and assume that each of the two arrays initially has no duplicates.
Let's assume the first array is of length m and the second array is of length n.
int[] array1; // length m
int[] array2; // length n
First, let's sort both arrays.
Arrays.sort(array1);
Arrays.sort(array2);
This assumes you have access to the Arrays class which is part of the standard Java Collections Framework. If not, any reasonable merge implementation (like MergeSort) will do the trick.
The sorts will take O(n log n + m log m) with most good sort implementations.
Next, let's merge the two sorted arrays. First, we need to allocate a new array big enough to hold all the elements.
int[] array3 = new int[size];
Now, we will need to insert the elements of array1 and array2 in order, taking care not to insert any duplicates.
int index=0, next=0, i=0, j=0;
int last = Integer.MAX_INT;
while(i < m || j < n) {
if(i == m)
next = array2[j++];
else if(j == n)
next = array1[i++];
else if(array1[i] <= array2[j])
next = array1[i++];
else
next = array2[j++];
if(last == next)
continue;
array3[index++] = next;
}
Now, you have your array. Just one problem - it could have invalid elements at the end. One last copy should take care of it...
int[] result = Arrays.copyOf(array3, index + 1);
The inserts and the final copy will take O(n + m), so the overall efficiency of the algorithm should be O(n log n + m log n).
I keep getting an out of bounds error whenever i try to run my code. Does anyone know what is wrong with it? I can't seem to figure it out.
public class Swapper{
/**
This method swaps the first and second half of the given array.
#param values an array
*/
public void swapFirstAndSecondHalf(int[] values) {
// your work here
int[] first = new int[values.length/2];
int[] second = new int[values.length/2];
for(int i = 0; i < values.length / 2; i++) {
second[i] = values[i];
}
for (int j = values.length / 2; j < values.length; j++) {
first[j] = values[j];
}
for(int k = 0; k < values.length / 2; k++) {
values[k] = first[k];
}
for(int l = values.length / 2; l < values.length; l++) {
values[l] = second[l];
}
}
// This method is used to check your work
public int[] check(int[] values) {
swapFirstAndSecondHalf(values);
return values;
}
}
int[] first = new int[values.length/2];
So indexes [0..values.length/2 - 1] are valid for first.
for (int j=values.length/2; j<values.length; j++)
{
first[j] = values[j];
}
So with the first value of j being values.length/2, it's already out of bounds.
You need to practice debugging, placing a break point and tracing the code as it executes.
You could have used System.arraycopy() instead of all the for looping.
public static void main(String[] args) throws Exception {
int[] values = {1, 2, 3, 4, 5};
values = swapFirstAndSecondHalf(values);
System.out.println(Arrays.toString(values));
values = new int[]{1, 2, 3, 4, 5, 6};
values = swapFirstAndSecondHalf(values);
System.out.println(Arrays.toString(values));
}
public static int[] swapFirstAndSecondHalf(int[] values) {
boolean evenSize = values.length % 2 == 0;
int half = values.length / 2;
int[] swapper = new int[values.length];
System.arraycopy(values, evenSize ? half : half + 1, swapper, 0, half);
System.arraycopy(values, 0, swapper, evenSize ? half : half + 1, half);
// The middle number stays the middle number
if (!evenSize) {
swapper[half] = values[half];
}
return swapper;
}
Results:
[4, 5, 3, 1, 2]
[4, 5, 6, 1, 2, 3]
If you're wanting the middle number, for an odd sized array, to be part of the second half then the swapFirstAndSecondHalf() would look like this:
public static int[] swapFirstAndSecondHalf(int[] values) {
boolean evenSize = values.length % 2 == 0;
int half = values.length / 2;
int[] swapper = new int[values.length];
System.arraycopy(values, half, swapper, 0, evenSize ? half : half + 1);
System.arraycopy(values, 0, swapper, evenSize ? half : half + 1, half);
return swapper;
}
Results:
[4, 5, 3, 1, 2]
[4, 5, 6, 1, 2, 3]
Allocating new arrays is a waste of space. Just swap the halves in-place:
public static void swapFirstAndSecondHalf(int[] values) {
final int len = values.length / 2;
final int offset = values.length - len;
for (int i = 0; i < len; i++) {
int temp = values[i];
values[i] = values[offset + i];
values[offset + i] = temp;
}
}
The code allows odd length, and will leave center value alone.
My following code does the randomization of an array, however, I am wondering if I want to group first two or three elements together always, how should I proceed?
ArrayList<Integer> numbers = new ArrayList<Integer>();
for(int i=1;i<=11;i++)
{
numbers.add(i);
}
Collections.shuffle(numbers);
for (Integer nums : numbers)
System.out.println(nums);
Example Output: 5, 7, 4, 11, 2, 3, 1, 9, 6, 8, 10
(Note that the sequence '1,2,3' is randomized within the main array.)
Something like this maybe:
final int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
final int iterations = 10;
final int groupOf = 3;
for (int i = 0; i < array.length; i += groupOf) {
int groupOfRemainder = array.length - i < groupOf ? array.length - i : groupOf;
for (int j = 0; j < iterations; j++) {
int rnd1 = Math.random() * groupOfRemainder;
int rnd2 = Math.random() * groupOfRemainder;
Object temp = array[i + rnd1];
array[i + rnd1] = array[i + rnd2];
array[i + rnd2] = temp;
}
}
public static void shuffleKeepingFirstRTogether(List<Integer> list, int r) {
int size = list.size();
Collections.shuffle(list.subList(0, r));
Collections.shuffle(list.subList(r, size));
Collections.rotate(list, new Random().nextInt(size - r));
}