Sorting 2d String array using java - java

I am trying to sort a string 2d array taken as user input. But this code is working for some cases and not working for some.
The code is:
public class Source {
public static void main(String args[]) throws Exception {
Scanner sc = new Scanner(System.in);
String[][] customerDetails= new String[5][3];
customerDetails[0][0]="10";
customerDetails[0][1]="Raj";
customerDetails[0][2]="Chennai";
customerDetails[1][0]="100";
customerDetails[1][1]="Akshay";
customerDetails[1][0]="Pune";
customerDetails[2][0]="20";
customerDetails[2][1]="Simrath";
customerDetails[2][2]="Amristar";
customerDetails[3][0]="30";
customerDetails[3][1]="Gaurav";
customerDetails[3][2]="Delhi";
customerDetails[4][0]="101";
customerDetails[4][1]="Ganesh";
customerDetails[4][2]="Chennai";
/*for (int i = 0; i < 5; i++) {
for (int j = 0; j < 3; j++) {
//customerArray[i][j] = sc.nextLine();
}
}*/
Arrays.sort(customerArray, (a, b)->a[0].compareTo(b[0]));
for (int y = 0; y < 5; y++) {
for (int z = 0; z < 3; z++) {
System.out.println(customerArray[y][z]);
}
}
}
}
I have given direct inputs in this code. I want to sort the numbers as String

You are getting wrong answer because you were comparing 0th index of each row of 2D array which are String. So, according to string comparison logic the outputs are correct. To get the sorting order as integer, you have to convert 0th index of each row to Integer in your comparator.
Modify your sort method call like below which should work according to your expectation because a[0] and b[0] are converted to Integer before comparison:
Arrays.sort(customerArray, (a, b)->Integer.valueOf(a[0]).compareTo(Integer.valueOf(b[0])));
Output:
10
Akhil
Pune
20
Rajni
Hyderabad
30
Praveen
Delhi
100
Rohith
Chennai
101
Sam
Bangalore

Related

How to rotate 2-D Array in Java

[SOLVED]
The title of this question is vague but hopefully this will clear things up.
Basically, what I am looking for is a solution to rotating this set of data. This data is set up in a specific way.
Here is an example of how the input and output would look like:
Input:
3
987
654
321
Output:
123
456
789
The '3' represents the number of columns and rows that will be used. If you input the number '4', you will be allowed to input 4 sets of 4 integers.
Input:
4
4567
3456
2345
1234
Output:
1234
2345
3456
4567
The goal is to find a way to rotate the data only if needed. You have to make sure the smallest corner number is at the top left. For example, for the code above, you rotated it so 1 is at the top left.
The problem I have is that I don't know how to rotate the data. I am only able to rotate the corners but not the sides. This is what my code does so far:
take the input of each line and turn them into strings
split those strings into separate characters
store those characters in an array
I just do not know how to compare those characters and in the end rotate the data.
Any help would be appreciated! Any questions will be answered.
A detailed description of the problem is here(problem J4).
This is just a challenge I assigned myself for practice for next year's contest, so giving me the answer won't "spoil" the question, but actually help me learn.
Here is my code so far:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
int max = kb.nextInt();
int maxSqrt = (max * max);
int num[] = new int[max];
String num_string[] = new String[max];
char num_char[] = new char[maxSqrt];
int counter = 0;
int counter_char = 0;
for (counter = 0; counter < max; counter++) {
num[counter] = kb.nextInt();
}
for (counter = 0; counter < max; counter++) {
num_string[counter] = Integer.toString(num[counter]);
}
int varPos = 0, rowPos = 0, charPos = 0, i = 0;
for (counter = 0; counter < maxSqrt; counter++) {
num_char[varPos] = num_string[rowPos].charAt(charPos);
i++;
if (i == max) {
rowPos++;
i = 0;
}
varPos++;
if (charPos == (max - 1)) {
charPos = 0;
} else {
charPos++;
}
}
//
for(int a = 0 ; a < max ; a++){
for(int b = 0 ; b < max ; b++)
{
num_char[counter_char] = num_string[a].charAt(b);
counter_char++;
}
}
//here is where the code should rotate the data
}
}
This is a standard 90 degree clockwise rotation for a 2D array.
I have provided the solution below, but first a few comments.
You said that you're doing this:
take the input of each line and turn them into strings
split those strings into separate characters
store those characters in an array
Firstly youre essentially turning a int matrix into a character matrix. I do not think you need to do this, since even if you do want to compare values, you can use the ints provided.
Secondly, there is no need to compare any 2 data elements in the matrix, since the rotation does not depend on any value.
Here is an adapted solution for java, originally written in C# by Nick Berardi on this question
private int[][] rotateClockWise(int[][] matrix) {
int size = matrix.length;
int[][] ret = new int[size][size];
for (int i = 0; i < size; ++i)
for (int j = 0; j < size; ++j)
ret[i][j] = matrix[size - j - 1][i]; //***
return ret;
}
If you wanted to do a counterCW rotation, replace the starred line with
ret[i][j] = matrix[j][size - i - 1]

