Swap rows in 2d array by row sum in Java - java

I implemented this thing but I am not sure this is correct
Example : int [][]={{2,1,0},{2,8,9},{1,1,0}}
In the above sum of elements in row 1 (2+1+0=3) is lesser than sum of elements in row 2(2+8+9=19) and greater than row 3 sum(2).
The final array should be like {{2,8,9},{2,1,0},{1,1,0}}
int arr[5][5];
int rowSum[5];
int sum = 0;
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
sum = sum + arr[i][j];
}
rowSum[i] = sum;
sum=0;
}
int swap;
//now sorting
for (int c = 0 ; c < ( n - 1 ); c++)
{
for (int d = 0 ; d < n - c - 1; d++)
{
if (rowSum[d] > rowSum[d+1]) /* For decreasing order use < */
{
swap = rowSum[d];
rowSum[d] = rowSum[d+1];
rowSum[d+1] = swap;
//swapping original array
for(int i=0;i<5;i++){
swap = arr[d][i];
arr[d][i] = arr[d+1][i];
arr[d+1][i] = swap;
}
}
}
}

Using Java 8 features:
int[][] arr = { { 2, 1, 0 }, { 2, 8, 9 }, { 1, 1, 0 } };
Arrays.sort(arr, Comparator.comparingInt((int[] row) -> Arrays.stream(row).sum()).reversed());
System.out.println(Arrays.deepToString(arr));

Integer[][] numbers = new Integer[][]{{2,1,0},{2,8,9},{1,1,0}};
System.out.println("Before:");
for(Integer[] row : numbers) {
for(Integer num : row) {
System.out.print(num+",");
}
System.out.println("");
}
Arrays.sort(numbers, new Comparator<Integer[]>(){
#Override
public int compare(Integer[] o1, Integer[] o2) {
Integer sumArray_1 = 0;
Integer sumArray_2 = 0;
for(int i = 0; i < o1.length; ++i) {
sumArray_1 += o1[i];
}
for(int i = 0; i < o2.length; ++i) {
sumArray_2 += o2[i];
}
return sumArray_2.compareTo(sumArray_1); //Decending order
}
});
System.out.println("After:");
for(Integer[] row : numbers) {
for(Integer num : row) {
System.out.print(num+",");
}
System.out.println("");
}
Output:
Before:
2,1,0,
2,8,9,
1,1,0,
After:
2,8,9,
2,1,0,
1,1,0,

Use the below Code Snippet,
int[][] temp = {{2,1,0},{2,8,9},{1,1,0}};
Arrays.sort(temp, new Comparator<int[]>() {
#Override
public int compare(int[] a, int[] b) {
return Integer.compare(b[1], a[1]);
}
});
System.out.println("After applying comparator");
for(int[] arr:temp){
for(int val:arr){
System.out.print(val+" ");
}
System.out.println("");
}
It will display the output like this,
After applying comparator
2 8 9
2 1 0
1 1 0

Related

I have problem with sort the matrix. [MergeSort]

