Troubles sorting an ArrayList - java

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

Related

sort by date java basic list

I have a list in java that contains lines of string id;city;date;days;price;vehicle. I need to sort all of it by date.(it's from a csv file that I read)
My list:
List <Ticket> list = new LinkedList<Ticket>();
And the way it is defined:
class Ticket {
int id;
String city;
String date;
int days;
float price;
String vehicle;
Ticket(int i, String c, String y, int d, float p, String v) {
id = i;
city = c;
date = y;
days = d;
price = p;
vehicle = v;
}
I was trying bubble sort but I have no clue how to compare dates and all the examples I found had ArrayList or were comparing small amounts of dates. I'm sorry if this is a bad question I just don't know how to apply everything I found to my situation.
You can do this with Comparator interface. I prefer to convert the string into date first.
For dd/MM/yyyy (01/01/1970) pattern example (without conversion):
List<Ticket> list = new LinkedList<Ticket>();
... //fill the list.
Collections.sort(list, new Comparator<Ticket>() {
public int compare(Ticket t1, Ticket t2) {
String[] dateParts1 = t1.date.split("/");
String[] dateParts2 = t2.date.split("/");
int yearResult = dateParts1[2].compareTo(dateParts2[2]);
if (yearResult != 0) {
return yearResult;
}
int monthResult = dateParts1[1].compareTo(dateParts2[1]);
if (monthResult != 0) {
return monthResult;
}
int dayResult = dateParts1[0].compareTo(dateParts2[0]);
if (dayResult != 0) {
return dayResult;
}
return 0;
}
});
or (with conversion):
List<Ticket> list = new LinkedList<Ticket>();
... //fill the list.
Collections.sort(list2, new Comparator<Ticket>() {
public int compare(Ticket t1, Ticket t2) {
String pattern = "dd/MM/yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
try {
Date date1 = simpleDateFormat.parse(t1.date);
Date date2 = simpleDateFormat.parse(t2.date);
return date1.compareTo(date2);
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
}
});
Also, you can do same thing in class with Comparable interface.
public class Ticket **implements Comparable<Ticket>** {
int id;
String city;
String date;
int days;
float price;
String vehicle;
Ticket(int i, String c, String y, int d, float p, String v) {
id = i;
city = c;
date = y;
days = d;
price = p;
vehicle = v;
}
**#Override
public int compareTo(Ticket o) {
String[] dateParts1 = this.date.split("/");
String[] dateParts2 = o.date.split("/");
int yearResult = dateParts1[2].compareTo(dateParts2[2]);
if (yearResult != 0) {
return yearResult;
}
int monthResult = dateParts1[1].compareTo(dateParts2[1]);
if (monthResult != 0) {
return monthResult;
}
int dayResult = dateParts1[0].compareTo(dateParts2[0]);
if (dayResult != 0) {
return dayResult;
}
return 0;
}**
}
Then:
List<Ticket> list = new LinkedList<Ticket>();
... //fill the list.
Collections.sort(list);
You can parse the date String to a date object like LocalDateTime or Instant and etc' (depending on your use case).
I randomly picked LocalDateTime for this example.
Then you can do:
tickets.add(new Ticket(1, "dsa", LocalDateTime.now().plusSeconds(5), 6, 5, "rew"));
tickets.add(new Ticket(0, "dsa", LocalDateTime.now(), 6, 5, "rew"));
List<Ticket> sortedTicketsByDate = tickets.stream()
.sorted(Comparator.comparing(t -> t.date)) // comparing by date
.collect(Collectors.toList());
System.out.println(sortedTicketsByDate);
Output:
[
Ticket(id=0, city=dsa, date=2021-05-02T23:46:03.214, days=6, price=5.0, vehicle=rew),
Ticket(id=1, city=dsa, date=2021-05-02T23:46:08.197, days=6, price=5.0, vehicle=rew)
]
Here is another clean version using java records (new since JDK 16) which is recommended for plain java objects (pojos) that store data.
Read more info in this article : https://www.baeldung.com/java-record-keyword
You implement the Comparable interface based on date and Collections.Sort() can sort your ArrayList based on that.
import java.util.ArrayList;
import java.util.Collections;
record Ticket(int id,String city,String date,int days,float price,String vehicle) implements Comparable<Ticket>{
public int compareTo(Ticket ticket){
return this.date.compareTo(ticket.date);
}
}
public class Main{
public static void main(String[] args) {
Ticket ticket1 = new Ticket(1,"New York","2021-05-03",10,110.30f,"Ferrari");
Ticket ticket2 = new Ticket(2,"Miami","2021-05-02",9,120.50f,"Porche");
Ticket ticket3 = new Ticket(3,"Los Angeles","2021-05-01",10,150.50f,"Mercedes");
var list = new ArrayList<Ticket>();
list.add(ticket1);
list.add(ticket2);
list.add(ticket3);
System.out.println("The List before sorting:\n");
list.forEach(System.out::println);
Collections.sort(list);
System.out.println("\nThe List After sorting:\n");
list.forEach(System.out::println);
}
}

Calculator for metric distance from an expression that contains different scales

public enum Operator {
PLUS("+"),
MINUS("-");
private final String operator;
Operator(String operator) {
this.operator = operator;
}
public String getOperator() {
return operator;
}
public static Operator getByValue(String operator) {
for (Operator operatorEnum : Operator.values()) {
if (operatorEnum.getOperator().equals(operator)) {
return operatorEnum;
}
}
throw new IllegalArgumentException("Invalid value");
}
}
//////////
public enum MetricConvertor {
m(1000),
cm(10),
mm(1),
km(1000000),
dm(100);
private int scale;
MetricConvertor(int scale) {
this.scale = scale;
}
public int getScale() {
return scale;
}
}
/////////
public class Application {
public static void main(String[] args) {
int scale = MetricConvertor.valueOf("m").getScale();
}
I wan to create a calculator that is capable of computing a metric distance value from an expression that contains different scales and systems.
Output should be specified by the user.
Only Addition and subtraction is allowed.
Output is in lowest unit.
Expression: 10 cm + 1 m - 10 mm
Result: 1090 mm
I am stuck at this point, how can I add or substract the values for a list and convert them at the lowest scale sistem( eg above mm, but it can be dm if are added for example dm + m + km)
Here is solution
split each string by add/minus and add it to appropriate list
split number and metric in each list(can use matcher) and sum it
result = sumAdd - sumMinus(mm).
Please optimize it, because i don't have time to optimize this code, I need to go to bed :D
Result is in mm, so you have to get lowest metric and recaculate it(leave it to you).
private static int caculator(String exp) {
List<String> addList = new ArrayList<>();
List<String> minusList = new ArrayList<>();
int checkPoint = 0;
boolean op = true;//default first value is plus
// Split string with add/minus
for (int i = 1; i < exp.length(); i++) {
String s = exp.substring(i, i + 1);
if (Operator.PLUS.getOperator().equals(s)) {
checkOperator(addList, minusList, op, exp.substring(checkPoint, i).trim());
checkPoint = i + 1;
op = true;
continue;
}
if (Operator.MINUS.getOperator().equals(s)) {
checkOperator(addList, minusList, op, exp.substring(checkPoint, i).trim());
checkPoint = i + 1;
op = false;
continue;
}
}
// Add last string
checkOperator(addList, minusList, op, exp.substring(checkPoint).trim());
// Get sum each list
int sumAdd = sumList(addList);
int sumMinus = sumList(minusList);
return sumAdd - sumMinus;
}
//sum a list
private static int sumList(List<String> addList) {
int sum = 0;
for (String s: addList) {
String[] arr = s.split(" ");
int value = Integer.parseInt(arr[0]);
int scale = MetricConvertor.valueOf(arr[1]).getScale();
sum += value * scale;
}
return sum;
}
// check operator to put into approriate list
private static void checkOperator(List<String> addList, List<String> minusList, boolean op, String substring) {
if (op) {
addList.add(substring);
} else {
minusList.add(substring);
}
}

Algorithm to find maximum classes attended by student | activity selection problem

Algorithm asked in one of the top company's interview, but I am not able to find a feasible solution. Need expert advice.
Suppose a student wants to attend maximum number of classes in a collage in a day (without any class overlap).
Input Format
The first line contains an integer n which gives the number of subjects offered on that day.
The next n lines follow containing the subject name (which is a string) followed by the start and end time for that subject in 24-hour format: hh:mm
For eg: Maths 10:00 11:00
Note: The timings are given in a 24-hour format and the subject names do not have spaces between them.
Output Format
The output should contain a number representing the maximum number of classes the student can choose.
Constraints
2 <= n <= 100
start time of a class < end time of class
Sample Input
4
Maths 16:00 18:00
ComputerScience 12:00 13:00
Physics 12:30 14:00
Chemistry 14:00 16:30
Sample Output
2
Explanation
ComputerScience starts the earliest and ends the earliest, so we take it first. After that, we cannot take Physics because it starts before ComputerScience is over. So we will take the next class, that is, Chemistry. But after Chemistry we cannot take Maths as Maths class starts before Chemistry class ends. So we can schedule a maximum of 2 classes for the day.
Below is my solution but I am not getting correct answer:
private void getMaxClass(String input) {
Map<String, Long> classTime = new LinkedHashMap<>();
Map<String, List<String>> timeMap = new LinkedHashMap<>();
String[] split = input.split(" ");
String subject = split[0];
String StartTime = split[1];
String endTime = split[2];
List<String> lvalue = new ArrayList<>();
lvalue.add(StartTime);
lvalue.add(endTime);
timeMap.put(subject, lvalue);
long difference = FineDifferenceInTime(StartTime, endTime);
classTime.put(subject, difference);
int count = 0;
Date date1 = null;
Date date2 = null;
Map<String, Long> sortedByValueDesc = classTime.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
for (Map.Entry<String, Long> entry : sortedByValueDesc.entrySet()) {
String sub = entry.getKey();
List<String> startEnd = timeMap.get(sub);
Date dateBefore = null;
Date dateAfter = null;
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
try {
dateBefore = format.parse(startEnd.get(0));
dateAfter = format.parse(startEnd.get(1));
} catch (ParseException e) {
e.printStackTrace();
}
if (count == 0) {
count++;
try {
date1 = format.parse(startEnd.get(0));
date2 = format.parse(startEnd.get(1));
} catch (ParseException e) {
e.printStackTrace();
}
}
if (dateBefore.after(date1) && dateBefore.before(date2)) {
timeMap.remove(sub);
}
}
System.out.println(timeMap.size());
}
This is known in literature as the Interval Scheduling Problem. There are many ways to solve it, but since it is NP-complete (as there is a a polynomial reduction from VC) you'll necessarily need to explore all the combinations.
Greedy algorithms do exist (as is yours and the solution by #PriyankaDeshmukh), but they don't guarantee you the exact solution for all instances of the problem.
The solution below is a simple tree search: at each level we decide if we take a given course or not and move on to decide on the next course.
You could also implement a dynamic programming solution.
Here is a very good blog post covering solutions to the Interval Scheduling Problem.
I modelled a student class the following way:
class StudentClass {
public int _start;
public int _end;
public String _name;
public StudentClass(String name, int start, int end) {
_name = name;
_start = start;
_end = end;
}
public boolean overlapsWith(StudentClass other) {
return _start < other._end && _end > other._start;
}
public String toString() {
return "[" + _start + " - " + _end + "] " + _name;
}
}
There are classes to represent the time of the day, but their syntax/instantiation is a bit annoying/verbose -- feel free to improve this answer though! My Java is also very rusty, so feel free to correct me :-)
The Schedule class has a getMaxSchedule() which returns the solution to the problem -- what is the maximum number of classes a student can take, such that none of them overlap?
There are a few ways to optimize it, but I left it as-is as I believe it's easier to be understood.
public class Schedule {
List<StudentClass> _classes = new LinkedList<>();
public void addClass(String name, int startTime, int endTime) {
_classes.add(new StudentClass(name, startTime, endTime));
}
private int getMaxSchedule(int index, Collection<StudentClass> selected) {
// check if we reached the end of the array
if (index >= _classes.size()) {
return 0;
}
StudentClass current = _classes.get(index);
// check if taking this class doesn't conflict with the
// previously-selected set of classes
boolean canTakeThisClass = true;
for (StudentClass other : selected) {
if (current.overlapsWith(other)) {
canTakeThisClass = false;
break;
}
}
// check best schedule if we don't take this class
int best = getMaxSchedule(index + 1, selected);
// check best schedule if we take this class (if such is possible)
if (canTakeThisClass) {
selected.add(current);
best = Math.max(best, 1 + getMaxSchedule(index + 1, selected));
selected.remove(current);
}
return best;
}
public int getMaxSchedule() {
Collection<StudentClass> selected = new ArrayList<>();
return getMaxSchedule(0, selected);
}
}
You can see the result is 3 for your concrete problem through the following:
public static void main(String[] args) {
Schedule s = new Schedule();
s.addClass("Maths", 1600, 1800);
s.addClass("Computer Science", 1200, 1300);
s.addClass("Physics", 1230, 1400);
s.addClass("Chemistry", 1400, 1630);
System.out.println("maximum classes: " + s.getMaxSchedule());
}
I tried it with Python. It gives correct output.
I got it sorted by start time of class.
sorted_by_start = [{'sub': 'ComputerScience', 'start': '12:00', 'end': '13:00',
'duration': 60}, {'sub': 'Physics', 'start': '12:30', 'end': '14:00', 'duration':
90}, {'sub': 'Chemistry', 'start': '14:00', 'end': '16:30', 'duration': 150},
{'sub': 'Maths', 'start': '16:00', 'end': '18:00', 'duration': 120}]
possible_sub = set()
for a, b in itertools.combinations(sorted_by_start, 2):
strt_tme = datetime.datetime.strptime(a["end"], '%H:%M')
end_tme = datetime.datetime.strptime(b["start"], '%H:%M')
if(strt_tme <= end_tme) :
possible_sub.add((a["sub"],b["sub"]))
print("A student can attend these combinations of subject classes:",possible_sub)
print("Maximum classes student can attend in a day is: ",max(map(len,possible_sub)))
Here trick part is deciding how many combinations you can make. So, that you can do by adding additional for loop ranging from 2 to length of sorted_list and pass i to combinations(sorted_list, i) like this.
Ouput is :
A student can attend these combinations of subject classes: {('Physics', 'Maths'), ('Physics', 'Chemistry'), ('ComputerScience', 'Chemistry'), ('Compu
terScience', 'Maths')}
Maximum classes student can attend in a day is: 2
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class InputSubject implements Comparable<InputSubject>{
String subject;
String startTime;
String endTime;
InputSubject(){
}
InputSubject(String subject, String startTime, String endTime){
this.subject = subject;
this.startTime = startTime;
this.endTime = endTime;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
#Override
public int compareTo(InputSubject o) {
return this.endTime.compareTo(o.endTime);
}
}
public class SubjectSort {
static int getToatlSubject(List<InputSubject> list){
String sTime = null;
String eTime = null;
int count = 0;
int noOfSubject = 0;
for(InputSubject object : list){
if(count == 0){
count++;
eTime = object.getEndTime();
noOfSubject ++;
}
else {
if(object.getStartTime().compareTo(eTime) > 0){
eTime = object.getEndTime();
noOfSubject ++;
}
}
}
return noOfSubject;
}
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
try {
int days = Integer.parseInt(reader.readLine());
for(int i = 0 ; i < days ;i++){
int sub = Integer.parseInt(reader.readLine());
List<InputSubject> list = new ArrayList<>();
for(int k = 0 ; k < sub ; k++){
InputSubject inputSubject = null;
String subDetails = reader.readLine();
String[] subAndTimes = subDetails.split(" ");
inputSubject = new InputSubject(subAndTimes[0],subAndTimes[1],subAndTimes[2]);
list.add(inputSubject);
}
Collections.sort(list);
System.out.println(getToatlSubject(list));
}
} catch (Exception e) {
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class InputSubject implements Comparable<InputSubject>{
String subject;
String startTime;
String endTime;
InputSubject(){
}
InputSubject(String subject, String startTime, String endTime){
this.subject = subject;
this.startTime = startTime;
this.endTime = endTime;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
#Override
public int compareTo(InputSubject o) {
return this.endTime.compareTo(o.endTime);
}
}
public class solution {
static int getToatlSubject(List<InputSubject> list){
String sTime = null;
String eTime = null;
int count = 0;
int noOfSubject = 0;
for(InputSubject object : list){
if(count == 0){
count++;
eTime = object.getEndTime();
noOfSubject ++;
}
else {
if(object.getStartTime().compareTo(eTime) >= 0){
eTime = object.getEndTime();
noOfSubject ++;
}
}
}
return noOfSubject;
}
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
try {
int days = Integer.parseInt(reader.readLine());
for(int i = 0 ; i < days ;i++){
int sub = Integer.parseInt(reader.readLine());
List<InputSubject> list = new ArrayList<>();
for(int k = 0 ; k < sub ; k++){
InputSubject inputSubject = null;
String subDetails = reader.readLine();
String[] subAndTimes = subDetails.split(" ");
inputSubject = new InputSubject(subAndTimes[0],subAndTimes[1],subAndTimes[2]);
list.add(inputSubject);
}
Collections.sort(list);
System.out.println(getToatlSubject(list));
}
} catch (Exception e) {
}
}
}
i had same question in a coding round of a recruitment and I have solved it the following way and it gives correct answer. But unfortunately this code passed only 1 test case given in the challenge. I believe that the test cases were incorrect. Can anyone point out if I have missed something in code which might have led to this code failing other test cases?
import java.util.*;
import java.time.*;
import java.time.format.DateTimeFormatter;
import static java.time.temporal.ChronoUnit.*;
class solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
for (int i = 0; i < t; i++) {
int n=sc.nextInt();
String trash=sc.nextLine();
HashMap subjects=new HashMap<String,String>();
HashMap starttime=new HashMap<String,LocalTime>();
HashMap endtime=new HashMap<String,LocalTime>();
HashMap length=new HashMap<String,Long>();
for (int j = 0; j < n; j++){
String classes = sc.nextLine();
String[] classesArray=classes.split(" ");
String subject=classesArray[0];
if(classesArray[1].split(":")[0].length()==1){
classesArray[1]="0"+classesArray[1];
}
if(classesArray[2].split(":")[0].length()==1){
classesArray[2]="0"+classesArray[2];
}
LocalTime startTime=LocalTime.parse(classesArray[1]);
LocalTime endTime=LocalTime.parse(classesArray[2]);
DateTimeFormatter formatter = DateTimeFormatter.ISO_TIME;
Long lengthLecture=MINUTES.between(startTime, endTime);
subjects.put(subject,subject);
starttime.put(subject,startTime);
endtime.put(subject,endTime);
length.put(subject,lengthLecture);
String value = startTime.format(formatter);
String value1 = endTime.format(formatter);
// System.out.printf("Sub:%s st:%s et:%s length:%d\n",subject,value,value1,lengthLecture);
}
findMax(subjects,starttime,endtime,length);
//System.out.println(num);
}
}
public static void findMax(HashMap<String,String> subs,HashMap<String,LocalTime> strt,HashMap<String,LocalTime> endt,HashMap<String,Long> length){
int number=0;
List<Integer> list = new ArrayList<Integer>();
String curr,next1;
for (Map.Entry<String,String> entry : subs.entrySet()){
//System.out.println("Checkign for number: "+entry.getKey());
number=findnext(entry.getKey(),strt,endt);
// System.out.println("Number is: "+number);
list.add(number);
}
System.out.println(Collections.max(list));
}
public static int findnext(String subjt,HashMap<String,LocalTime> strt,HashMap<String,LocalTime> endt){
String sub=subjt;
int number=1;
LocalTime substtime=strt.get(subjt);
LocalTime subedtime=endt.get(subjt);
Long timetillstart=922337203L;
for (Map.Entry<String,LocalTime> entry : strt.entrySet()){
if((entry.getValue().compareTo(subedtime)>=0) && (MINUTES.between(subedtime, entry.getValue())<=timetillstart)){
sub=entry.getKey();
substtime=strt.get(entry.getKey());
timetillstart=MINUTES.between(subedtime, entry.getValue());
}
}
if(sub!=subjt){
number=number+findnext(sub,strt,endt);
}
return number;
}
}

addScore method is over writing current array values instead of appending to the current list

I am a novice java student. I have a project for a java class where I am to write a Golfer class, Score class and a tester for the Golfer class to test all methods. The specific problems I am having is :
When I call the addScore method, the method overwrites the old data instead of adding to the existing. I need to get the program to add the scores in the array in addition to the previous score.
The findScore method is private and used in the public method getScore, however, when I run the program, I get the null value regardless of the parameter in the call. I need to return the index of an array based on the date entered.
The following is excerpts from the code and not the entire program.
public class Golfer {
/**String representing the golfer's name*/
private String name;
/**String representing the golf course where the golfer's hadicap is kept*/
private String homeCourse;
/**Unique integer that identifies every golfer*/
private int idNum;
/**Array storing all the golfer's scores*/
private Score[] scores;
public static int nextIDNum;
/**Default constructor, sets all instance field to a default value. Creates Array.
*/
public Golfer() {
name = "";
homeCourse = "";
scores = new Score[0];
nextIDNum = 1000;
}
/**Constructor sets name and homeCourse from parameters and uses the static variable nextIDNum to retrieve the next available ID number. Creates Array.
*/
public Golfer(String golferName, String home) {
setName(golferName);
setHomeCourse(home);
setNextIDNum(nextIDNum);
scores = new Score[10];
}
/**Creates a Score object from the parameters that represent the course, course rating, course slope, date and score.  Adds the newly created Score object to the Array of Scores. 
#param golfCourse A String representing the golf course name
#param rating A double representing the golf course rating
#param slope An int representing the golf course slope
#param scoreDate A String representing the date the course was played
#param score An int representing what was scored on the course
*/
public void addScore(String golfCourse, double rating, int slope, String scoreDate, int score) {
Score[] golfScores = new Score[scores.length + 1];
for (int i = 0; i < scores.length; i++) {
golfScores[i] = scores[i];
}
golfScores[golfScores.length - 1] = new Score(golfCourse, rating, slope, scoreDate, score);
scores = golfScores;
}
/**Deletes a score from the Array based on score date,  Assumes only one score per day.
#param golfDate A string representing the date of the golf score
#return true if score found and deleted,
#return false if score not found.
*/
public boolean deleteScore (String golfDate) {
for (int i = 0; i < scores.length; i++) {
if (findScore(golfDate) > 0) {
scores[i] = null;
}
return true;
}
return false;
}
/**Returns a score object based on the score date. If not found returns null
#param golfDate The date of the golf score
#return Scores[i] The score on the parameterized date
#return null A null value if the score was not found.
*/
public Score getScore(String golfDate) {
for (int i = 0; i < scores.length; i++) {
if (findScore(golfDate) > 0) {
return scores[i];
}
}
return null;
}
/**Given a parameter representing the score's date, finds the score on a given date and returns the Array index of a score. Return constant NOTFOUND if not found.
#param golfDate A string representing the date of the score
#return i An array index representing the score
#return NOTFOUND A constant set to -1 if the score isn't found
*/
private int findScore(String golfDate) {
final int NOTFOUND = -1;
for (int i = 0; i < scores.length; i++) {
if (scores[i].equals(golfDate)) {
return i;
}
}
return NOTFOUND;
}
}
The score class:
public class Score {
private String courseName;
private int score;
private String date;
private double courseRating;
private int courseSlope;
public Score(String course, double rating, int slope, String golfDate, int scr) {
setCourseName(course);
setScore(scr);
setDate(golfDate);
setCourseRating(rating);
setCourseSlope(slope);
}
public Score() {
courseName = "";
score = 0;
date = "";
courseRating = 0.0;
courseSlope = 0;
}
public void setCourseName(String course) {
courseName = course;
}
public String getCourseName() {
return courseName;
}
public void setScore(int golfScore) {
if ((golfScore < 40) && (golfScore > 200)) {
golfScore = 9999;
System.out.println("Error: golf score must be between 40 and 200.");
}
score = golfScore;
}
public int getScore() {
return score;
}
public void setDate(String golfDate) {
date = golfDate;
}
public String getDate() {
return date;
}
public void setCourseRating(double rating) {
if ((rating < 60) && (rating > 80)) {
rating = 9999;
System.out.println("Error: the course rating must be between 60 and 80.");
}
courseRating = rating;
}
public double getCourseRating() {
return courseRating;
}
public void setCourseSlope(int slope) {
if ((slope < 55) && (slope > 155)) {
slope = 9999;
System.out.println("Error: The course slope must be between 55 and 155.");
}
courseSlope = slope;
}
}
The tester class:
public class GolferTester {
public static void main (String []args) {
String course1 = "Augusta National";
String course2 = "Bayhill CC";
String course3 = "TPC Sawgrass";
String player1 = "Sam Snead";
String player2 = "Arnold Palmer";
String player3 = "Jack Nicklaus";
int score1 = 66;
int score2 = 201;
int score3 = 72;
int slope1 = 60;
int slope2 = 156;
int slope3 = 77;
double rating1 = 65.2;
double rating2 = 81.8;
double rating3 = 70.9;
String date1 = "01/01/2017";
String date2 = "06/01/2016";
String date3 = "12/22/2016";
Golfer golfer1 = new Golfer(player1, course1);
Golfer golfer2 = new Golfer(player2, course2);
Score s1 = new Score(course1, rating1, slope1, date1, score1);
Score s2 = new Score(course2, rating2, slope2, date2, score2);
s1.setScore(score1);
s1.setDate(date1);
s1.setCourseRating(rating1);
s1.setCourseSlope(slope1);
s1.setCourseName(course1);
s2.setScore(score3);
s2.setDate(date3);
s2.setCourseRating(rating3);
s2.setCourseSlope(slope3);
s2.setCourseName(course3);
golfer1.addScore(s1.getCourseName(), s1.getCourseRating(), s1.getCourseSlope(), s1.getDate(), s1.getScore());
golfer2.addScore(s2.getCourseName(), s2.getCourseRating(), s2.getCourseSlope(), s2.getDate(), s2.getScore());
System.out.println(golfer1);
System.out.println("");
System.out.println(golfer2);
System.out.println("");
s1.setScore(score2);
s1.setCourseRating(rating2);
s1.setCourseSlope(slope2);
golfer1.addScore(s1.getCourseName(), s1.getCourseRating(), s1.getCourseSlope(), s1.getDate(), s1.getScore());
System.out.println(golfer1);
deleteScore(s1.getDate());
System.out.println(s1.getDate());
}
}
Any help would be appreacited
Don't use an array for a list of elements that you know will grow/shrink. Use ArrayList, which has add()
Your getScore method is returning null always

Sorting through file using QuickSort in Java

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.

Categories

Resources