java sorting in alphabetical order [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I am attempting to sort a list of names in alphabetical order and I keep getting the error Exception in thread "main" java.lang.NullPointerException and I don't know why.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;
public class alphabeticalOrder {
static String names[];
static int count = 0;
static String sorting;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String[] names = new String[500];
File namesFile = new File("names.txt");
Scanner inputFile = new Scanner(namesFile);
while (inputFile.hasNextLine()) {
String line = inputFile.nextLine();
String[] namesDetails = line.split(" ");
names[count] = namesDetails[0];
count++;
}
sort();
System.out.println(Arrays.toString(names));
}
public static void sort() {
int namesLength = names.length;
for (int i = 0; i < namesLength - 1; i++) {
for (int j = 0; j < namesLength - 1; j++) {
if (names[j].compareTo(names[j - 1]) > 0) {
sorting = names[j - 1];
names[j - 1] = names[j];
names[j] = sorting;
}
}
}
}
}
Customers txt has these names
Smith, Alexandra
Downes, Trish
Akbal, Maria
and the array must equal 500

Change
if (names[j].compareTo(names[j - 1]) > 0) {
to
if (names[j] != null && names[j].compareTo(names[j - 1]) > 0) {
And the annoying null pointer exception will go away.
If you ever get over your 500 String array obsession I suggest you try TreeSet since it will do all the sorting work for you.
public static void main(String[] args)
{
Set<String> alphabetical = new TreeSet<String>();
alphabetical.add("A");
alphabetical.add("Z");
alphabetical.add("M");
System.out.println(alphabetical);
}
outputs: [A, M, Z]

Your names array has 500 elements, most of which are null. That's why you are getting NullPointerException, when you call names[j].compareTo() for a null reference.
You should only attempt to sort as many names as you get as input.
Instead of
int namesLength = names.length;
Try
int namesLength = count;
Since count holds the number of inputs you actually have.
BTW, your sort() method has other problems :
The loops should go from 0 to namesLength - 1, so the condition should be j < namesLength
names [j-1] would give you ArrayIndexOutOfBoundsException when j==0

You have the array in size 500 and number your names are 6.
when you assign six names to first six indexes of the array, the rest indexes are still having null value. Therefor, comparing with the null value will throw NullPointerException.
why?
Because Objects in Java initialized by null value when they are defined for the first time.
Suggestion :
Try to use ArrayList which shrinks and expands by itself

Related

Java Selection Sort implementation not working output "[I#15db9742" [duplicate]

This question already has answers here:
What's the simplest way to print a Java array?
(37 answers)
Closed 5 years ago.
Hey I'm trying to test my selection sort algorithm but all the output I get in the console is just "[I#15db9742"
Could someone please explain to me why I'm getting junk output? It is really baffling me, could it possible be a problem with the IDE or is it something in the code?
Thanks
import java.util.Arrays;
public class SelectionSorterTest {
// Factories
// Queries
/**
* Sorts a copy of the input array.
* #param input an array.
* #return a sorted copy of input.
*/
public static int[] sort (int[] input) {
int[] sorted = Arrays.copyOf(input, input.length);
for(int i = 0; i < sorted.length - 1; i++)
{
int minIndex = i;
for(int j = i + 1; j < sorted.length - 1; j++)
{
if(sorted[j] < sorted[minIndex])
{
minIndex = j;
}
}
if(i != minIndex)
{
swap(sorted, minIndex, i);
}
}
return sorted;
}
// Commands
// Private
// disabled constructor
private SelectionSorterTest () { }
private static void swap (int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
public static void main(String[] args)
{
int[] Array = {9,7,6,4,3,2,21,1};
System.out.println(sort(Array));
}
}
By using this line System.out.println(sort(Array)); you are printing out an array's address in memory. Use a loop to print the element of that array!
By the way, your algorithm is incorrect because you are missing the last element in the for loop. Remove the -1 part out of the loop to correct it. Thanks
You are printing array object directly on console.
Use java.util.Arrays.toString(int[]) method. It returns a string representation of the contents of the specified int array.
In your case it would be System.out.println(Arrays.toString(sort(Array)));
I#15db9742 is the the result of calling long[].toString(), consisting of the type signature of long[] plus an '#' plus the hashCode() (thank you EJP)
Access the element in the array to print it.
public static void main(String[] args)
{
int[] Array = {9,7,6,4,3,2,21,1};
for(int n : sort(Array)){
System.out.println(n);
}
}
The problem is that you print the array directly to the console:
you need to use Arrays.toString(anArray) or your custom function:
In case of using Arrays.toString(anArray):
First you need to import the Arrays class to our program:
import java.util.Arrays;
Second Then change your print statement from:
System.out.println(sort(Array));
To be
System.out.println(Arrays.toString(sort(Array)));
In case of your custom method:
Implement your own function like this one, just to exclude the brackets:
private static void printArray(int[] anArray) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < anArray.length; i++) {
if (i > 0) {
sb.append(", ");
}
sb.append(anArray[i]);
}
System.out.println(sb.toString());
}
And change your print statement to be:
System.out.println(printArray(sort(Array)));

addition of distinct substrings of multiple strings to a Treeset

Question - You are given n strings w1, w2, ......, wn. Let Si denote the set of strings formed by considering all unique substrings of the string wi. A substring is defined as a contiguous sequence of one or more characters in the string. More information on substrings can be found here. Let S = {S1 U S2 U .... Sn} .i.e S is a set of strings formed by considering all the unique strings in all sets S1, S2, ..... Sn
My approach - I am using a TreeSet and filling it directly rather than creating a list, a set, and a sorted list.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int cases = Integer.parseInt(in.nextLine());
String[] a = new String[cases];
int i, c;
//Adding directly to the Set prevents a larger list because you remove the duplicates
Set<String> set = new TreeSet<String>();
for( i = 0; i < cases; i++)
{
a[i] = in.nextLine();
for (c = 0; c < a[i].length(); c++)
{
for (i = 1; i <= a[i].length() - c; i++)
{
String sub = a[i].substring(c, c + i);
set.add(sub);
}
}
}
}
for input :
2
aab
aac
i got a runtime error :
Exception in thread "main" java.lang.NullPointerException
at Solution.main(Solution.java:32)
can anyone explain me why i am getting this runtime error , what should i do to avoid this null pointer exception and why did this occur in the first place? please help me if you can
We have a lot of memory nowadays. But even old days it was considered a bad practice to use the same variable for different purposes. Use each one for one purpose and it will be all right. Code is clear and undersatndable and no more unexplainable exceptions:
import java.io.StringReader;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(new StringReader("2\naab\naac\n"));
int cases = Integer.parseInt(in.nextLine());
String[] a = new String[cases];
//int i, c;
// Adding directly to the Set prevents a larger list because you remove
// the duplicates
Set<String> set = new TreeSet<String>();
for (int i = 0; i < cases; i++) {
a[i] = in.nextLine();
for (int c = 0; c < a[i].length(); c++) {
for (int ii = 1; ii <= a[i].length() - c; ii++) {
String sub = a[i].substring(c, c + ii);
set.add(sub);
}
}
}
System.out.println(set);
}
}
P.S. Homework - make name of variables meaningful and unforgetable.