Displays the list of matrix columns on the screen, in descending order of the maximum in the respective columns; data sorting will be done through merge sort.
I write the maximal elements in the vector, then the vector is sorted, and already from the vector you have to display the columns. And if there are 2 identical numbers in the matrix, it has to display the correct column, it must work with coordinates, but I failed.
2 6 1
10 5 11
4 8 9
Final result
1 2 6
11 10 5
9 4 8
static void maxVec(int[][] myArray, int n, int m) {
int[] elMax=new int[m];
for (int i=0; i<m; i++) {
int max=0;
if(n>m) {
int count=(n-m);
for (int j=0; j<myArray[i].length+count; j++) {
if(myArray[j][i]>max) {
max=myArray[j][i];
}
}
}
if(n==m) {
for (int j=0; j<myArray[i].length; j++) {
if(myArray[j][i]>max) {
max=myArray[j][i];
}
}
}
if(n<m) {
int count=(m-n);
for (int j=0; j<m-count; j++) {
if(myArray[j][i]>max) {
max=myArray[j][i];
}
}
}
elMax[i]=max;
}
mergeSort(elMax, elMax.length);
for(int i=0;i<elMax.length;i++) {
System.out.print(elMax[i]+" ");
}
System.out.println("\n===================================");
//here i don't know what to do
for(int k=0;k<elMax.length;k++) {
for (int i=0; i<myArray.length; i++) {
for (int j=0; j<myArray[i].length; j++) {
if(elMax[k]==myArray[i][j]) {
for (int w=0; w<myArray[w].length; w++) {
System.out.print(myArray[i][w]+" ");
}
System.out.println();
}
}
}
}
}
//merge sort
public static void merge(
int[] a, int[] l, int[] r, int left, int right) {
int i=0, j=0, k=0;
while(i<left && j<right) {
if(l[i]>=r[j]) {
a[k++]=l[i++];
}
else {
a[k++]=r[j++];
}
}
while(i<left) {
a[k++]=l[i++];
}
while(j<right) {
a[k++]=r[j++];
}
}
public static void mergeSort(int[] a, int n) {
if(n<2) {
return;
}
int mid =n/2;
int[] l = new int[mid];
int[] r = new int[n-mid];
for(int i=0;i<mid;i++) {
l[i]=a[i];
}
for(int i=mid;i<n;i++) {
r[i-mid]=a[i];
}
mergeSort(l, mid);
mergeSort(r, n-mid);
merge(a, l, r, mid, n-mid);
}
hope this helps you, and better use this on not very large matrix,
class Matrix {
int[][] matrix = new int[][] {
{ 1, 3, 5, 16, 9},
{ 2, 4, 15, 6, 0},
{18, 14, 17, 11, 10},
{14, 15, 12, 16, 13}
};
void sortByColumn() {
class ColMax {
int col;
int val;
ColMax(int c, int v) {
col = c;
val = v;
}
#Override
public String toString() {
return "[" + col + ": " + val + "]";
}
}
int cols = matrix[0].length;
int rows = matrix.length;
int[][] target = new int[rows][cols];
ColMax[] colmaxes = new ColMax[cols];
for (int i = 0; i < cols; i++) {
colmaxes[i] = new ColMax(i, matrix[0][i]);
}
// find every column's max item
for (int i = 0; i < cols; i++) {
for (int k = 0; k < rows; k++) {
if (colmaxes[i].val < matrix[k][i]) {
colmaxes[i].val = matrix[k][i];
}
}
}
// sort it descending
Arrays.sort(colmaxes, (a,b) -> b.val - a.val);
for (int i = 0; i < cols; i ++) {
System.out.print(colmaxes[i] + ", ");
}
System.out.println();
// copy sorted cols
for (int i = 0; i < rows; i++) {
for (int k = 0; k < cols; k++) {
target[i][k] = matrix[i][colmaxes[k].col];
System.out.print(target[i][k] + ", ");
}
System.out.println();
}
}
}

Get the maximum summation of 2D array

