Currently I have iterated through the file but I am now trying to sort the output using quickSort. I have created a working quickSort/partition class that works with a local array but I am wondering how to use it with the file in the other class. I want to do things such as sort by population, sort by city alphabetically, and sort by latitude.
Here is some of the file that I'm working with:
ad,Andorra La Vella,07,20430,42.5,1.5166667
ad,Canillo,02,3292,42.5666667,1.6
ad,Encamp,03,11224,42.5333333,1.5833333
ad,La Massana,04,7211,42.55,1.5166667
ad,Les Escaldes,08,15854,42.5,1.5333333
ad,Ordino,05,2553,42.55,1.5333333
ad,Sant Julia De Loria,06,8020,42.4666667,1.5
ae,Abu Dhabi,01,603687,24.4666667,54.3666667
ae,Dubai,03,1137376,25.2522222,55.28
My code:
public class City {
String countrycode;
String city;
String region;
int population;
double latitude;
double longitude;
public City(String countrycode, String city, String region, int population, double latitude, double longitude) {
this.countrycode = countrycode;
this.city = city;
this.region = region;
this.population = population;
this.latitude = latitude;
this.longitude = longitude;
}
public String toString() {
return this.city + "," + this.population + "," + this.latitude + "," + this.longitude;
}
}
public class Reader {
In input = new In("file:world_cities.txt");
public static City cityInfo;
public static void main(String[] args) {
// open file
In input = new In("world_cities.txt");
try {
// write output to file
FileWriter fw = new FileWriter("cities_out.txt");
PrintWriter pw = new PrintWriter(fw);
int line = 0;
// iterate through all lines in the file
while (line < 47913) {
// read line
String cityLine = input.readLine();
// create array list
ArrayList<String> cityList = new ArrayList<String>(Arrays.asList(cityLine.split(",")));
// increase counter
line += 1;
// create variables for the object
String countrycode = cityList.get(0);
String city = cityList.get(1);
String region = cityList.get(2);
int population = Integer.parseInt(cityList.get(3));
double latitude = Double.parseDouble(cityList.get(4));
double longitude = Double.parseDouble(cityList.get(5));
// create instance
cityInfo = new City(countrycode, city, region, population, latitude, longitude);
System.out.println(cityInfo);
// print output to file
pw.println(cityInfo);
}
// close the file
pw.close();
}
// what is printed when there is an error when saving to file
catch (Exception e) {
System.out.println("ERROR!");
}
// close the file
input.close();
}
}
public class QuickSort3 {
public static void main(String[]args) {
int[] array = {4, 77, 98, 30, 20, 50, 77, 22, 49, 2}; // local array that works with the quicksort
quickSort(array,0,array.length - 1);
System.out.println(Arrays.toString(array));
}
public static void quickSort(int[] a, int p, int r)
{
if(p<r)
{
int q = Partition(a, p,r);
quickSort(a, p, q-1);
quickSort(a, q+1, r);
}
}
private static int Partition(int[] a, int p, int r)
{
int x = a[r];
int i = p-1;
int temp=0;
for(int j=p; j<r; j++)
{
if(a[j]<=x)
{
i++;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
temp = a[i+1];
a[i+1] = a[r];
a[r] = temp;
return (i+1);
}
}
So if I understand correctly, you have a quicksort method that can sort ints and now your requirement is to sort City objects. I think you can find much inspiration on the Internet. First you need to specify a sort order. Since you want different sort orders (by population, alphabetically, etc.), write a Comparator<City> that does that. Search your textbook and/or the net for guidance and examples. Your comparator will need your City class to have get methods, so add some of those too. For example, a comparator to sort by population (greatest first) might be
Comparator<City> populationComparator = Comparator.comparingInt(City::getPopulation).reversed();
This will require that City has a getPopulation method.
Next you need to rewrite your quicksort method to accept an array of City objects and a comparator, and the same for Partition(). Inside the Partition method, where it says a[j]<=x, replace by cityComparator.compare(a[j], x) <= 0 (if your comparator parameter is called cityComparator). You need to change the type of x and other variables holding elements to City.
Related
I need to show a list sorted by countries with the minimum days to reach 50,000 cases in the .csv file. The countries are displaying by each day in each line, so I have to read each line to figure it out how many days. In the end it should print the number of countries that achieved 50,000 cases in the minimum days, in ascending order.
Spain Beginning
Spain Ending
So in this case it should show 84 days to reach 50000 cases.
In this code if it passes 50000 cases, it won't enter the while loop, so I guess I'm doing something wrong. And I'm not sure if in this one I'm giving the country the minimum number or if I'm just giving the line of the day.
// Constructor for class Country
public Country(String isoCode, String continent, String location, LocalDate date, int totalCases, int newCases, int totalDeaths, int newDeaths, int newTests, int totalTests, int population,
double older65, double cardiDeathRate, double diabetesPrevalence, double femaleSmokers, double maleSmokers, double numBeds, double lifeExpectancy) {
this.isoCode = isoCode;
this.continent = continent;
this.location = location;
this.date = date;
this.totalCases = totalCases;
this.newCases = newCases;
this.totalDeaths = totalDeaths;
this.newDeaths = newDeaths;
this.newTests = newTests;
this.totalTests = totalTests;
this.population = population;
this.older65 = older65;
this.cardiDeathRate = cardiDeathRate;
this.diabetesPrevalence = diabetesPrevalence;
this.femaleSmokers = femaleSmokers;
this.maleSmokers = maleSmokers;
this.numBeds = numBeds;
this.lifeExpectancy = lifeExpectancy;
}
This is the loader code:
public boolean load(String filename) {
p = new ArrayList<>();
try{
Files.lines(Paths.get(filename)).skip(1).forEach(p -> loadLine(p));
} catch (Exception e) {
return false;
}
return true;
}
private void loadLine(String line) {
String [] data = line.split(",");
p.add(new Country(data[0],
data[1],
data[2],
LocalDate.parse(data[3),
Integer.parseInt(data[4]),
Integer.parseInt(data[5]),
Integer.parseInt(data[6]),
Integer.parseInt(data[7]),
Integer.parseInt(data[8]),
Integer.parseInt(data[9]),
Integer.parseInt(data[10]),
Integer.parseInt(data[11]),
Double.parseDouble(data[12]),
Double.parseDouble(data[13]),
Double.parseDouble(data[14]),
Double.parseDouble(data[15]),
Double.parseDouble(data[16]),
Double.parseDouble(data[17])));
}
And this is the sort one:
public List<Country> sortedByMinDays(Country p1, Country p2) {
int min=0;
List<Country> lp = new ArrayList<>(p);
while(p1.getIsoCode()==p2.getIsoCode() && p2.getTotalCases()<=50000){
min=min + 1;
p2.setMinDays(min);
}
for (int n=0; n<lp.size(); n++){
if (p2.getMinDays()<p1.getMinDays()){
int aux = p1.getMinDays();
p2.setMinDays(p1.getMinDays());
p1.setMinDays(aux);
}
}
return sortedByMinDays(p1, p2);
}
The goal of the application is as following: I want to create objects (airplanes) of the class "Flugzeug" (German word for airplane). I want to create an array which refers to the different attributes of the objects.
The problem is (as far as I know) that one single array can only refer to variables of the exact same type.
How can I change my program that it works? Is it inevitable to create an array for each attribute (e.g. for each different type of variable)?
The code:
public class Fluggesellschaft {
public static void main(String[] args) {
Flugzeug [] airline = new Flugzeug [4];
for (int i = 0; i < 4; i=i+1){
airline[i] = new Flugzeug ();
airline[0].type = "A320";
airline[0].idNumber = "1";
airline[0].seats = "165";
airline[0].velocity = "890";
airline[0].range = "12600";
airline[1].type = "Boeing 747";
airline[1].idNumber = "2";
airline[1].seats = "416";
airline[1].velocity = "907";
airline[1].range = "12700";
airline[2].type = "Avro RJ 85";
airline[2].idNumber = "3";
airline[2].seats = "93";
airline[2].velocity = "760";
airline[2].range = "2200";
airline[3].type = "Airbus 380";
airline[3].idNumber = "4";
airline[3].seats = "516";
airline[3].velocity = "907";
airline[3].range = "12000";
}
for (int i=0; i < 4; i=i+1) {
airline[i].printInfo();
double time = airline[i].getTime(6320); //distance from Zurich to New York
System.out.println("duration: " + time + " h");
int capacity = airline[i].getCapacity(365);
System.out.println("capacity: " + capacity + " passengers / year");
}
}
}
public class Flugzeug {
String type;
int idNumber;
int seats;
double velocity;
double range;
double distance;
int days;
public void printInfo() {
System.out.println("type: " + this.type);
System.out.println("ID-number: " +this.idNumber);
System.out.println("seats: " + this.seats);
System.out.println("velocity: " + this.velocity);
System.out.println("range: " + this.range);
}
public double getTime (double dist) {
double result = 0;
result = dist / velocity;
double time = result;
return time;
}
public int getCapacity(int days) {
int capacity = seats * days;
return capacity;
}
}
The core of your problem is this:
one single array can only refer to variables of the exact same type.
That is correct (or mostly correct, all elements of an array must have a common base type, but that's not a relevant distinction right now).
But the type inside of your array is Flugzeug, not String!
So each element of the array must be a Flugzeug. That doesn't mean that the fields of that class have to all share a single type (and indeed, as you posted, they don't).
Look at this line:
airline[0].idNumber = "1";
this is almost correct, but since idNumber is an int you must assign it an int value (such as 1) instead:
airline[0].idNumber = 1;
The second (mostly unrelated) problem is that you try to access all 4 Flugzeug instances inside of the loop that creates them. That means when you try to access the second instance after just having created the first one (only!) it will crash:
Replace this:
for (int i = 0; i < 4; i=i+1) {
airline[i] = new Flugzeug ();
airline[0].type = "A320";
airline[1].type = "Boeing 747";
airline[2].type = "Avro RJ 85";
airline[3].type = "Airbus 380";
}
with this:
for (int i = 0; i < 4; i=i+1) {
airline[i] = new Flugzeug ();
}
airline[0].type = "A320";
airline[1].type = "Boeing 747";
airline[2].type = "Avro RJ 85";
airline[3].type = "Airbus 380";
if some type like int,double,long... was used " " ,They almost all become String type
I found two problems with your code.
First, you have declared idNumber as int int idNumber; but while assigning the value you are inserting a string value airline[0].idNumber = "1";.
NOTE: "1" is a string not integer.
The solution here would be airline[0].idNumber = 1;
You need to assign same type of values to every variable as they are declared.
And second, you are creating multiple objects in the loop airline[i] = new Flugzeug (); but overwriting the same single object (stored in the 0th position of the array) everytime. I would suggest to do,
airline[i].type = "A320";
airline[i].idNumber = 1; // Again this should not be "1"
airline[i].seats = 165; // And this should not be "165"
airline[i].velocity = 890; // Same is applicable here
airline[i].range = 12600; // and here
The problem is the variables are not only String type but ints and doubles as well. You need to assign the correct type. In addition you shouldn't access class variables like that, make them private create a constructor with getters and setters.
public class Flugzeug {
private String type;
private int idNumber;
private int seats;
private double velocity;
private double range;
private double distance;
private int days;
public Flugzeug(String type, int idNumber, int seats, double velocity, double range) {
this.type = type;
this.idNumber = idNumber;
this.seats = seats;
this.velocity = velocity;
this.range = range;
}
public double getDistance() {
return this.distance;
}
public void setDistance(double distance) {
this.distance = distance;
}
}
public class Fluggesellschaft {
public static void main(String[] args) {
Flugzeug[] airline = new Flugzeug [4];
airline[0] = new Flugzeug("A320", 1, 165, 890, 12600);
airline[1] = new Flugzeug(...);
}
}
i have a situation where i have to read xml files where i get three elements like this
2019-03-19,null,null
2016-11-30,null,null
2016-10-14,null,null
2016-09-30,null,null
2016-09-30,1,YEARS
2016-09-30,3,MONTHS
2016-09-30,4,MONTHS
I have to store all three items on some data structure and apply my logic like below
I have to find the max of last item and then for that i have to find the max of second item then for that i have to find the max of first element of more than one is present .
Please suggest me some idea
Create a single object like below that can hold all three data elements and is also capable of handling a "null" value for the quantity and term length values. You may want to have the constructor convert the String date (2019-03-19) into a real date object or you could handle that before object creation. Then add these objects to a data structure (i.e. list, etc) that you can use to manage and organize them.
public class ListElement {
public Date date;
public Integer qty;
public String termLength;
public ListElement(Date d, Integer q, String t) {
this.date = d;
this.qty = q;
this.termLength = t
}
// getter methods
public Date getDate() {
return this.date;
}
public Integer getQty() {
return this.qty;
}
public String getTermLength() {
return this.termLength;
}
public toString() {
return System.out.println(this.date + "::" +
this.qty + "::" +
this.termLength)
}
}
You can create an enum if you have some predefined terms:
enum Term {
AGES, YEARS, MONTHS, WEEKS, DAYS, HOURS, MINUTES, SECONDS;
}
And use it in your class with other two types as:
public class MyObjects {
private Date date;
private Integer quantity;
private Term term;
public MyObjects(Date date, Integer quantity, Term term) {
this.date = date;
this.quantity = quantity;
this.term = term;
}
// getters, setters
}
Then define the constructor that accepts these 3 arguments and use it while processing XML file.
Two different ways to store the data. One is 2D array and the other is arraylist. All the data is type String. You would have to Parse the Integers using Integer.parseInt() to get int value. You will also have to catch for null values. This assumes that your xml data have newline characters at the end of each line.
public static void main(String[] args) {
// TODO code application logic here
//Assuming there are \n char at end of line
String xml = "2019-03-19,null,null\n" +
"2016-11-30,null,null\n" +
"2016-10-14,null,null\n" +
"2016-09-30,null,null\n" +
"2016-09-30,1,YEARS\n" +
"2016-09-30,3,MONTHS\n" +
"2016-09-30,4,MONTHS";
System.out.println("2D Array Output:");
String[][] twoDArrayExample = twoDArrayVersion(xml);
//print 2D array
for(int i = 0; i < twoDArrayExample.length; i++)
{
for(int z = 0; z < twoDArrayExample[i].length; z++)
{
System.out.print(twoDArrayExample[i][z] + " - ");
}
System.out.println();
}
System.out.println("\n\nArray List Output:");
ArrayList<ArrayList<String>> arrayListExample = arrayListVersion(xml);
//print arraylist
for(ArrayList<String> entry : arrayListExample)
{
for(String item : entry)
{
System.out.print(item + " + ");
}
System.out.println();
}
}//end of main
static String[][] twoDArrayVersion(String xml)
{
String[][] dataHolder;
String[] tempDataHolder = xml.split("\n");
dataHolder = new String[tempDataHolder.length][3];
for(int i = 0; i < tempDataHolder.length; i++)
{
String[] tempDataHolder2 = tempDataHolder[i].split(",");
dataHolder[i][0] = tempDataHolder2[0];
dataHolder[i][1] = tempDataHolder2[1];
dataHolder[i][2] = tempDataHolder2[2];
}
return dataHolder;
}
static ArrayList<ArrayList<String>> arrayListVersion(String xml)
{
ArrayList<ArrayList<String>> dataHolder = new ArrayList();
String[] tempDataHolder = xml.split("\n");
for(int i = 0; i < tempDataHolder.length; i++)
{
ArrayList<String> tempArrayList = new ArrayList();
String[] tempDataHolder2 = tempDataHolder[i].split(",");
tempArrayList.add(tempDataHolder2[0]);
tempArrayList.add(tempDataHolder2[1]);
tempArrayList.add(tempDataHolder2[2]);
dataHolder.add(tempArrayList);
}
return dataHolder;
}
Background:
Trying to build a neural network which will have 13 input nodes, 8 hidden nodes, and 1 output node
Data That Is Being Read
Code That I Have So Far
NeuralNetwork.java
public class NeuralNetwork {
//Setup an array of Node to store values from a .data file
Node[] dataSet;
//Declare a double[][] array, and randomize the weights of the double array in constructor
protected double[] weights;
//We set a double field named eta equal to 0.05.
protected double eta = 0.05;
private final String comma = ",";
private final String qMarks = "?";
private List<InputNode> input;
//We initialize a constructor which only takes a parameter int n.
public NeuralNetwork(File f){
List<InputNode> network = new ArrayList<InputNode>();
this.input = network;
try {
#SuppressWarnings("resource")
Scanner inFile = new Scanner(f);
//While there is another line in inFile.
while (inFile.hasNextLine()){
//Store that line into String line
String line = inFile.nextLine();
//Parition values separated by a comma
String[] columns = line.split(comma);
/*System.out.println(Arrays.toString(columns)); //Test code to see length of each column
* code works and prints out row
* */
//create a double array of size columns
InputNode[] rows = new InputNode[columns.length];
for (int i = 0; i < columns.length; i++){
//For each row...
if (!columns[i].equals(qMarks)){
//If the values in each row do not equal "?"
//Set rows[i] to the values in column[i]
rows[i] = new InputNode(Double.parseDouble(columns[i]));
}
else {
rows[i] = new InputNode(0);
}
}
input.add(rows);
}
System.out.println(input.size());
//System.out.println(input.size()); //Test code to see how many rows in .data file
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Create Hidden Layer Network
for (int i = 0; i < input.size(); i++){
}
}
Node.java
public class Node {
private double number;
public Node(double value){
this.number = value;
}
public double output(){
return number;
}
}
InputNode.java
public class InputNode extends Node {
//Declare a double variable to represent the holding value for InputNode
private double value;
public InputNode(double value) {
super(value);
// TODO Auto-generated constructor stub
}
//Create method to initialize input nodes
public void set(double tempValue){
this.value = tempValue;
}
public double get(Node s){
return s.output();
}
//Override method from Node class
//This method will grab the sum of all input node values.
public double output(){
return value;
}
}
HiddenLayer.java
public class HiddenLayer extends Node {
protected List<InputNode> nodes = new ArrayList<InputNode>();
public HiddenLayer(double value) {
super(value);
// TODO Auto-generated constructor stub
}
//Some activation functions which can be called upon.
class ActivationFunction {
//Sigmoid activation function
public double sigmoid(double x) {
return (1.0 / (1 + Math.pow(Math.E, -x)));
}
public double deriveSigmoid(double d){
return d * (1.0 - d);
}
// Hyperbolic Tan Activation Function
public double hyperTanFunction(double x) {
return (Math.pow(Math.E, x) - Math.pow(Math.E, -x)) / (Math.pow(Math.E, x) + Math.pow(Math.E, -x));
}
public double deriveHyperTanFunction(double d){
return (1.0 - Math.pow(hyperTanFunction(d), 2.0));
}
}
//Output method for the HiddenNode class which will sum up all the input nodes for
//a specific hidden node
public double output(){
/*Here we will be implementing the following function
* Sigma(x[i] * weights[i]) = net
* Pass net into the hyberbolic tangent function to get an output between -1 to 1
* We will pass net into the activation function in the train method of Neural Network
*/
//Setup a double sum variable to represent net
double net = 0;
//Setup for loop to loop over input nodes array for a hidden node
for (int i = 0; i < nodes.size(); i++){
net += nodes.get(i).output();
}
return net;
}
}
Desired Outcome
I would like my NeuralNetwork(File f) constructor partition each number for each row of the data into separate input nodes
For example:
For row 1: [28, 1, 2, 130, 132, 0, 2, 185, 0, 0, ?, ?, ?, 0]
You get InputNodes of:
InputNode[1] = 28
InputNode[2] = 1
InputNode[3] = 2
.....
This is only for each row only, the method should loop over each row. Also I have been having a hard time trying to figure out how to setup the HiddenLayer objects.
For each HiddenNode the network should sum up all the input node values (in each row) and multiply it times the weight of the hidden node, this is then fed into a sigmoid function
This code will loop through the input list and then the array and print the output.
for(int i=0;i < input.size(); i++) {
System.out.println("For Row " + i + " of file:");
InputNode[] = input.get(i);
for (int j=0;j < InputNode.length; j++ ) {
System.out.println(" InputNode[ " + j + "] = " + InputNode[j].output());
}
}
You can use the same logic in HiddenLayer and do processing.
What I have written so far works from my current knowledge of basic arrays, but I just don't understand how to use an arraylist, or how to read from a file. What I have written so far works. Any links or advice to help fix my code to read from a file and use an arraylist would be greatly appreciated. Thank you.
public class TestPackages
{
public static void main (String[] args)
{
Packages testPackages = new Packages();
testPackages.addPacket(1001, 7.37, "CA");
testPackages.addPacket(1002, 5.17, "CT");
testPackages.addPacket(1003, 11.35, "NY");
testPackages.addPacket(1004, 20.17, "MA" );
testPackages.addPacket(1005, 9.99, "FL");
testPackages.addPacket(1006, 14.91, "VT");
testPackages.addPacket(1007, 4.97, "TX");
System.out.println(testPackages);
}
}
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
import java.util.Scanner;
import java.io.*;
import java.util.ArrayList;
public class Packages
{
private Packet[] shipment;
private int count;
private double totalWeight;
public Packages()
{
shipment = new Packet[100];
count = 0;
totalWeight = 0.0;
}
public void addPacket (int idNumber, double weight, String state)
{
if(count == shipment.length)
increaseSize();
shipment[count] = new Packet (idNumber, weight, state);
totalWeight += weight;
count++;
}
public String toString()
{
String report;
report = "All Packets\n";
for(int num = 0; num < count; num++)
report += shipment[num].toString() + "\n";
report += "Total Weight:\t" +totalWeight+" pounds";
return report;
}
private void increaseSize()
{
Packet[] temp = new Packet[shipment.length * 2];
for (int num = 0; num < shipment.length; num++)
temp[num] = shipment[num];
shipment = temp;
}
}
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
public class Packet
{
private int idNumber;
private double weight;
private String state;
public Packet(int idNumber, double weight, String state)
{
this.idNumber = idNumber;
this.weight = weight;
this.state = state;
}
public boolean isHeavy(double weight)
{
return (weight > 10);
}
public boolean isLight(double weight)
{
return (weight < 7);
}
public String toString()
{
String description = "ID number: " + idNumber + "\tWegiht: " + weight + "\tState: "
+ state;
return description;
}
}
Try this link to learn how to read from file with JAVA
How to read a large text file line by line using Java?
You can try the following code to learn how to use Arraylist (There are many more tutorials in the web)
Packet p1=new Packet (1001, 7.37, "CA");
Packet p2=new Packet (1002, 17.5, "SF");
Packet p3=new Packet (1003, 13.8, "DF");
Packet p4=new Packet (1004, 14.4, "XC");
ArrayList<Packet> arr= new ArrayList<Packet>();
arr.add(p1);
arr.add(p2);
arr.add(p3);
arr.add(1,p4);
System.out.println("return the 2st element- " + arr.get(1) );
System.out.println("return the 4rd element- " + arr.get(3) );
System.out.println("Size of ArrayList after insertion- " + arr.size());
System.out.println("Elements of ArrayList after insertion- " + arr);
arr.remove(p2);
arr.remove(2);
System.out.println("Size of ArrayList after deletion- " + arr.size());
System.out.println("Elements of ArrayList after deletion- " + arr);
There are many ways to read a file line by line in java. But I prefer using commons-io utils. It's a very useful tool that provide reading from a file. Here is a one line example.
List<String> lines = FileUtils.readLines(new File(fileName));