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;
}
}
Related
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);
}
}
I've recently had a small class test in college for java and I need help.
I have an object called "Products" that takes (String, double, int) as it's parameters.
I've created an ArrayList
ArrayList<Product> products = new ArrayList<>();
What I'm trying to do is use a StringTokenizer to read from this format and
store it into individual objects and then I want to print out the object contents.
PR0001 7.99 10
PR0002 29.99 0
PR0003 5.99 25
PR0004 99.99 50
PR0005 17.99 15
PR0006 15.99 0
PR0007 19.99 35
PR0008 39.99 40
PR0009 2.99 0
PR0010 3.99 5
My main method is:
package objects;
import java.util.ArrayList;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
public class main_object_class
{
public static void main(String[] args)
{
ArrayList<Product> products = new ArrayList<>();
String fileName = "products.txt";
try
{
Scanner file = new Scanner(new File(fileName));
while(file.hasNextLine())
{
StringTokenizer strToken = new StringTokenizer(file.next(), " ");
while(strToken.hasMoreTokens())
{
String pCode = strToken.nextToken();
System.out.println("pCode Works");
double pPrice = Double.parseDouble(strToken.nextToken());
System.out.println("pPrice Works");
int pQuantity = Integer.parseInt(strToken.nextToken());
System.out.println("pQuantity Works");
products.add(new Product(pCode,pPrice,pQuantity));
System.out.println("Storing Works");
}
}
for(int i=0;i<products.size();i++)
{
System.out.println(products);
}
}catch(FileNotFoundException e)
{
e.printStackTrace();
}
}
}
My Product method:
package objects;
public class Product
{
private String pCode = "";
private double pPrice = 0;
private int pQuantity = 0;
public Product(String c, double p, int q)
{
pCode = c;
pPrice = p;
pQuantity = q;
}
public void setCode(String c)
{
pCode = c;
}
public String getCode()
{
return pCode;
}
public void setPrice(double p)
{
pPrice = p;
}
public double getPrice()
{
return pPrice;
}
public void setQuantity(int q)
{
pQuantity = q;
}
public int getQuantity()
{
return pQuantity;
}
#Override
public String toString()
{
return "Code : " + getCode() + "\tPrice : $" + getPrice() + "\tQuantity : " + getQuantity();
}
}
My Error:
run:
pCode Works
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(StringTokenizer.java:349)
at objects.main_object_class.main(main_object_class.java:24)
C:\Users\Alex\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
I'd really like to thank for all the input. I've tried all solutions and they all worked. Yet I'm going to go with #Jerin Joseph solution!
Read the file line by line, Scanner::nextLine() gives you one line at a time.
StringTokenizer strToken = new StringTokenizer(file.nextLine(), " ");
Remove the while(strToken.hasMoreTokens()), You need to check it for every token you parse.
Change it to ,
String pCode = "";
double pPrice = 0;
int pQuantity = 0;
if(strToken.hasMoreTokens()){
pCode = strToken.nextToken();
System.out.println("pCode Works");
}
if(strToken.hasMoreTokens()){
pPrice = Double.parseDouble(strToken.nextToken());
System.out.println("pPrice Works");
}
if(strToken.hasMoreTokens()){
pQuantity = Integer.parseInt(strToken.nextToken());
System.out.println("pQuantity Works");
}
products.add(new Product(pCode,pPrice,pQuantity));
System.out.println("Storing Works");
Your problem is that you check if there are Tokens left, and than call "nextToken()" 3 times. Where there cannot be a guranty that there will be 3 tokens left, unless you specifically check for it. Like so:
if(strToken.countTokens() >= 3)
{
\\ here you can call strToken.nextToken() safly for 3 times.
}
Your current approuch is a classic approuch for basic itteration. E.g.
while(strToken.hasMoreElements())
{
String next = strToken.nextToken();
}
But it allows only one safe call of "nextToken()" between the bracets.
I hope this helped
Having trouble figuring out exactly how to do this. Ive wrote 10 different things and worked on it for 8 hours and have yet to figure out how to get this to work. What I'm trying to do with this program is get a the persons name, friends name, persons age, friends age, and persons popularity (All of this from a .txt file with each line as : Michelle, 12/20/2008, Camilla) . I have gotten the persons name to output correctly, persons age to output correctly, and persons friend to output correctly. But having trouble with popularity and getting friends age from personsofinterest's age.
What I need help with :
1.Popularity points adding up and returned for each time the personOfInterest is in the name array. With the popularity I have went back and debugged it after i was getting 0 for every popularity for each person. And I got that it wasn't adding anything to the return, I tried many different ways but still could not figure it out.
2.Setting personOfInterest name to certain age to be used as friendsAge if the users friend is a personOfInterest already found age for.(All personOfInterest names in .txt field is someones friend)
friends_data.txt :
Michelle, 12/20/2008, Camilla
Bryan, 3/8/2007, Tom
Camilla, 6/7/2005, Michelle
Tom, 10/15/2007, Bryan
Charlotte, 3/2/2008, Michelle
I believe my code looks a little messy, started going back and throwing things together I thought would work.
Person Class :
import java.util.ArrayList;
public class Person {
public String personsName;
public String personsFriend;
public String personsBirthday;
public int personsPopularity;
public int popularity = 0;
public ArrayList<String> friends = new ArrayList<>();
public Person(String aName, String aFriend, String aBirthday) {
personsName = aName;
personsFriend = aFriend;
friends.add(personsFriend);
personsBirthday = aBirthday;
}
public String getName() {
return personsName;
}
public String getFriendsName() {
return personsFriend;
}
public String getBirthday() {
return personsBirthday;
}
public void getPopularityNumber(){
for(int i = 0; i < friends.size(); i++){
if (personsName.equals(friends.get(i))){
popularity = 1 + popularity;
}
else
popularity = popularity;
}
System.out.println(popularity);
}
public String getFriend() {
return personsFriend;
}
public int getAge() {
int MONTH = 0;
int DAY = 0;
int YEAR = 0;
for (int i = 0; i < 3; i++) {
String[] dates = personsBirthday.split("/");
String month = dates[0];
String day = dates[1];
String year = dates[2];
MONTH = Integer.parseInt(month);
DAY = Integer.parseInt(day);
YEAR = Integer.parseInt(year);
}
int age = (2014 - YEAR);
int moAge = (5 - MONTH);
if (moAge < 0) {
age--;
}
return age;
}
}
Main File :
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;
public class PersonTester {
public static void main(String[] args) throws FileNotFoundException {
//Get that file and start the scan on that broseph
File inputFile = new File("friends_data.txt");
Scanner in = new Scanner(inputFile);
//Set up an array for our Person objects
final int SIZE = 5;
Person[] personsOfInterest = new Person[SIZE];
String[] friends = new String[5];
//Lets get this i declared as 0 for our array!
int i = 0;
int popularity = 0;
String person;
while (in.hasNextLine()) {
String line = in.nextLine();
String[] nameBirthdayname = line.split(", ");
person = nameBirthdayname[0];
String birthday = nameBirthdayname[1];
String friend = nameBirthdayname[2];
friends[i] = friend;
personsOfInterest[i] = new Person(person, friend, birthday);
i++;
}
for (i = 0; i < SIZE; i++) {
System.out.println("");
System.out.println("New Person");
System.out.println("--------------------------------------------------------");
System.out.println("Persons Name : " + personsOfInterest[i].getName());
System.out.println("Popularity : " + personsOfInterest[i].getPopularityNumber());
System.out.println("Their age on May 1, 2014 : " + personsOfInterest[i].getAge());
System.out.println("Persons Best Friend : " + personsOfInterest[i].getFriend());
System.out.println("Best Friends Age on May 1,2014 : " + personsOfInterest[i].getName());
System.out.println("--------------------------------------------------------");
}
}
}
Have Also Tried this for getPopularityNumber Method :
public void getPopularityNumber(String[] friends) {
for (int i = 0; i < 5; i++) {
if (personsName.equals(friends[i])) {
popularity = 1 + popularity;
} else
popularity = popularity;
}
System.out.println(popularity);
}
Any help would be greatly appreciated!
I am trying to make my method display people who are born during the month of July.
class Personne {
private String naissance;
private int nbCafe;
public Personne(String year, int number) {
naissance = year;
nbCafe = number;
}
public Personne(String year) {
naissance = year;
nbCafe = 1;
}
public String getNaissance() {
return naissance;
}
public int getNbcafe() {
return nbCafe;
}
public void afficher(String message) {
System.out.println(message + ": nee le 16 novembre 1994, consomme 2 tasse(s) de cafe");
}
static void afficherTable(Personne[] pers, int amount) {
System.out.printf("\nContenu du tableau de %d personne(s)\n", amount);
System.out.printf("nbPers Birth numCafe\n");
for (int i = 0; i < amount; i++)
System.out.printf(" %d) %s %d\n", i, pers[i].getNaissance(), pers[i].getNbcafe());
}
static void demo1(Personne[] pers, int amount) {
int count = 0;
String juillet = "07";
for (int i = 0; i < amount; i++)
if (pers[i].toString().substring(3, 5) == juillet) {
count++;
}
System.out.println(count);
}
}
public class popo {
public static void main(String args[]) {
Personne p1 = new Personne("16/11/1994", 2);
Personne p2 = new Personne("15/12/1990");
Personne[] pers = {new Personne("12/10/1991", 3),
new Personne("15/10/1990", 6),
new Personne("13/07/1993", 3),
new Personne("05/06/1991"),
new Personne("16/12/1992", 3)};
int nbpers = pers.length;
p1.afficher("Informations de p1");
Personne.afficherTable(pers, nbpers);
Personne.demo1(pers, nbpers);
}
}
The method demo1() in my class is supposed to pick out the people who are born in July but it doesn't seem to work. I've tried using charAt/indexOf/substring to get the month from "Naissance" to no avail. Is there another way of finding what you want from a table of strings?
I would add this to the Personne class:
public int getMonth(){
return Integer.parseInt(this.naissance.substring(3,5));
}
Then you can call
If (pers[i].getMonth == 7)
The problem is that you're using:
pers[i].toString().substring(3, 5) == juillet)
You need to use
pers[i].getNaissance().substring(3, 5).equals(juillet))
since you're looking for the month from the naissance field.
You should use the String.equals(String other) function to compare strings, not the == operator.
The function checks the actual contents of the string, the == operator checks whether the references to the objects are equal. More info: Java String.equals versus ==
static void demo1(Personne[] pers, int amount){
int count = 0;
final String juillet = "07";
for (int i=0; i<amount; i++)
if (pers[i].naissance.substring(3,5).equals(juillet)) {
count++;
}
System.out.println(count);
}
}
The toString method was not overriden, you intended to use getNaissance() or so.
Also comparing strings is done with equals, not ==.
Instead of amount you may use pers.length.
if(pers[i].toString().substring(3,5)== juillet) has to be
if(pers[i].toString().substring(3,5).equals(juillet))
Honestly I'ld do in this way:
static void demo1(Personne[] pers, int amount) throws ParseException{
int count=0;
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setLenient(true);
Calendar c = GregorianCalendar.getInstance();
int juillet=7;
for (int i=0; i<amount;i++)
{
Date d = sdf.parse(pers[i].getNaissance());
c.setTime(d);
int month = c.get(Calendar.MONTH)+1;
if( month == juillet )
{
count++;
}
}
System.out.println(count);
}
Angelo
I am trying to all possible child domains from a given host. I have written following code. It works but my only worry is performance.
Is it required to optimize this code further:
import java.util.Arrays;
import java.util.Collections;
public class DemoExtractHostArray {
public static String[] createHostArray(String host) {
String[] stringArr = host.split("\\.");
String[] hostArray = new String[stringArr.length];
int hostIndex = 0;
for(int index = stringArr.length-1; index>=0;index--){
if(hostIndex==0){
hostArray[hostIndex] = stringArr[index];
}
else{
hostArray[hostIndex] = stringArr[index]+"."+hostArray[hostIndex-1];
}
hostIndex++;
}
Collections.reverse(Arrays.asList(hostArray));
return hostArray;
}
public static void main(String a[]){
for(String s: createHostArray("a.b.c.d.e.f")){
System.out.println(s);
}
}
}
Output:
a.b.c.d.e.f
b.c.d.e.f
c.d.e.f
d.e.f
e.f
f
The only potential improvement to your code is removing this call:
Collections.reverse(Arrays.asList(hostArray));
Since you are creating the hostArray and then reversing it, you might as well change the loop to create the array in reverse order right away, so as to no longer requiring an explicit reversal:
// hostIndex is no longer required - remove the line below:
// int hostIndex = 0;
for(int index = stringArr.length-1 ; index>=0 ; index--){
if(index == stringArr.length-1) {
hostArray[index] = stringArr[index];
}
else{
hostArray[index] = stringArr[index]+"."+hostArray[index+1];
}
}
I would personally use recusion. This implementation does not require the reversal of the array and, in my opinion, may be easier to follow.
http://ideone.com/MnMZOL
package com.poachit.utility.web;
import java.util.Arrays;
import java.util.Collections;
public class DemoExtractHostArray {
public static void createHostArray(String[] root, String[] result, int index) {
String host="";
int i = index;
if (index == root.length) {
return;
}
for ( ; i < root.length-1; i++) {
host += root[i] + ".";
}
if (i < root.length) {
host += root[i];
}
result[index] = host;
createHostArray(root, result, ++index);
}
public static void main (String[] args) throws java.lang.Exception
{
String host = "a.b.c.d.e.f";
String [] tokens = host.split("\\.");
String [] result = new String[tokens.length];
createHostArray(tokens, result, 0);
for (String s : result) {
System.out.println(s);
}
}
}
You can optimize the code like this
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
public static String[] createHostArray(String host) {
String[] stringArr = host.split("\\.");
String[] hostArray = new String[stringArr.length];
int hostIndex = 0;
for(int index = stringArr.length-1; index>=0;index--){
if(hostIndex==0){
hostArray[hostIndex] = stringArr[index];
}
else{
hostArray[hostIndex] = stringArr[index]+"."+hostArray[hostIndex-1];
}
hostIndex++;
}
Collections.reverse(Arrays.asList(hostArray));
return hostArray;
}
public static String[] betterCreateHostArray(String host) {
List<String> hostList = new ArrayList<String>();
do {
if(!host.contains(".")) {
hostList.add(host);
break;
} else {
hostList.add(host);
host = host.substring(host.indexOf('.')+1);
}
} while(host.length() > 0);
return hostList.toArray(new String[hostList.size()]);
}
public static void main(String a[]){
long startTime = System.nanoTime();
String[] array = createHostArray("a.b.c.d.e.f");
long endTime = System.nanoTime();
long timeByFirstApproach = endTime - startTime;
for(String s: array){
System.out.println(s);
}
System.out.println("=====");
startTime = System.nanoTime();
array = betterCreateHostArray("a.b.c.d.e.f");
endTime = System.nanoTime();
long timeBySecondApproach = endTime - startTime;
for(String s: array){
System.out.println(s);
}
System.out.println(String.format("Time taken by first approach=[%d] nano seconds and\n"
+ "Time taken by second approach=[%d] nano seconds", timeByFirstApproach,timeBySecondApproach));
}
}
and here the performance result
a.b.c.d.e.f
b.c.d.e.f
c.d.e.f
d.e.f
e.f
f
=====
a.b.c.d.e.f
b.c.d.e.f
c.d.e.f
d.e.f
e.f
f
Time taken by first approach=[1625572] nano seconds and
Time taken by second approach=[308289] nano seconds
Second approach is more than 5 times faster than the approach you are following.