There is a 2D array. int[][] arr= {{1,3,4,1},{5,7,8,9},{6,1,2,1}} . I want to get summation of each columns and get the maximum number. Finally it should be returned {5,7,8,9} . Because it has the maximum summation. I have mentioned i tried code below and it not return correct value. Help me to solve this
Your k is supposed to track the index with the greatest sum. So when you are resetting max you need to say k=i. You said i=k by mistake. Changing it makes your program run as desired.
EDIT: There was once code in the original question, to which this solution referred.
If the max column is expected, then I might have a solution:
import java.util.Arrays;
public class ArrayTest {
public static void main(String args[]) {
/*
* 1 3 4 1
* 5 7 8 9
* 6 1 2 1
*
*/
int[][] arr = {{1, 3, 4, 1}, {5, 7, 8, 9}, {6, 1, 2, 1}};
int m = arr.length;
int n = arr[0].length;
int[] arr2 = new int[n];
int p = 0;
int[][] colArray = new int[n][m];
for (int i = 0; i < n; i++) {
int[] arr_i = new int[m];
//System.out.println("i = " + i);
//System.out.println("p = " + p);
int sum = 0;
for (int j = 0; j < m; j++) {
arr_i[j] = arr[j][p];
sum += arr_i[j];
}
//System.out.println("Col: " + p + " : " + Arrays.toString(arr_i));
colArray[i] = arr_i;
arr2[p] = sum;
p++;
}
System.out.println("Sum: " + Arrays.toString(arr2));
int k = 0;
int max = arr2[0];
for (int i = 0; i < 3; i++) {
if (arr2[i] > max) {
max = arr2[i];
k = i;
}
}
System.out.println("Column index for max: " + k);
System.out.println("Column: " + Arrays.toString(colArray[k]));
}
}
Output:
Sum: [12, 11, 14, 11]
Column index for max: 2
Column: [4, 8, 2]
I recommend you find a way to break down your problem into smaller parts, solve each part with a function, then combine everything into a solution.
Example solution below:
public class Main {
public static long sum(int[] a){
long sum = 0;
for (int i : a) {
sum = sum + i;
}
return sum;
}
public static int[] withMaxSumOf(int[][] as){
// keep one sum for each array
long[] sums = new long[as.length];
// calculate sums
for (int i = 0; i < as.length; i++) {
int[] a = as[i];
sums[i] = sum(a);
}
// find the biggest one
int maxIndex = 0;
long maxSum = sums[0];
for (int i=1;i<sums.length;i++){
if (sums[i] > maxSum){
maxSum = sums[i];
maxIndex = i;
}
}
// return array that had biggest sum
return as[maxIndex];
}
public static void main(String[] args){
int[][] arr= {{1,3,4,1},{5,7,8,9},{6,1,2,1}};
// find the one with max sum
int[] max = withMaxSumOf(arr);
// print it
for (int i = 0; i < max.length; i++) {
int x = max[i];
if (i > 0) System.out.print(", ");
System.out.print(x);
}
System.out.println();
}
}
I think this might be your problem:
for(int i=0;i<3;i++) {
if(arr2[i]>max) {
max=arr2[i];
i=k;
}
}
I think that i=k really needs to be k=i.
Note also that it's worthwhile using better variable names. index instead of i, for instance. What is k? Call it "indexForHighestSum" or something like that. It doesn't have to be that long, but k is a meaningless name.
Also, you can combine the summation loop with the find-highest loop.
In the end, I might write it like this:
public class twoDMax {
public static void main(String args[]) {
int[][] arr= { {1,3,4,1}, {5,7,8,9}, {6,1,2,1} };
int indexForMaxRow = 0;
int previousMax = 0;
for(int index = 0; index < 4; ++index) {
int sum = 0;
for(int innerIndex = 0; innerIndex < 4; ++innerIndex) {
sum += arr[index][innerIndex];
}
if (sum > previousMax) {
previousMax = sum;
indexForMaxRow = index;
}
System.out.println(indexForMaxRow);
for(int index = 0; index < 4; ++index) {
System.out.println(arr[indexForMaxRow][index]);
}
}
}
I did a few other stylish things. I made use of more obvious variable names. And I am a little nicer about whitespace, which makes the code easier to read.
public static void main( String args[] ) {
int[][] arr = { { 1, 3, 4, 1 }, { 5, 7, 8, 9 }, { 6, 1, 2, 1 } };
int indexOfMaxSum = 0;
int maxSum = 0;
for ( int i = 0; i < arr.length; i++ ) {
int[] innerArr = arr[ i ]; // grab inner array
int sum = 0; // start sum at 0
for ( int j : innerArr ) {
// iterate over each int in array
sum += j; // add each int to sum
}
if ( sum > maxSum ) {
// if this sum is greater than the old max, store it
maxSum = sum;
indexOfMaxSum = i;
}
}
System.out.println( String.format( "Index %d has the highest sum with a sum of %d", indexOfMaxSum, maxSum ) );
int [] arrayWithLargestSum = arr[indexOfMaxSum]; // return me
}

any better solution to get duplicates and there count in an array?

I have the below code which is aimed at finding out a duplicate element in an array and printing it with its count.
I have used the below approach to solve the problem.
copy the original array into temp array
find the duplicates in original array and remove the same
copy the non duplicate array into another temp array
compare non duplicate array with original array and print out the duplicates with their counts.
For calculating the length I am using my own version of code.
It o/ps
5 4
2 3
which is correct but I want to know if we can still refine this code.
Please suggest best approach, condition is that there should not be any build in method/functions usage.
package codingpractice;
public class DuplicateCount {
public static void main(String argsp[]) throws Exception {
int array[] = { 5, 1, 2, 5, 3, 2, 2, 5, 5 };
DuplicateCount hw = new DuplicateCount();
int length = hw.length(array);
hw.duplicates(array, length);
}
public void duplicates(int array[], int length) throws Exception {
int end =length, dupCount = 0;
//copying to another array for later comparison
int[] aarray = new int[length];
for (int i = 0; i < end; i++) {
aarray[i] = array[i];
}
//finding duplicates and removing the same
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (array[i] == array[j]) {
int shiftLeft = j;
for (int k = j + 1; k < end; k++, shiftLeft++) {
array[shiftLeft] = array[k];
}
end--;
j--;
}
}
}
//copying non duplicates to another array
int[] tarray = new int[end];
for (int i = 0; i < end; i++) {
tarray[i] = array[i];
}
//Printing duplicates and there counts, comparing original array and non duplicate array
for (int i = 0; i < length(tarray); i++) {
dupCount = 0;
for (int j = 0; j < length; j++) {
if (tarray[i] == aarray[j]) {
dupCount++;
}
}
if (dupCount > 1) {
System.out.println(tarray[i] + " " + dupCount);
}
}
}
//length of array- not using inbuild function
int length(int array[]) throws Exception {
int count = 0;
int temp = 0;
try {
while (true) {
count++;
temp = array[count];
}
} catch (Exception e) {
return count;
}
}
}
Much easier technique:
Map<Integer, Integer> map = new HashMap<>();
for (int i : array) {
Integer count = map.get(i);
if (count == null) {
map.put(i, 1);
}
else {
map.put(i, count.intValue() + 1);
}
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
if (entry.getValue() > 1) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
}
For the fun of it, here's a Java 8 equivalent:
Map<Integer, Integer> map = new HashMap<>();
for (int i : array) {
map.compute(i, (k, v) -> (v == null) ? 1 : v + 1);
}
map.entrySet().stream()
.filter(e -> e.getValue() > 1)
.forEach(e -> System.out.println(e.getKey() + " : " + e.getValue()));
The map.compute() call could also be replaced by
map.merge(i, 1, Integer::sum);
Just to complement JB Nizet's Java 7 solution. Here is a Java 8 solution:
public static void main(final String[] args) throws Exception {
final int[] ints = {1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 0, 0, 0};
final Map<Integer, Integer> count = IntStream.of(ints).
boxed().collect(HashMap::new, (map, i) -> {
map.merge(i, 1, (j, k) -> j + k);
}, HashMap::putAll);
//to print out
count.forEach((i, c) -> {System.out.println( i + " has a count of " + c);});
}
Output:
0 has a count of 3
1 has a count of 2
2 has a count of 1
3 has a count of 2
4 has a count of 2
5 has a count of 1
6 has a count of 1
7 has a count of 1
8 has a count of 1
9 has a count of 1
Using indices, create an empty array. Run on your array and increase the corresponding value at the index each time you run on it.
In your example:
int[] source = { 5, 1, 2, 5, 3, 2, 2, 5, 5 };
int[] counts = new int[6];
for (int i : source) {
counts[i]++;
}
Then your can run on the counts and you will get each element (array index) and its count (array value).