Incorrect Output for List

I'm doing a beginner Java tutorial on Lists, and am presented with the below problem
// 1) Declare am ArrayList of strings
// 2) Call the add method and add 10 random strings
// 3) Iterate through all the elements in the ArrayList
// 4) Remove the first and last element of the ArrayList
// 5) Iterate through all the elements in the ArrayList, again.
Below is my code
import java.util.ArrayList;
import java.util.Random;
public class Ex1_BasicArrayList {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i <= 10; i++){
Random rand = new Random();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder();
sb.append(alphabet.charAt(rand.nextInt(alphabet.length())));
String randy = sb.toString();
list.add(randy);
}
for (int i = 0; i < list.size(); i++){
System.out.print(list.get(i));
}
list.remove(0);
list.remove(list.size()-1);
for (int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
}
I have managed to generate an output, but it is incorrect :(
For my first System.out.print(list.get(i)); I'm trying to get an output for 10 String values, but I get 12.
Sample output: nhgacqhlejph
And when I run the second System.out.println(list.get(i));, I get an output for 8 String Values, which is correct if I started out with 10 in the list, but I have 12, so it means that 4 values were removed :/
Sample output:
g
a
c
q
h
l
e
j
Does anyone know where I went wrong with my code?
To repeat:
I wish to get 10 String values of one letter each from the first System.out.print(list.get(i));
I also want to get 2 less String values from the original list by running the second System.out.println(list.get(i));
First, the for loop should stop at i=9 not at i=10. Hence the loop should be as follows:
for (int i = 0; i < 10; i++){
Second, when printing the list after removing the first and last elements, you're not printing a new line to distinguish between the two outputs. You can add a println between them so that they are separated:
for (int i = 0; i < list.size(); i++){
System.out.print(list.get(i));
}
System.out.println();
list.remove(0);
list.remove(list.size()-1);
Having said this, your implementation is not very efficient in that it creates a StringBuilder in every iteration of the loop as well as a Random object. You can create only one Random object to use it for every iteration. You also don't need a StringBuilder to begin with. The program can be simplified to the following, for example:
ArrayList<String> list = new ArrayList<String>();
Random rand = new Random();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 10; i++){
list.add(String.valueOf(alphabet.charAt(rand.nextInt(alphabet.length()))));
}
First of all: int i = 0; i <= 10; i++ generates 11 chars.
First loop will produce 11 characters (without newline).
Second loop will produce 9 characters (with newlines).
Therefore you see 12 characters (11 from 1st loop + one from the 2nd) in one line and then 8 characters on next lines
for (int i = 0; i <= 10; i++)
Above for lop runs from 0 till 10 both including (so it runs for 11 times) apart from this your code looks fine. change i<=10 to i<10
I had rewritten the program and you could use this for your testing
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Ex1_BasicArrayList {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 10; i++){
Random rand = new Random();
String alphabet = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder();
sb.append(alphabet.charAt(rand.nextInt(alphabet.length())));
String randy = sb.toString();
list.add(randy);
}
printList(list);
// Remove Elements
list.remove(0);
list.remove(list.size()-1);
printList(list);
}
/**
* #param list
*/
private static void printList(List<String> list) {
System.out.println("List size:"+list.size());
System.out.println("List="+list);
for(String listElement: list){
System.out.println(listElement);
}
}
}
Output of the program is
List size:10
List=[k, g, i, a, g, k, s, s, x, t]
k
g
i
a
g
k
s
s
x
t
List size:8
List=[g, i, a, g, k, s, s, x]
g
i
a
g
k
s
s
x
Note
List entries would vary as they are picked randomly, but size would be 10 & 8 before delete & after delete respectively

