Java sorting text file with Comparable - java

I need a program that reads in data and sorts the file in descending order using quicksort based on the index provided for instance this is the data using comparable
adviser,32/60,125,256,6000,256,16,128,198,199
amdahl,470v/7,29,8000,32000,32,8,32,269,253
amdahl,470v/7a,29,8000,32000,32,8,32,220,253
amdahl,470v/7b,29,8000,32000,32,8,32,172,253
amdahl,470v/7c,29,8000,16000,32,8,16,132,132
And i need to sort by the 5th index(mmax) case 2 and the 6th(cache) case 3 and the ninth index(php) case 4 in descending order & print the first index which is already sorted case 1
The problems with my code are as follows:
It doesn't sort based off the index
It gives me an error at runtime with the code: Arrays.sort(c);
Please help with suggestions
Thanks
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Prog4 {
static Scanner input;
static File filename;
/**
* This function displays the menu for the user to choose an option from
*/
public void menu() {
System.out.println("Option 1: Sort by VENDOR: ");
System.out.println("Option 2: Sort decreasing number by MMAX: ");
System.out.println("Option 3: Sort decreasing number by CACH: ");
System.out.println("Option 4: Sort decreasing number by PRP: ");
System.out.println("Option 5: Quit program");
}
/**
* Constructor to handle the cases in the menu options
* #throws FileNotFoundException
* #throws IOException
*/
public Prog4() throws FileNotFoundException {
//Accepts user input
Scanner in = new Scanner(System.in);
//calls the menu method
menu();
//Initializes the run variable making the program loop until the user terminates the program
Boolean run = true;
//While loop
while (run) {
switch (in.nextInt()) {
case 1:
System.out.println("Option 1 selected");
System.out.println("Sorted by vendor:");
filename = new File("machine.txt");
//Instantiate Scanner s with f variable within parameters
//surround with try and catch to see whether the file was read or not
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Instantiate a new Array of String type
String array [] = new String[10];
//while it has next ..
while (input.hasNext()) {
//Initialize variable
int i = 0;
//store each word read in array and use variable to move across array array[i] = input.next();
//print
System.out.println(array[i]);
//so we increment so we can store in the next array index
i++;
}
case 2:
System.out.println("Press any key to continue");
Scanner input2 = new Scanner(System.in);
String x = input2.nextLine();
if (x.equals(0)) continue;
System.out.println("Option 2 selected") ;
Computer[] c = new Computer[10];
filename = new File("machine.txt");
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Arrays.sort(c);
while (input.hasNextLine()) {
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
}
}
}
/**
* Main method
* #param args
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
//Calls the constructor
new Prog4();
//static Scanner input;
}
public static void quickSort(int arr[], int left, int right) {
if (left < right) {
int q = partition(arr, left, right);
quickSort(arr, left, q);
quickSort(arr, q+1, right);
}
}
private static int partition(int arr[], int left, int right) {
int x = arr[left];
int i = left - 1;
int j = right + 1;
while (true) {
i++;
while (i < right && arr[i] < x)
i++;
j--;
while (j > left && arr[j] > x)
j--;
if (i < j)
swap(arr, i, j);
else
return j;
}
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Comparator class:
import java.util.Comparator;
class Computer implements Comparable<Computer> {
private String vendor;
private int mmax;
private int cach;
private int php;
public Computer(int value) {
this.mmax = value;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public int getMmax() {
return mmax;
}
public void setMmax(int mmax) {
this.mmax = mmax;
}
public int getCach() {
return cach;
}
public void setCach(int cach) {
this.cach = cach;
}
public int getPhp() {
return php;
}
public void setPhp(int php){
this.php = php;
}
#Override
public int compareTo(Computer m) {
if (mmax < m.mmax) {
return -1;
}
if (mmax > m.mmax) {
return 1;
}
// only sort by height if age is equal
if (cach > m.cach) {
return -1;
}
if (cach < m.cach) {
return 1;
}
if (php > m.php) {
return -1;
}
if (php < m.php) {
return 1;
}
return 0;
}
public static Comparator<Computer> ComparemMax = new Comparator<Computer>() {
#Override
public int compare(Computer p1, Computer p2) {
return p2.getMmax() - p1.getMmax();
}
};
}

The biggest problem is that the Computer classes do not get instantiated for each line that gets read.
As you want to have different sort options depending on the user input, you can not let the Computer class determine the compare method, but instead you will need to create a separate Comparator implementation for each sort option. Next, make the file read operation generic and abstract it away in a separate method call from each selected case. Instead of an array of Computers, I would make it a List or a Set, because you don't (want to) know the length up front.

I would like to lay out the steps in detail so that you could figure out each step for yourself. You have got a lot of it right.. but there are gaps.
Create a Computer class. It should have a constructor which takes a single String and splits it using the separator ',' and parses each part to String/int as applicable. (It would be preferable for you to parse and store the whole string.. which means you can have 10 fields in your class)
Create a blank ArrayList to store the Computer objects.
Iterate through the file and readLine
Call the Computer constructor using the String representing each line in the file within the while loop
Add the new Computer object to the computers ArrayList
Write 5 different comparators.
Based on user input, instantiate the correct comparator and pass it to the sort method
Print the sorted array
If you still face a problem, mention the specific point at which you like more clarity..

Related

How to make a Linear Search OOP approach that uses Input Scanner

So I refactored a Linear Search code that only uses the main method. My goal is to convert it into an OOP approach. But I have trouble saving the input set of integers.
// LinearSearchDriver.java
import java.util.Scanner;
public class LinearSearchDriver {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
LinearSearch linearSearch = new LinearSearch();
System.out.println("Enter number of elements");
int numElements = in.nextInt();
linearSearch.setNumberOfElements(numElements);
System.out.println("Enter " + numElements + " integers");
for (int count = 0; count < numElements; count++){
int setIntegers = in.nextInt();
linearSearch.setNumberOfIntegers(setIntegers);
}
System.out.println("Enter value to find");
int search = in.nextInt();
linearSearch.findValue(search);
}
}
//LinearSearch.java
public class LinearSearch {
private int c;
private int n;
private int array[];
public void setNumberOfElements(int n) {
this.n = n;
this.array = new int[n];
}
public void setNumberOfIntegers(int y) {
for (c=0; c < n; c++)
array[c] = y;
}
public void findValue(int search) {
for (c = 0; c < n; c++) {
if (array[c] == search) { /* Searching element is present */
System.out.println(search + " is present at location " + (c + 1) + ".");
break;
}
}
if (c == n) { /* Searching element is absent */
System.out.println(search + " is not present in array.");
}
}
}
Example output:
But when I input number 1, this is the output:
The program only reads number 2 output which I think, the last number is only the one that is saving to an array.
for (c = 0; c < n; c++) {
array[c] = y;
}
is where things go wrong. You're setting the last value passed to that function for every index in the Array.
You can adress this in several ways:
Pass an Array to the function instead of a single argument.
You can determine the current number of elements in your Array and then append the newest value "manually". See this post.
Or you could simply use a dynamic structure, such as a List and append the element to that.
Here is a rough outline for the 3rd Option:
public class LinearSearch {
private List<Integer> intList;
public LinearSearch() {
}
public void setNumberOfElements(int n) {
intList = new ArrayList<>(n); //Set the capacity here like before.
}
public void setNumberOfIntegers(int y) {
//If you want your List to always only contain the initially allowed number of elements, you could implement
// this logic here, by adding the new value and removing the "oldest" one.
intList.add(y);
}
public void findValue(int search) {
if (!intList.contains(search)) { //You can put this up here and potentially skip the looping.
System.out.println(search + " is not present in array.");
return;
}
for (int n : intList) {
if (n == search) {
System.out.println(search + " is present at location " + intList.indexOf(search) + ".");
return; //Use return to exit the method, break only exits the loop in your example, and you could print both lines.
}
}
}
}