Finding differences in a array

I'm not sure how to set the differences to store in the array differences. The numbers stored should be 5-(1+2+3), 7-(1,2,4), 8-(3,5,9) : the output should be differences[0]= 1, differences[1] = 0, differences[2] = 9
import java.util.Scanner;
public class Main {
public static int[][] Array = { { 5, 1, 2, 3 }, { 7, 1, 2, 4 }, { 8,3,5,9 } }; //My 2D array//
int [] differences = new int [3];
public static int[] Sum(int[][] array) {
int index = 0; //setting the index to 0//
int temp[] = new int[array[index].length]; //making a temperary variable//
for (int i = 0; i < array.length; i++) {
int sum = 0;
for (int j = 1; j < array[i].length; j++) {
sum += array[i][j]; //going to add the rows after the first column//
}
temp[index] = sum;
for(int a = 0; a<differences.length; a++){
if(sum != array[index][0])
sum -= array[i][j];
System.out.println("the first integer " + array[index][0] + " the answer is " + sum); //going to print out the first integer each row and print out the sum of each row after the first column//
index++; //index is going to increment//
}
return temp;
}
public static void main(String[] args) {
new Main().Sum(Array);
}
}
Output:
the first integer 5 the answer is 6
the first integer 7 the answer is 7
the first integer 8 the answer is 17
Why do you want to complicate the task of yours when it is this simple? :)
public int[] Sum(int[][] array)
{
int sum;
for(int i = 0; i < Array.length; i++)
{
sum = Array[i][0] * -1;
for(int j = 1; j < Array[i].length; j++)
{
sum += Array[i][j];
}
differences[i] = sum;
}
return differences;
}
If I understand your problem correctly, I think that you want to put a
differences[i] = Array[i][0] - sum
somewhere in your code

