Program does nothing when run? - java

I wrote this program and have all the code that it should need. At first I was having some run-time errors, but I easily fixed those. Now it shows no visible errors, and when I run it, it does nothing.
In essence, what it should be doing is printing out a list of classes with students and id numbers, which have been merged from two files. It matches the ids of students to the ids of classes and forms them into a list. This all seems to be happening, it just isn't printing it out.
My code is below. Please let me know what you think. I have included a description at the top and markers of where I think the issue starts and ends. Also after the code there is an example of the contents of the two files.
/* This program reads in two files, one which contains a list of student names and id numbers, and another which lists class id numbers.
* Then, the data is taken into arrays which are then used in different sorts. One sorts the id numbers numerically, one sorts the students
* alphabetically, and one sorts the class names alphabetically.The id numbers of students are matched to class and both are compiled into
* a list which then prints out first the class name, then the list of students within it. All done alphabetically.
*
*/
import java.io.*;
import java.util.Scanner;
public class MergingFiles {
public static void main(String[] args) throws IOException {
String[][] studentArray = new String [1000][2];
String[][] classArray = new String[4000][2];
int count = 0;
Scanner sc = new Scanner(new File("students.txt"));
while(sc.hasNextLine()){
String studentInput = sc.nextLine();
String name = studentInput.substring(0, 30).trim();
String id = studentInput.substring(30).trim();
studentArray[count][0] = name;
studentArray[count][1] = id;
count++;
}
for(int i = 0; i < count-1; i++){ //sorts id number numerically
for(int j = 0; j < count-1-i; j++){
if(studentArray[j][1].compareTo(studentArray[j+1][1]) > 0){
String holder = studentArray[j][1];
studentArray[j][1] = studentArray[j+1][1];
studentArray[j+1][1] = holder;
}
}
}
int counter3 = 0;
Scanner sc2 = new Scanner(new File("classes.txt"));
while(sc2.hasNextLine()){
int counter2 = 0;
String classInput = sc2.nextLine();
while(classInput.charAt(counter2)!= ' '){
counter2++;
}
String className = classInput.substring(0, counter2);
while(classInput.charAt(counter2) == ' '){
counter2++;
}
String idNum = classInput.substring(counter2);
int low = 0;
int high = count - 1;
int mid = (high - low)/2 + low;
while(!idNum.equals(studentArray[mid][1])){ //binary search
if(idNum.compareTo(studentArray[mid][1]) < 0){
high = mid - 1;
}else
low = mid + 1;
mid = (high - low)/2 + low;
}
String studentName2 = studentArray[mid][1];
classArray[counter3][0] = className;
classArray[counter2][1] = studentName2;
}
//I THINK THE ISSUE STARTS HERE
for(int a = 0; a < (counter3 - 1); a++){ //sort class names alphabetically
for(int b = 0; b < counter3-1-a; b++){
if(classArray[b][0].compareTo(classArray[b+1][0]) > 0){
String holder2 = classArray[b][0];
classArray[b][0] = classArray[b+1][0];
classArray[b+1][0] = holder2;
}
}
}
for(int c = 0; c < (counter3 - 1); c++){ //sort class names alphabetically
for(int d = 0; d < counter3-1-c; d++){
if((classArray[d][0].compareTo(classArray[d+1][0])) == 0){
if(classArray[d][1].compareTo(classArray[d+1][1]) > 0){
String holder3 = classArray[d][1];
classArray[d][1] = classArray[d+1][1];
classArray[d+1][1] = holder3;
}
}
}
}
String currentClass = "";
for(int s = 0; s < counter3; s++){
if(!classArray[s][0].equals(currentClass)){
currentClass = classArray[s][0];
System.out.print(currentClass);
}
System.out.print(classArray[s][1]);
}
//THIS IS WHERE THE ISSUE ENDS
}
}
studentArray contents example (without //'s):
//Lambert, Desmond 451825335
//Johnston, Michaela 143547061
//Wells, Shirley 942366473
// Blevins, Dawson 407183976
// Roy, Benjamin 575069268
// Mitchell, Jaquan 285633099
// Freeman, Nayeli 312234364
// Benson, Myles 755491358
// Wilkinson, Stephany 384506082
// Bradshaw, Nikki 159900631
// Davila, Sarah 788743448
// Wyatt, Eddie 253830483
// Ortega, Josh 891761169
// Pruitt, Deven 533987743
// Harrison, Aliyah 710258372
// Perez, Emerson 611325979
// Stanton, Sonny 430095944
// Rice, Bruce 301915859
// Callahan, Brandon 327995163
// Torres, Jovan 629852538
// Mathis, Timothy 936191071
// Calhoun, Nathanael 107519769
// Mullen, Malik 711847273
// Sims, Marvin 519717164
// Pham, Siena 530779316
// Vincent, Demetrius 618276821
etc.
classArray contents example (without //'s):
//ECON101 938597595
//BUS100 951008337
//ECON408 620903271
//PHY101 695451867
//COSC150 392023624
//MATH215 557048539
//COSC325 495522117
//BUS215 185642398
//ECON408 807662685
//MATH215 920062540
//MATH325 517786537
//PHY150 915173832
//BUS100 518392974
//BUS408 410797598
//BUS215 152414047
//PHY150 561839967
etc.
Thanks.

I think you should add tokens in the txt file and using StringTokenizer have the columns captured per row in the arrays. Once you have all the data in the array, then you should be process the data to merge.
When you are saying "The id numbers of students are matched to class and both are compiled into a list which then prints out first the class name, then the list of students within it. All done alphabetically."
Are you intend to match the id in the student file with class file? if so, the above example values does not show it though.
Also if you have the student and classtxt files, share those and I can try running with them.

Basic problem is,counter3 is never set to anything besides 0, so the body of your print loop never executes. You probably want to increment counter3 here, and also use it as the index into classArray for both of these assignment statements (I think you're mistakenly using counter2 to set the student name):
classArray[counter3][0] = className;
classArray[counter2][1] = studentName2;
counter3++;
By the way, your sorting is broken because you're sorting the student ids without also sorting their names - make sure to shuffle the whole Student[] (studentArray[i]) forward instead of only studentArray[i][1]. Here's a working example using Arrays.sort(T[] a, Comparator<? super T> c):
// sort students by id number and sort null elements to end of array
Arrays.sort(studentArray, new Comparator<String[]>() {
public int compare(String[] student1, String[] student2)
{
if (student1[1] == null) return 1;
if (student2[1] == null) return -1;
return student1[1].compareTo(student2[1]);
}
});

Related

Reversing strings in Java (loops) until "done"

this is a lab for class I'm trying to do. Here's the instructions:
Write a program that takes in a line of text as input, and outputs that line of text in reverse. The program repeats, ending when the user enters "Done", "done", or "d" for the line of text.
Ex: If the input is:
"Hello there
Hey
done"
the output is:
"ereht olleH
yeH"
And here's what I have right now:
public class LabProgram {
public static void main(String[] args) {
/* Type your code here. */
Scanner scnr = new Scanner(System.in);
String[] inputs = new String[100];
String input;
int i = 0;
while (true) {
input = scnr.nextLine();
if(input.equals("Done") || input.equals("done") || input.equals("d"))
break;
inputs[i] = input;
i++;
}
for (int j = 0; j < i; j++) {
int length = inputs[j].length();
String reverse = "";
for (int k = length - i; k >= 0; k--) {
reverse = reverse + inputs[j].charAt(k);
}
System.out.print("\n" + reverse);
}
}
}
Current output
What am I doing wrong??
Iterate through the array, and reverse elements at every index.
This solution is time consuming but does your job
for (int j = 0; j < inputs.lenght; j++) {
int length = inputs[j].length();
char a;
String rev = "";
for(int i =0; i< length; i++){
a = inputs[j].charAt(i);
rev = a + rev;
}
System.out.println(rev);
}
*Try to use StringBuilder And use method reverse -- #Artur Todeschini
To add to what Artur said, an ArrayList of StringBuilders could do the trick quite well:
for(StringBuilder nextEntry : stringBuilderList)
{
nextEntry.reverse();
}
The enhanced for-loop will go through each entry in the ArrayList, and the StringBuilder's reverse will change the order of the letters.
EDIT TO SHOW FORMATTING
ArrayList<StringBuilder> stringBuilderList= new ArrayList<>();
*note. given that this is for a lab, its probably for learning purposes and using built-in classes that does all the work for you are usually not the intended solution. -- #experiment unit 1998X
Try to use StringBuilder
And use method reverse
This is another "ArrayList and StringBuilder-less" version.
Create two Strings, one filled and one empty:
String nextString = stringArray[i],
template = new String();
Loop through the length of the String, adding the next character in from the end each time through.
int length = nextString.length() - 1;
for(int j = 0; j < length; j++)
{
template += nextString.charAt(length - j);
}
Add the whole String to the String array's index
stringArray[i] = template;
NOTE
This is an inner loop for a String array and is NOT complete code

Java - Problem at sorting array list using bubblesort

I have a problem at the moment I have a college assignment and we need to list a file that contain books and should be sorted A to Z,
My sort algorithm is a bubble sort and at the moment is not sorting alphabetically but don't give errors, I cant see where I should change to make it work as the coding seems correct to me.
We are not allowed to use collections so that is the reason I am not using sort().
package Book;
public class AlphabeticalOrderTitle{
//Global variables
public static String input;
public static int bookId;
public static String bookTitle;
public static String authorName;
public static boolean isAvailable;
public static void main(String[] args)
{
ArrayList<Book> books = BubbleSort();
System.out.println(linearSearch(books));
}
public static ArrayList<Book> loadData() {
//Creating an array list;
ArrayList<Book> books = new ArrayList<>();
try {
//Here we start reading our file
BufferedReader br = new BufferedReader(new FileReader("Book.txt"));
//This header string will allow to skip the header so does not mismatch with getter and setters.
String header = br.readLine();
//This string will read the lines.
String contentLine = br.readLine();
//Giving our array name data;
String [] data;
//Here we loop to continue the reading of data for each array box.
while (contentLine != null) {
data = contentLine.split(",");
bookId = Integer.parseInt(data[0]);
bookTitle = data[1];
authorName = data[2];
isAvailable = Boolean.parseBoolean(data[3]);
books.add(new Book(bookId, bookTitle, authorName, isAvailable));
contentLine = br.readLine();
}
}catch (IOException ex) {
Logger.getLogger(SearchBookAuthor.class.getName()).log(Level.SEVERE, null,ex);
}
return books;
}
public static int linearSearch(ArrayList<Book> array){
//Variables for holding values
int n;
String temp;
// Going one by one the elements in the array
for(int g = 0; g < array.size(); g++){
//Getting the array size from the file and giving the array name a size
n = array.size();
String names[] = new String[n];
//Load all the names
for(int i = 0; i < n; i++) {
names[i] = array.get(g).getBookTitle();
}
//Bubble sort starts
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (names[i].compareTo(names[j]) > 0)
{
temp = names[i];
names[i] = names[j];
names[j] = temp;
}
}
}
//Print sorted
System.out.println(names[n-1]);
}
return -1;
}
}
Outpout:
Captains
Romeo
Don
-1
and what I am aiming is Captains, Don, Romeo.
My book.txt contains is like this:
book
Any suggestion for me to fix it ? Thank you very much.
Bubble Sort Example
I linked a bubble sort example. You can click on Java to see a version in Java. And you can see there are differences between yours and theirs, even though they are very similar.
What I would do is do it manually. That is, grab some paper, write down what your array looks like then actually pretend you're the computer and see what you end up with. It will be a good exercise for you, and you'll probably figure out what you're doing wrong.
First of all, BubbleSort() is not an appropriate name for this method as all it does is reading the file and storing the content inside the list.
If this course is not an upper-level algorithms class, you could probably use java libraries to sort your list instead.
Something like this should work and produce the needed result:
Collections.sort(books);
Also, I usually just do the following:
List books = new ArrayList<>();
In case you have to implement bubble sort, please use the following link which shows how to use bubble sort to sort string arrays: https://www.geeksforgeeks.org/sorting-strings-using-bubble-sort-2/
For array A of 'n' elements A[n], then the first loop in bubble sort always ends with n-1.
The idea of bubble sort is to compare the adjacent elements and then swap if the are not in order (increasing / decreasing depending on the use case).
So, when i=n-1, as you mentioned in your first for loop=>j=n-1. We are basically comparing A[i=n-1] to A[j=n-1].
//Bubble sort starts
for (int i = 0; i < n-1; i++)
{
for (int j = i + 1; j < n; j++)
{
if (names[i].compareTo(names[j]) > 0)
{
temp = names[i];
names[i] = names[j];
names[j] = temp;
}
}
}
you can try a quick dry-run whenever you are stuck in such problems by substituting with small numbers and writing the loop content on paper. Helps a lot to learn and to build logic. :)
So after a couple days working on it I have come with a working solution thanks to everyone.
public class Alphabetical_Order {
//Global variables
public static String input;
public static int bookId;
public static String bookTitle;
public static String authorName;
public static boolean isAvailable;
//Creating an array list;
public static ArrayList<Book> books = new ArrayList<>();
public static void main(String[] args)
{
loadData();
int n = 0;
String temp;
//Scanner s = new Scanner(System.in);
System.out.print("Enter number of names you want to enter:");
//get size of arraylist
for (int g = 0; g < books.size(); g ++) {
n = books.size();
}
String names[] = new String[n];
//Names to be get from user
Scanner s1 = new Scanner(System.in);
System.out.println("Enter all the names:");
for(int i = 0; i < n; i++)
{
names[i] = books.get(i).getAuthorName();
}
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (names[i].compareTo(names[j])>0)
{
temp = names[i];
names[i] = names[j];
names[j] = temp;
}
}
}
System.out.print("Names in Sorted Order:");
for (int i = 0; i < n - 1; i++)
{
System.out.print(names[i] + ",");
}
System.out.print(names[n - 1]);
}
public static void loadData() {
try {
//Here we start reading our file
BufferedReader br = new BufferedReader(new FileReader("Book.csv"));
//This header string will allow to store the header so does not mistach with getter and setters.
String header = br.readLine();
//This string will read the lines.
String contentLine = br.readLine();
//Giving our array name data;
String [] data;
//Here we loop to continue the reading of data for each array box.
while (contentLine != null) {
data = contentLine.split(",");
bookId = Integer.parseInt(data[0]);
bookTitle = data[1];
authorName = data[2];
isAvailable = Boolean.parseBoolean(data[3]);
books.add(new Book(bookId, bookTitle, authorName, isAvailable));
contentLine = br.readLine();
}
}catch (IOException ex) {
Logger.getLogger(SearchBookAuthor.class.getName()).log(Level.SEVERE, null,ex);
}
}}