How do you pass the elements from a one-dimensional array to a two dimensional array

I am trying to figure out how to print the elements of an array with 10 elements per line. Every time I think I have come up with a solution there is some part of the code that we haven't studied yet. So I hit a dead end. I thought about passing the element of my one dimensional array to a two-dimensional array with 10 elements per row then printing the individual rows. But I dont' know how to pass the elements form the one dimensional array to the two dimensional array.
import java.util.*;
public class myFirstArray
{
public static void main(String[] args)
{
double alpha[] = new double[50];
for (int i = 0; i < alpha.length; i++)
if (i < 25)
alpha[i] = i * i;
else
alpha[i] = i * 3;
for (int i = 0; i < alpha.length; i++)
// prints all 50 elements on one line
System.out.print (alpha[i] + ", ");
}
}
You don't need a two-dimensional array for this. Simply print a new line when i = 0 (mod 10) to split up the output into lines of 10 numbers each.
You might need to modify the way you deal with commas a bit, depending on your output specifications, but in general the code will look like:
for (int i = 0; i < alpha.length; i++) {
if(i != 0 && i % 10 == 0) {
System.out.println();
}
System.out.print(alpha[i] + ", ");
}

Transferring the contents of a one-dimensional array to a two-dimensional array

I'm trying to make an encryption program where the user enters a message and then converts the "letters into numbers".
For example the user enters a ABCD as his message. The converted number would be 1 2 3 4 and the numbers are stored into a one dimensional integer array. What I want to do is be able to put it into a 2x2 matrix with the use of two dimensional arrays.
Here's a snippet of my code:
int data[] = new int[] {10,20,30,40};
*for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for (int ctr=0; ictr<data.length(); ictr++){
a[i][j] = data[ctr];}
}
}
I know there's something wrong with the code but I am really lost.
How do I output it as the following?
10 20
30 40
(instead of just 10,20,30,40)
Here's one way of doing it. It's not the only way. Basically, for each cell in the output, you calculate the corresponding index of the initial array, then do the assignment.
int data[] = new int[] {10, 20, 30, 40, 50, 60};
int width = 3;
int height = 2;
int[][] result = new int[height][width];
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
result[i][j] = data[i * width + j];
}
}
Seems like you want to output a 2xn matrix while still having the values stored in a one-dimensional array. If that's the case then you can to this:
Assume the cardinality m of your set of values is known. Then, since you want it to be 2 rows, you calculate n=ceil(m/2), which will be the column count for your 2xn matrix. Note that if m is odd then you will only have n-1 values in your second row.
Then, for your array data (one-dimension array) which stores the values, just do
for(i=0;i<2;i++) // For each row
{
for(j=0;j<n;j++) // For each column,
// where index is baseline+j in the original one-dim array
{
System.out.print(data[i*n+j]);
}
}
But make sure you check the very last value for an odd cardinality set. Also you may want to do Integer.toString() to print the values.
Your code is close but not quite right. Specifically, your innermost loop (the one with ctr) doesn't accomplish much: it really just repeatedly sets the current a[i][j] to every value in the 1-D array, ultimately ending up with the last value in the array in every cell. Your main problem is confusion around how to work ctr into those loops.
There are two general approaches for what you are trying to do here. The general assumption I am making is that you want to pack an array of length L into an M x N 2-D array, where M x N = L exactly.
The first approach is to iterate through the 2D array, pulling the appropriate value from the 1-D array. For example (I'm using M and N for sizes below):
for (int i = 0, ctr = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j, ++ ctr) {
a[i][j] = data[ctr];
}
} // The final value of ctr would be L, since L = M * N.
Here, we use i and j as the 2-D indices, and start ctr at 0 and just increment it as we go to step through the 1-D array. This approach has another variation, which is to calculate the source index explicitly rather than using an increment, for example:
for (int i = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j) {
int ctr = i * N + j;
a[i][j] = data[ctr];
}
}
The second approach is to instead iterate through the 1-D array, and calculate the destination position in the 2-D array. Modulo and integer division can help with that:
for (int ctr = 0; ctr < L; ++ ctr) {
int i = ctr / N;
int j = ctr % N;
a[i][j] = data[ctr];
}
All of these approaches work. Some may be more convenient than others depending on your situation. Note that the two explicitly calculated approaches can be more convenient if you have to do other transformations at the same time, e.g. the last approach above would make it very easy to, say, flip your 2-D matrix horizontally.
check this solution, it works for any length of data
public class ArrayTest
{
public static void main(String[] args)
{
int data[] = new int[] {10,20,30,40,50};
int length,limit1,limit2;
length=data.length;
if(length%2==0)
{
limit1=data.length/2;
limit2=2;
}
else
{
limit1=data.length/2+1;
limit2=2;
}
int data2[][] = new int[limit1][limit2];
int ctr=0;
//stores data in 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
data2[i][j] = data[ctr];
ctr++;
}
else
{
break;
}
}
}
ctr=0;
//prints data from 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
System.out.println(data2[i][j]);
ctr++;
}
else
{
break;
}
}
}
}
}