Problems with Finding the Longest word in a Data File

Sounds Pretty Straightforward, but for me it's quite strange. I'm trying to import a data file (which I've done successfully), and use this and compare each and every word to see which one is the longest. So far, it is not working (index out of bounds), and when I did manipulate it to work (incorrectly), it gave me the wrong word as the longest one.
This is what I have so far...
Main File:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Collections;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import static java.lang.System.*;
public class FancyWordsRunner
{
private static int max = 0;
public static void main( String args[] ) throws IOException
{
ArrayList<String> wordList = new ArrayList<String>();
{
String ray = "";
Scanner welcome = new Scanner(new File("fancywords.dat"));
while(welcome.hasNext())
{
ray = welcome.next();
wordList.add(ray);
for(int i = 0; i<wordList.size(); i++)
{
int j = i+1;
if(wordList.get(j).length()>wordList.get(i).length())
max = j;
}
}
}
String maximum = wordList.get(max);
out.println(maximum);
}
}
fancywords.dat:
2013 UIL STATE CONTEST
PROGRAMMING IS FUN
TODAY IS SATURDAY
Current Output:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at FancyWordsRunner.main(FancyWordsRunner.java:35)
How about replacing your while loop with something like this.
String longestSoFar = "";
while (welcome.hasNext()) {
String current = welcome.next();
if (current.length() > longestSoFar.length()) {
longestSoFar = current;
}
}
I realize that your bug has been identified by other answers, but, you do realize that this problem can be solved in a much simpler way?
public static void main( String args[] ) throws IOException {
String max = "";
Scanner welcome = new Scanner(new File("fancywords.dat"));
while(welcome.hasNext()) {
String ray = welcome.next();
if (ray.length() > max.length()) {
max = ray;
}
}
System.out.println(max);
}
In your first iteration, you've only added one item to the list, so the size is 1 meaning only an index of 0;
int j = i+1;
if(wordList.get(j)
This is trying to access index 1
Walk through:
1)
ArrayList<String> wordList = new ArrayList<String>();
// wordlist.size() = 0; available indices - none
2)
wordList.add(ray);
// wordlist.size() = 1; available indices - 0
3)
int j = i+1; // i = 0; j = 1
if(wordList.get(j) // access index j
// oops!; There is no index j
This causes an IndexOutOfBoundsException.
EDIT: Alternative - you really don't need a list to perform this task
String maxWord = "";
String current = "";
while(welcome.hasNext()){
current = welcome.next();
if (current.length() > maxWord.length()){
maxWord = current;
}
}
System.out.println(maxWord);
for(int i = 0; i<wordList.size(); i++)
{
int j = i+1;
You're setting up your for loop to make sure i is never out of bounds, but then you set j equal to one larger than i, so on the last run of the loop, when i is at the last index, j is one larger than the last index (and out of bounds).
Try this:
for(int i=0; i<(wordList.size()-1); ++i)
Solution to the logic error:
for(int i = 0; i<wordList.size();++i) {
if(wordList.get(i).length() >= wordList.get(max).length()) {
max = i;
}
}
(This also gets rid of the j that was causing the IndexOutOfBoundsException in the first place.)
And as others have pointed out, there is some redundancy in your program. Changing your for loop to my suggestion will fix your logic problem and make your program output the correct result. The other answers all get rid of the ArrayList, which isn't totally necessary, but if you want to simplify your solution and keep the ArrayList, your while loop could look something like this:
String longestWord = "";
Scanner welcome = new Scanner(new File("fancywords.dat"));
while(welcome.hasNext()) {
ray = welcome.next();
wordList.add(ray);
if(ray.length() > longestWord.length()) {
longestWord = ray;
}
}
This solution simplifies your answer, saves some time in the program and keeps the ArrayList (you still have every word saved in memory).
Your for loop was running a LOT and checking every word numerous times. Once we know that CONTEST is the longest of the first four words, we don't need to see whether PROGRAMMING is longer than the first three or not, just whether it's longer than CONTEST, and we don't need to compare SATURDAY to any word other than PROGRAMMING, which was established as the longest word when it was read and continued to be the longest word between then and reading SATURDAY, etc. If all we care about is the longest word, we only need to compare each word to the current longest word.
And because your ArrayList is still in memory, you can recreate the original words you read in, find the shortest word, find the average word length, etc., whatever you want to do with it.

read in 2 files, convert to arrays, then print what has been called

So the data in the files are girls & boys names. The order is the popularity and the corresponding number is the number of times the name was registered in a certain year. eg:
Frank 678
William 2
etc
There are 1000 names in each file. I need to load each file into string[] & int[], then when a name is written into the keyboard, the program must go thou the arrays, find the name, print out the index of the string array (less one obviously) & the number that is in the int[]. my current code is just returning 1000, 1000. so I'm not sure where I'm going wrong
Hope this makes sense, its for a uni question. Here is my code so far, sorry if it seems primitive, I'm still learning :-)
import java.io.*;
import java.util.*;
public class H252{
static final int ENTRIES = 1000; // Number of entries in the file
public static int isInArray(String[] entries, String target) {
int number = 0;
for (int i = 0; i < entries.length - 1; i++)
if (entries[i] == target)
number = i + 1;
else
number = ENTRIES;
return number;
}
public static void LoadFile(String[] entries, int[] count, String filename) {
Scanner file = new Scanner(filename);
int a = 0;
int b = 0;
while (file.hasNextLine()) {
if (file.hasNext())
entries[a++] = file.next();
if (file.hasNextInt())
count[b++] = file.nextInt();
}
}
public static void main(String[] args) {
while (JPL.test()) {
Scanner kb = new Scanner(System.in);
String getName = kb.next();
String[] boyNames = new String[ENTRIES];
String[] girlNames = new String[ENTRIES];
int[] countB = new int[ENTRIES];
int[] countG = new int[ENTRIES];
LoadFile(girlNames, countG, "girlnames.txt");
System.out.print(isInArray(girlNames, getName)
+ countG[isInArray(girlNames, getName) - 1]);
LoadFile(boyNames, countB, "boynames.txt");
System.out.print(isInArray(boyNames, getName)
+ countB[isInArray(boyNames, getName) - 1]);
}
}
}
java.lang.NullPointerException
at H252.isInArray(H252.java:21)
at H252.main(H252.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
Your problem is that you compare strings with ==
That way of doing you compare the references and therefore it is always different and you reach the max value and return ENTRIES.
To compare strings in java use .equals
in your code replace
if (entries[i] == target)
with
if (entries[i].equals(target))
and it should work.
EDIT
Another mistake is that with
for (int i = 0; i < entries.length - 1; i++)
you never check your last element of entries. Correct your code to
for (int i = 0; i < entries.length; i++)
Try that instead:
public static int isInArray(String[] entries, String target) {
int number = ENTRIES;
for (int i = 0; i < entries.length; i++){ // You were not checking the last element of the array
if (entries[i].equals(target)){ //if you want to compare String use method equals
number = i + 1;
} // With the previous else comment you were almost certain to always get ENTRIES value returned all the time
}
return number;
}
I don't know if it solves all the issues but that's a beginning ;)

sorting strings using bubblesort in java

I tried sorting strings using bubblesort, but I dont know whether it makes any sense but can someone just help me figure out how to sort strings and let me know if my logic is correct? i have converted the strings to character just to check if they are in alphabetical order..eg app ban acc will be sorted to acc app and ban..can anyone give the logic to this problem.
import java.io.*;
import java.util.*;
class sort
{
public static void main(String args[])throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter the strings");
String str=br.readLine();
StringTokenizer st=new StringTokenizer(str,",");
String s1=st.nextToken();
String s2=st.nextToken();
String s3=st.nextToken();
char ch1[]=s1.toCharArray();
char ch2[]=s2.toCharArray();
char ch3[]=s3.toCharArray();
if ((ch1[0]<ch2[0])&&(ch1[0]<ch3[0])&&(ch2[0]<ch3[0]))
for(int i=0;i<4;i++)
{
System.out.println(+ch1[i]);
System.out.println(+ch2[i]);
System.out.println(+ch3[i]);
}
else if((ch2[0]<ch1[0]&&ch2[0]<ch3[0]&&ch1[0]<ch3[0]) )
for(int i=0;i<4;i++)
{
System.out.println(+ch2[i]);
System.out.println(+ch1[i]);
System.out.println(+ch3[i]);
}
else if((ch3[0]<ch1[0])&&(ch3[0]<ch2[0])&&ch1[0]<ch2[0])
for(int i=0;i<4;i++)
{
System.out.println(+ch3[i]);
System.out.println(+ch1[i]);
System.out.println(+ch2[i]);
}
}
}
Bubble sort, also known as sinking sort, is a simple sorting algorithm that works by repeatedly stepping through the list to be sorted, comparing each pair of adjacent items and swapping them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm gets its name from the way smaller elements "bubble" to the top of the list. Because it only uses comparisons to operate on elements, it is a comparison sort. Although the algorithm is simple, it is not efficient for sorting large lists; other algorithms are better. Wikipedia
The following is the sort-cut way to do so.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
final public class Main
{
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter the strings:->");
String str=br.readLine();
String strArr[]=str.split(" ");//your sentence will be split into words.
Arrays.sort(strArr);
for(int i=0;i<strArr.length;i++)
{
System.out.println(strArr[i]);
}
}
}
If you wish, you can apply your own logic as follows.
final public class Main
{
public static void main(String[] args) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter the strings:->");
String str=br.readLine();
String strArr[]=str.split(" ");
String temp;
for(int i = 0; i<strArr.length - 1; i++)
{
for(int j = 0; j<strArr.length - 1; j++)
{
if(strArr[j].compareTo(strArr[j+1]) > 0)
{
temp = strArr[j];
strArr[j] = strArr[j+1];
strArr[j+1] = temp;
}
}
}
for(int i=0;i<strArr.length;i++)
{
System.out.println(strArr[i]);
}
}
}
In both the cases, I have assumed spaces as word separator and not commas , that you're using in your example.
First you need to choose how do you want to sort strings ?
is it by length ? is it by alpha order ?
After you choose the appropriated method, you just need to sync it for the existing sorting method of bubblesort.
public static int[] bubble(String[] str_arr) {
for (int i = 0, temp; i < str_arr.length-1; i++) {
for(int j = 0; j < str_arr.length-1; j++) {
if (str_arr[j] < str_arr[j+1]) {
temp = str_arr[j];
str_arr[j] = str_arr[j+1];
str_arr[j+1] = temp;
}
}
}
return str_arr;
}
As i mentions theres couple of ways of comparing strings:
Length - length of a string
Lexicographically - explanation here
If we want to use one of the two method mentioned above, we should change the line:
if (str_arr[j] < str_arr[j+1])
to
if (str_arr[j].length < str_arr[j+1].length)
Or for the lexicographically order we will use:
if (str_arr[j].compareTo(str_arr[j+1].length) < 0)
compareTo is a java String method that checking lexicog.. order.
it returnes:
0 - strings are identical.
positive number - first string is bigger then second string.
negative number - first string is smaller then second string.
String implements interface Comparable (so overrides compareTo() method), thus you can compare two strings (>,<,>=,<=). That's why you don't have to compare every char element by element. Not worth trying even.
The solution: put Strings into array:
String[] stringArray = new String[]{"element1","element2"};
and then use default bubble-sort algorithm:
for (int x = 1; x < stringArray.length; x++) {
for (int y = 0; y < stringArray.length - x; y++) {
if (stringArray[y].compareTo(stringArray[y + 1]) > 0) {
temp = stringArray[y];
stringArray[y] = stringArray[y + 1];
stringArray[y + 1] = temp;
}
}
}
and you should receive sorted array.

Categories

Resources