Stack implementation in java using default integer array with auto resize

So I am trying to create a more time efficient stack implementation in java but I don't know how to make it work faster. Here is my code:
import java.util.Scanner;
public class A {
public static void main(String[] args) {
int[] n = new int[0];
Scanner scan = new Scanner(System.in);
loop: while(true){
String stringy = scan.next();
switch(stringy){
case "push":
int x = scan.nextInt();
n = push(x, n);
System.out.println("ok");
break;
case "pop":
n = pop(n);
break;
case "exit":
System.out.println("bye");
break loop;
case "size":
System.out.println(n.length);
break;
case "back":
back(n);
break;
case "clear":
n = clear();
System.out.println("ok");
break;
}
}
}
static int[] push(int n, int[] x) {
int[] z = new int[x.length + 1];
for (int i = 0; i < x.length; i++){
z[i] = x[i];
}
z[x.length] = n;
return z;
}
static int[] pop(int[] x){
int z[] = new int[x.length-1];
for(int i = 0; i < z.length; i++){
z[i] = x[i];
}
System.out.println(x[x.length-1]);
return z;
}
static void back(int[] x){
System.out.println(x[x.length-1]);
}
static int[] clear(){
int x[] = new int[0];
return x;
}
}
Brief explanation:
Program takes values from scanner. And depending on a word that was entered, program proceeds with the corresponding instructions like push, pop, back... And it prints out the expected values to console with ok. Everything so far works properly as expected except the performance.
As you can see, in methods push and pop, my program creates new arrays and copies the values of the taken array which is x and adds 1 index with a pushed value or removes the popped value. This approach seems rather slow and inefficient. I couldn't find a more efficient way of doing that without picking arraylist or other classes from java library. But I have to use default integer arrays. And are there any other issues worsening the perfomance of the program?
How can I make my program work faster?
You can create member variables outside your method to keep track of the array and what is the size of it (similar to how array lists are implemented), no need to recopy the whole array everytime you need to pop/push.
You will need 2 variables, the array itself and the size (which will expand/shrink based on what you do)
You're better off creating a new class, I am gonna name it CustomStack
public class CustomStack
{
private int[] elements = new int[10]; // instantiated with a size of 10
private int size; // To track how many ints we currently have
....
}
You can now access the array and the size within the methods.
So first you need the push method, but wait there is a trick here, what if I already reached the max size of the array? (i.e: 10 numbers are already inside the array), well you need to cater for this, a known way to tackle this is create a new array with double the size of the current array and then copy all the values to the new array.
private void validateArraySize()
{
if (size == elements.length)
{
int[] temp = new int[elements.length * 2]; //double the size
System.arraycopy(elements, 0, temp, 0, elements.length); // copy the array
elements = temp; //set our member variable array to the new array
}
}
And the push method:
public void push(int n)
{
validateArraySize(); // The previos method to check if we can safely insert the value
elements[size] = n;
size++;
}
Regarding the pop method, it is very straight forward, you just need to check if there are any integers inside the array:
public int pop()
{
int valueRemoved = 0;
if (size == 0)
System.out.println("No elements found to pop");
else
{
valueRemoved = elements[size - 1]; //Get the last value
elements[size - 1] = 0; // remove the last value
size--;
}
return valueRemoved; // return removed value
}
The whole class will look like this:
public class CustomStack
{
private int[] elements = new int[10];
private int size;
public void push(int n)
{
validateArraySize();
elements[size] = n;
size++;
}
private void validateArraySize()
{
if (size == elements.length)
{
int[] temp = new int[elements.length * 2];
System.arraycopy(elements, 0, temp, 0, elements.length);
elements = temp;
}
}
public int pop()
{
int valueRemoved = 0;
if (size == 0)
System.out.println("No elements found to pop");
else
{
valueRemoved = elements[size - 1];
elements[size - 1] = 0;
size--;
}
return valueRemoved;
}
public int getSize()
{
return size;
}
public void back()
{
if (size == 0)
System.out.println("No elements found");
else
System.out.println(elements[size - 1]);
}
public void clear()
{
elements = new int[10];
}
}
Your main method will become:
public static void main(String[] args) {
CustomStack customStack = new CustomStack();
Scanner scan = new Scanner(System.in);
loop: while(true){
String stringy = scan.next();
switch(stringy){
case "push":
int x = scan.nextInt();
customStack.push(x);
System.out.println("ok");
break;
case "pop":
int val = customStack.pop();
System.out.println(val + " is popped");
break;
case "exit":
System.out.println("bye");
break loop;
case "size":
System.out.println(customStack.getSize());
break;
case "back":
customStack.back();
break;
case "clear":
customStack.clear();
System.out.println("ok");
break;
}
}

Java- function seems to mess up the console, nothing will be printed out after calling the function

I was asked to program a method that receives a scanner, and returns a sorted array of words which contain only letters, with no repetitions (and no bigger in length than 3000). Then, I was asked to program a method that checks whether a certain given string is contained in a given vocabulary. I used a simple binary search method.
This is what I've done:
public static String[] scanVocabulary(Scanner scanner){
String[] array= new String[3000];
int i=0;
String word;
while (scanner.hasNext() && i<3000) {
word=scanner.next();
if (word.matches("[a-zA-Z]+")){
array[i]=word.toLowerCase();
i++;
}
}int size=0;
while (size<3000 && array[size]!=null ) {
size++;
}
String[] words=Arrays.copyOf(array, size);
if (words.length==0 || words.length==1) {
return words;
}
else {
Arrays.sort(words);
int end= removeDuplicatesSortedArr(words);
return Arrays.copyOf(words, end);
}
}
private static int removeDuplicatesSortedArr(String[] array) { //must be a sorted array. returns size of the new array
int n= array.length;
int j=0;
for (int i=0; i<n-1; i++) {
if (!array[i].equals(array[i+1])) {
array[j++]=array[i];
}
}
array[j++]=array[n-1];
return j;
}
public static boolean isInVocabulary(String[] vocabulary, String word){
//binary search
int n=vocabulary.length;
int left= 0;
int right=n-1;
while (left<=right) {
int mid=(left+right)/2;
if (vocabulary[mid].equals(word)){
return true;
}
else if (vocabulary[mid].compareTo(word)>0) {
right=mid-1;
}else {
right=mid+1;
}
}
return false;
}
while trying the following code:
public static void main(String[] args) {
String vocabularyText = "I look at the floor and I see it needs sweeping while my guitar gently weeps";
Scanner vocabularyScanner = new Scanner(vocabularyText);
String[] vocabulary = scanVocabulary(vocabularyScanner);
System.out.println(Arrays.toString(vocabulary));
boolean t=isInVocabulary(vocabulary, "while");
System.out.println(t);
System.out.println("123");
}
I get nothing but-
[and, at, floor, gently, guitar, i, it, look, my, needs, see, sweeping, the, weeps, while]
nothing else is printed out nor returned. Both functions seem to be working fine separately, so I don't get what I'm doing wrong.
I would be very happy to hear your thoughts, thanks in advance :)
This has nothing to do with the console. Your isInVocabulary method is entering an infinite loop in this block:
if (!isInVocabulary(vocabulary, "while")) {
System.out.println("Error");
}
If you were to debug through isInVocabulary, you would see that after a few iterations of the while loop,
left = 0;
right = 2;
mid = 1;
if (vocabulary[mid].equals(word)){
// it doesn't
} else if (vocabulary[mid].compareTo("while") > 0) {
// it doesn't
} else {
right = mid + 1;
// this is the same as saying right = 1 + 1, i.e. 2
}
So you'll loop forever.

