I want to write a code which can sort char array element. But the problem is where i want to sort 'a' before 'aa' element and I don't know how to write this part. It always sort 'aa' before 'a'. At first it get inputs from user and if we write '0' it will print sorted array.
import java.util.Scanner;
public class First {
public static void main(String[] args) {
int i, num = 0;
char[][] arr = new char[1000][1000];
char[] index = new char[1000];
Scanner myObj = new Scanner(System.in);
for(i = 0; i < 1000; i ){
arr[i] = myObj.next().toCharArray();
if(arr[i][0] == '0'){
break;
}
else{
num ;
}
for(int j = 0; j < i; j ){
if(arr[i][0] < arr[j][0]){
index = arr[i];
arr[i] = arr[j];
arr[j] = index;
j = 0;
}
}
}
for(i = 0; i < num; i ){
System.out.println(arr[i]);
}
}
}
CodePudding user response:
You have to consider that 'aa'
is not a char, instead 'a'
is a char.
If you want to sort strings the code is nearly okay.
Here an example:
import java.util.Scanner;
public class First {
public static void main(String[] args) {
int num = 0;
String[] arr = new String[1000];
String index = "";
Scanner myObj = new Scanner(System.in);
for(int i = 0; i < 1000; i ){
arr[i] = myObj.nextLine();
if(arr[i].equals("0")){
break;
}
else{
num ;
}
for(int j = 0; j < i; j ){
if(arr[i].compareTo(arr[j]) < 0){
index = arr[i];
arr[i] = arr[j];
arr[j] = index;
j = 0;
}
}
}
System.out.print("[ ");
for(int i = 0; i < num; i ){
System.out.print(arr[i] " ");
}
System.out.println("]");
}
}
Input:
aaaaaaaa
aaaaaaa
aaaaaa
aaaaa
aaaa
aaa
aa
a
0
Expected Output:
[ a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa ]
CodePudding user response:
It is only sorting by the first char of an entered word. Thus it seems like the input-order is preserved.
Issue
Adding some debug-prints shows the comparison of first-char is leading to incorrect or unwanted aa
before a
case:
import java.util.Scanner;
public class First {
public static void main(String[] args) {
int i, num = 0;
char[][] arr = new char[1000][1000];
char[] index = new char[1000];
Scanner myObj = new Scanner(System.in);
for(i = 0; i < 1000; i ){
arr[i] = myObj.next().toCharArray();
if(arr[i][0] == '0'){
break;
}
else{
num ;
}
System.out.printf("Debug [%d]: '%s' \n", i, String.valueOf(arr[i]));
for(int j = 0; j < i; j ){
System.out.printf("Compare '%s' < '%s' = %s\n", arr[i][0], arr[j][0], (arr[i][0] < arr[j][0]));
if(arr[i][0] < arr[j][0]){
index = arr[i];
arr[i] = arr[j];
arr[j] = index;
j = 0;
}
}
}
for(i = 0; i < num; i ){
System.out.println(arr[i]);
}
}
}
Output:
a
Debug [0]: 'a'
aa
Debug [1]: 'aa'
Compare 'a' < 'a' = false
0
a
aa
Refactored and solved
I just added a bit output to interact with user. Also refactored a bit (extract into methods, and control length of arrays with a configurable constant).
import java.util.Scanner;
public class First {
private static final int LENGTH = 10;
private static final Scanner myObj = new Scanner(System.in);
public static void main(String[] args) {
char[][] arr = new char[LENGTH][LENGTH];
System.out.println("Enter elements (each on a new line, 0 stops):");
int num = readArray(0, arr);
System.out.printf("Printing %d elements:\n", num);
printArray(num, arr);
}
private static int readArray(int num, char[][] arr) {
char[] index;
int i;
for (i = 0; i < LENGTH; i ) {
arr[i] = readChars();
if (arr[i][0] == '0') {
break;
} else {
num ;
}
for (int j = 0; j < i; j ) {
if (String.valueOf(arr[i]).compareTo(String.valueOf(arr[j])) < 0) { // entire array compared (chars in sequence) instead only: arr[i][0] < arr[j][0]
index = arr[i];
arr[i] = arr[j];
arr[j] = index;
j = 0;
}
}
}
return num;
}
private static void printArray(int num, char[][] arr) {
int i;
for (i = 0; i < num; i ) {
System.out.println(arr[i]);
}
}
private static char[] readChars() {
return myObj.next().toCharArray();
}
}
Output is as expected (a
before aa
):
Enter elements (each on a new line, 0 stops):
z
aa
b
a
0
Printing 4 elements:
a
aa
b
z
How it works
Entire array compared (chars in sequence) instead only the first char of each array.
before:
arr[i][0] < arr[j][0]
after:
String.valueOf(arr[i]).compareTo(String.valueOf(arr[j])) < 0
Bonus Tip: Naming can help to spot logical bugs
When renaming the methods and variable names it may get a bit clearer what the program does, we call it semantics:
- myObj becomes
scanner
- i becomes
index
or wordIndex orlineIndex
andlastLineIndex
- j is actually a character-index ... but in this short scope it should can be self-evident
- char-arrays can be
lines
or words - num becomes
length
of lines orcountLines
- and all the method-names are adjusted in semantics to operate on lines, expressed by name
<verb>Lines
import java.util.Scanner;
public class First {
private static final int LENGTH = 10;
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
char[][] lines = new char[LENGTH][LENGTH];
System.out.println("Enter elements (each on a new line, 0 stops):");
int countLines = readLines(lines);
System.out.printf("Printing %d elements:\n", countLines);
printLines(lines, countLines);
}
private static int readLines(char[][] lines) {
int linesRead = 0;
for (int lineIndex = 0; lineIndex < LENGTH; lineIndex ) {
lines[lineIndex] = readLine();
if (lines[lineIndex][0] == '0') {
break;
} else {
linesRead ;
}
sortLines(lines, lineIndex);
}
return linesRead;
}
private static void sortLines(char[][] lines, int lastLineIndex) {
for (int j = 0; j < lastLineIndex; j ) {
if (String.valueOf(lines[lastLineIndex]).compareTo(String.valueOf(lines[j])) < 0) { // entire array compared (chars in sequence) instead only: arr[i][0] < arr[j][0]
char[] line = lines[lastLineIndex];
lines[lastLineIndex] = lines[j];
lines[j] = line;
j = 0;
}
}
}
private static void printLines(char[][] lines, int length) {
for (int i = 0; i < length; i ) {
System.out.println(lines[i]);
}
}
private static char[] readLine() {
return scanner.next().toCharArray();
}
}