Cannot update an array in Main from nested loops inside of Main. How can I assign it's value?

So, I am writing my program when suddenly, I run into a problem in which my three arrays print as null, 0 and null.
The program reads values from a file, and assigns them to the three arrays based on the iteration number.
Here is my code:
String mushroom []= new String [10];
int weight [] = new int [10];
String cooking[] = new String [10];
FileReader fr = new FileReader ("7J_Mushrooms.csv");
BufferedReader br = new BufferedReader (fr);
System.out.println("Mushroom\t\tWeight\t\tCooking\n=======================================================");
String line = "";
while ((line = br.readLine()) != null){
String [] temp = line.split(",");
for (int i = 0; i < temp.length; i++){
if(i == 0){
mushroom[i] = temp[i];
}
else if (i == 1){
weight[i] = Integer.parseInt(temp[i]);
}
else{
cooking[i] = temp[i];
}
}
}
// This bit just sorts them by weight in ascending order like a parallel array
for (int i = 0; i < weight.length-1; i++){
for (int j = 0; j < weight.length-1;j++){
if (weight[j] > weight[j+1]){
int temp = weight [j];
String tempMush = mushroom [j];
String tempCook = cooking [j];
weight[j] = weight[j+1];
mushroom[j] = mushroom[j+1];
cooking[j] = cooking[j+1];
weight[j+1] = temp;
mushroom[j+1] = tempMush;
cooking[j+1] = tempCook;
}
}
}
for (int i = 0; i < weight.length; i++){
System.out.print(mushroom[i] + "\t\t" + weight[i] + "\t\t" + cooking[i] + "\n");
}
When I print the values of the arrays inside of the for loop, the values are correct, however outside of the while loop the code is printed as null, null and 0. However, the last three values are printed but I am sure that is something to do with my problem.
Anyway, I believe it is to do with scope.
After some searching, I discovered that java is "Pass by Value" instead of "Pass by Reference". I do not really understand this principal, but to my understanding it affects methods in particular, but all of my code is under a single method -- main. I tried to use return inside the for loop and outside but it does not work either!
The way you are initially reading the values in seems quite off: you are placing the corresponding weight and cooking into different indices than the actual mushroom and you are using the index i in completely the wrong way. It should probably be
int i = 0;
while ((line = br.readLine()) != null){
String[] temp = line.split(",");
if(temp.length == 3)
mushroom[i] = temp[0];
weight[i] = Integer.parseInt(temp[1]);
cooking[i] = temp[2];
} else {
// some error handling
}
i++;
}
"When I print the values of the arrays inside of the for loop, the values are correct" is wrong - if you inspect temp the values are correct but mushroom, weight and cooking are never being filled correctly with your code.
Further note:
try using a custom class to hold the associated values instead of dealing with 3 arrays which magically have something to do with each other. Then sort an array of instances of that class
You are writing/over-writing only first three elements in each mushroom, cooking and weight.
As
i < temp.length, i <= 3

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 ;)