String Array class in JAVA

I need help with this code
Problem
Write a Java class having a String array, with global visibility.
Add a method that adds a given sting to the string array.
Add a method that searches for a given string in the string array.
Add a method that searches for a given character in the string array. The method should count and returns the occurrence of the given character.
Write an appropriate main method to test these class methods.
and this is the code. First, I created a class for method I create scound class for TestString array
my question is i have error in scound class ,and i try to fix it but it dose not work
this the first class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package ooplab3;
public class StringArray {
String[] sTA = null;
int index = 0; //last added sring position in the string array
public StringArray() {
}
public String[] getsTA() {
return sTA;
}
public String getsTAindex(int i) {
return sTA[i];
}
public int getcounter() {
return index;
}
public void setCounter(int counter) {
this.index = counter;
}
public void addStrinToArray(String st) {
if (this.index < sTA.length) {
sTA[this.index] = st;
this.index++;
}
}
public int searchStringInArray(String sT) {
int n = 0;
for (int i = 0; i < this.index; i++) {
for (int j = 0; j < 10; j++) {
int indexOf = sTA[i].indexOf(sT);
n += searchStringInArray(sTA[i]);
return n;
}
}
return n;
}
public int searchcharInArray(String sT) {
int n = 0;
int Startindex = 0;
do {
n += sT.indexOf(Startindex);
} while (n > Startindex);
return n;
}
public boolean containsChar(String s, char search) {
if (s.length() == 0) {
return false;
} else {
return s.charAt(0) == search || containsChar(s.substring(1), search);
}
}
public void containsChar(Object object, String search) {
}
}
Sound class :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package ooplab3;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class testStringarray {
public static void main(String[] args) throws FileNotFoundException {
String[] testArray = new String[30];
Scanner infile = new Scanner(new FileReader("input_txt"));
// System.out.println("contents of testArray");
int i = 0;
while (infile.hasNext()) {
String j = infile.next();
addString(j, i);
System.out.println(testArray[i] + "\n");
i++;
}
}
}
the input file contain: hello this is my java program
As near as I can tell, you have a class named StringArray, and a second class which is intended to test the capabilities of StringArray. But that second class doesn't actually use StringArray at all; instead, it creates its own array, and calls a method addString() which has a similar, but not identical, name as a method in StringArray.
One significant problem with StringArray is that it never creates an actual array -- its array member variable remains null. You need a "new" expression to create the actual array. Then your test class should be doing something like
StringArray sa = new StringArray();
sa.addStringToArray("Hello, world");
String[] array = sa.getsTA();
for (String s: array)
System.out.println(s);
A number of problems exist.
Here's one of them:
In your StringArray.addStrinToArray() method, you attempt to assign a string to an element of a null array:
String[] sTA = null;
sTA[index] = st; //this will throw NullPointerException
You need to initialise the array:
String[] sTA = new String[initialSize];
Where initialSize is an integer containing the initial size of the array.