how to get the most common character in an array?

Suppose I have an integer array like this:
{5,3,5,4,2}
and I have a method which returns the most common character
public int highestnumber(String[] num) {
int current_number = Integer.parseInt(num[0]);
int counter = 0;
for (int i = 1; i < num.length; ++i) {
if (current_number == Integer.parseInt(num[i])) {
++counter;
} else if (counter == 0) {
current_number = Integer.parseInt(num[i]);
++counter;
} else {
--counter;
}
}
return current_number;
}
but if I have multiple common character then i need to get the number which is closest to one(1), like if i have an array like this:
{5,5,4,4,2};
then the method should return 4, what should I do for this?
As per what I understand your question,
What you have to done is,
1. Create ArrayList from your int[]
2. Use HashMap for find duplicates, which one is unique
3. Sort it as Ascending order,
4. First element is what you want..
EDIT: Answer for your question
int[] arr = {5, 4, 5, 4, 2};
ArrayList<Integer> resultArray = new ArrayList<Integer>();
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < arr.length; i++)
{
if (set.contains(arr[i]))
{
System.out.println("Duplicate value found at index: " + i);
System.out.println("Duplicate value: " + arr[i]);
resultArray.add(arr[i]);
}
else
{
set.add(arr[i]);
}
}
Collections.sort(resultArray);
for (int i = 0; i < resultArray.size(); i++)
{
Log.e("Duplicate Values:", resultArray.get(i) + "");
}
Your need is,
int values = resultArray.get(0);
Sort the array then count runs of values.
Fast way.
Create a counter int array one element for each number. Go through the array once and increment corresponding counter array for each number. Set highest number to first counter element then go through and change highest number to current element only if it is bigger than highest number, return highest number.
public int highestNumber(String[] num){
int[] count = new int[10];
int highest_number = 0;
int highest_value = 0;
for(int i = 0; i < num.length; i++)
count[Integer.parseInt(num[i])]++;;
for(int i = 0; i < count.length; i++)
if(count[i] > highest_value){
highest_number = i;
highest_value = count[i];
}
return highest_number;
}
10x slower but without other array.
Create three ints one for number and two for counting. Go through the array once for each int and increment current counting each time it shows up, if bigger that highest count, set to highest count and set highest number to current count. Return highest number.
public int highestNumber(String[] num){
int highest_number = 0;
int highest_value = 0;
int current_value = 0;
for(int i = 0; i < 10; i++){
for(int j = 0; j < num.length; j++)
if(i == Integer.parseInt(num[j]))
current_value++;
if(current_value > highest_value){
highest_value = current_value;
highest_number = i;
}
current_value = 0;
}
return highest_number;
}
The first is obviously much faster but if for whatever reason you don't want another array the second one works too.
You can also try this:
import java.util.TreeMap;
public class SmallestFrequentNumberFinder {
public static int[] stringToIntegerArray(String[] stringArray) {
int[] integerArray = new int[stringArray.length];
for (int i = 0; i < stringArray.length; i++) {
integerArray[i] = Integer.parseInt(stringArray[i]);
}
return integerArray;
}
public static int getSmallestFrequentNumber(int[] numbers) {
int max = -1;
Integer smallestFrequentNumber = null;
TreeMap<Integer, Integer> frequencyMaper = new TreeMap<Integer, Integer>();
for (int number : numbers) {
Integer frequency = frequencyMaper.get(number);
frequencyMaper.put(number, (frequency == null) ? 1 : frequency + 1);
}
for (int number : frequencyMaper.keySet()) {
Integer frequency = frequencyMaper.get(number);
if (frequency != null && frequency > max) {
max = frequency;
smallestFrequentNumber = number;
}
}
return smallestFrequentNumber;
}
public static void main(String args[]) {
String[] numbersAsString = {"5", "5", "4", "2", "4", "4", "2", "2"};
final int[] integerArray = stringToIntegerArray(numbersAsString);
System.out.println(getSmallestFrequentNumber(integerArray));
}
}

Categories

Resources