extract data from csv file and put to 2D Array - refactoring

I need read data from csv file and much more convinience for me is put there to 2D array (to my mind it's easiest way to work with this "schedule" data).
Each file line contained information in following format:
Instructor, Course, Group, Student, Result
as follows example:
Paul Schwartz,Introduction to Computer Architecture,I1,Ben Dunkin,88
Muhamed Olji,Object Oriented Programming,I4,Mike Brown,73
But my code needs some simplify. But I don't know how to make it easier and ask of You.
Code:
private String[][] fileContent(String pathToCSVFile) {
final int ROWS = 100;
final int COLUMNS = 5;
String fileData[][] = new String[ROWS][COLUMNS];
Scanner scanner = new Scanner(pathToCSVFile);
boolean done = false;
int i, j;
while (!done) {
for (i = 0; i >= 0; i++) {
for (j = 0; j >= 0; j++) {
String str[] = scanner.nextLine().split(",");
for (int element = 0; element < str.length; element++) {
fileData[i][element] = str[element];
if (i >= ROWS) {
Arrays.copyOf(fileData, fileData.length * 2);
}
}
}
}
if (!scanner.hasNextLine()) done = true;
}
return fileData;
}
How to refactor this snippet of code for better simplicity?
Does exist any better way for partially filled array (than Arrays.copyOf(fileData, fileData.length * 2))?
Using openCSV, you can get a list containing all the lines and convert it to an array (or just keep the list):
try (CSVReader reader = new CSVReader(new BufferedReader(
new FileReader(pathToCSVFile)));) {
List<String[]> lines = reader.readAll();
return lines.toArray(new String[lines.size()][]);
}
(using Java 7 try-with-resources syntax)
First of all, be careful with those for loops. They are "almost" undefined loops, because they start with i,j=0, and loop while >=0 (always, until they overflow into a negative number).
And why do you need them anyway? I think with you while and the for(element) you are done, right?
Something like that (I didn't tried, is just to explain the concept)
private String[][] fileContent(String pathToCSVFile) {
final int ROWS = 100;
final int COLUMNS = 5;
String fileData[][] = new String[ROWS][COLUMNS];
Scanner scanner = new Scanner(pathToCSVFile);
boolean done = false;
int i=0;
while (!done) {
String str[] = scanner.nextLine().split(",");
for (int element = 0; element < str.length; element++) {
fileData[i][element] = str[element];
if (i >= ROWS) {
Arrays.copyOf(fileData, fileData.length * 2);
}
}
if (!scanner.hasNextLine())
done = true;
else
i++;
}
return fileData;
}
By the way, why don't you use objects, like an ArrayList? It would make your life easier, so you don't have to worry about memory handling. You just add new objects.
Something like an ArrayList <ArrayList <String>>

Categories

Resources