how to insert into arraylist using a scanner?

I'm having some problems trying to figure out how to insert an integer using a scanner into an ArrayList. I'm not that great (actually not even really good) at java but I'm just trying to figure some things out and any help would be great.
package mySort;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class MergeInsert {
private int limit = 100;
//private int size = 0;
private ArrayList<Integer> ArrayToSort;
public MergeInsert(int x) {
ArrayToSort = new ArrayList<Integer>(x);
}
public MergeInsert(Scanner integerScan){
int j = 0;
while(integerScan.hasNextInt()){
this.insert(integerScan.hasNextInt());
if (j % 10000 == 0){
long time = System.nanoTime();
System.out.println(j + "," + time);
}
}
}
public void insert(int x){
for(int i=0; i<ArrayToSort.size(); i++){
ArrayToSort(size++) = x;
}
}
// public MergeInsert(int v){
// int val = v;
// }
// public void insertFile(){
// try {
// Scanner integerScan = new Scanner(new FileInputStream(""));
// while(integerScan.hasNextInt()){
// new MergeInsert(integerScan.nextInt());
// }
// }
// catch (FileNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
public void sort(){
}
public void mergeSort(ArrayList<Integer> in, int low,int high){
int n = in.size();
int mid = (high+low)/2;
if (n<2){ //already sorted
return;
}
if ((high - low) < limit){
insertionSort(in);
}
ArrayList<Integer> in1 = new ArrayList<Integer>(); //helper
ArrayList<Integer> in2 = new ArrayList<Integer>(); //helper
int i=0;
while (i < n/2){ //moves the first half to the helper
in1.add(in.remove(0));
i++;
}
while (!in.isEmpty()) //moves the second half to the helper
in2.add(in.remove(0));
mergeSort(in1, low, mid); //breaks it down some more like mergesort should
mergeSort(in2, mid+1, high); //does it again
merge(in1,in2,in); //trying to build it up again
}
public void merge(ArrayList<Integer> in, ArrayList<Integer> in1, ArrayList<Integer> in2){
while (!in1.isEmpty() || !in2.isEmpty()) //as long as both helpers still have elements
if ((in1.get(0).compareTo(in2.get(0)) <= 0)) //comparison to rebuild
in.add(in1.remove(0)); //building it back up
else
in.add(in2.remove(0)); //still building
while(!in1.isEmpty()) //as long as the first helper isn't empty keep building
in.add(in1.remove(0));
while(!in2.isEmpty()) //as long as the second helper isn't empty keep building
in.add(in2.remove(0));
}
public ArrayList<Integer> insertionSort(ArrayList<Integer> in){
int index = 1;
while (index<in.size()){
insertSorted((int)(in.get(index)),in,index);
index = index +1;
}
return in;
}
public ArrayList<Integer> insertSorted(Integer s, ArrayList<Integer> in, int index){
int loc = index-1;
while((loc>=0) || s.compareTo(in.get(loc)) <= 0){
in.set(loc + 1, in.get(loc));
loc = loc -1;
}
in.set(loc+1, s);
return in;
}
/**
* #param args
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
Scanner integerScan = new Scanner(new FileInputStream("src/myRandomNumbers.txt"));
MergeInsert myObject = new MergeInsert(integerScan);
myObject.sort();
}
}
It's not completely finished but the idea behind all of this is to try and improve on MergeSort. Basically once the elements get broken down to a certain point cut to InsertionSort because it is usually better on really small (really small being relative) sets of data.
public void insert(int x){
ArrayToSort.add(x); // add it to the end
}
The reason is... even if you go
ArrayToSort = new ArrayList<Integer>(100000);
It still has a size of 0. It just has a CAPACITY of 100000.
Use add to insert objects into the list.
Also, the way your code is structured now, you will get a NullPointerException when you attempt to invoke add because the constructor you invoke never initializes the list.
Given the quality of your code, I highly recommend reading Learning the Java Language.

Categories