java two dimensional array sorting

Write a program that prompts the user to enter a nxn matrix of double values and displays a new matrix which has the columns of the initial matrix sorted. You may use any sorting algorithm to solve the problem; please specify the name of the used sorting algorithm into your code header. Your program must implement a sorting algorithm; you cannot use the sorting methods provided in the Array class. The sorting should be implemented into a method, in which a new array is returned and the original array is intact:
public static double[][] sortCol(double[][] a)
The program should also implement a method that prints the initial and the result matrices to user. The print out should be nicely formatted. Here is a sample run:
What is the dimension of matrix? 3
Enter a 3x3 matrix row by row:
0.15 0.875 0.375
0.55 0.005 0.225
0.30 0.12 0.4
The column sorted array is:
0.15 0.005 0.225
0.3 0.12 0.375
0.55 0.875 0.4
This is what I have. I believe it is almost perfect. The sorting method I used I think will sort the column but it may also be sorting the rows. However when I run the program I get this...
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextDouble(Scanner.java:2456)
at Hmwk3_jrgluck.main(Hmwk3_jrgluck.java:16)
Any ideas/ help..
import java.util.Scanner;
public class sdfjasdf {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("What is the dimension of your matrix?");
int matrixdim = input.nextInt();
double[][] matrix = new double[matrixdim][matrixdim];
System.out.println("Enter " + matrixdim + " rows, and " + matrixdim
+ " columns.");
Scanner input1 = new Scanner(System.in);
for (int row = 0; row < matrix.length; row++) {
for (int column = 0; column < matrix.length; column++)
matrix[row][column] = input1.nextDouble();
}
System.out.println(sortCol(matrix));
}
public static double sortCol(double[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
double currentMin = matrix[i][0];
int currentMinIndex = i;
for (int j = i; j < matrix.length; j++) {
if (currentMin > matrix[j][0]
|| (currentMin == matrix[j][0] && matrix[currentMinIndex][1] > matrix[j][1])) {
currentMin = matrix[j][0];
currentMinIndex = j;
}
}
if (currentMinIndex != i) {
double temp0 = matrix[currentMinIndex][0];
double temp1 = matrix[currentMinIndex][1];
matrix[currentMinIndex][0] = matrix[i][0];
matrix[currentMinIndex][1] = matrix[i][1];
matrix[i][0] = temp0;
matrix[i][1] = temp1;
}
}
return sortCol(matrix);
}
}
I suspect that your locale can require commas instead dots in float number format. Try changing your data to
0,15 0,875 0,375
0,55 0,005 0,225
0,30 0,12 0,4
If that is true but you prefer to (or must) use dots instead of comma you can change locale used in Scanner by invoking
input.useLocale(new Locale("en", "US"));
or change global Locale before creating Scanner object with
Locale.setDefault(new Locale("en", "US"));
Also return type of sortCol should be aether
double[][] in case you want to return sorted copy of array (without changing original one). In that case you will need to first create copy of original array
void in case you want to sort original array (you don't have to return reference to object that you already have since you used it as methods argument)
Right now you are trying to return double by invoking again sortCol(matrix), so it again will try to return sortCol(matrix) (and so on) which will lead to stack overflow.

Categories

Resources