Group and count duplicate values in arraylist java - java

I have used ArrayLists in my application, so I do not want to move to HashMaps as I have seen a few answers using this but did not work in my case.
I am creating my final high school project which is a study time table scheduler. I have managed to sort the ArrayList by date of the exam, but now I am trying to analyze the time table to rate it and compare the ratings with other generated timetables to give the user the best timetable (with the highest value).
I have gotten the timetable to output what they will be doing on each day ie: Afrikaans, IT, LO, Maths, Afrikaans, Afrikaans, etc.
But it seems that it duplicates on the last one for a long time even if the two last exams are within 2 days or very close together, the last one will be more dominant in the entire list. Like this:
Exam Dates:
LO = 2 Sep
Maths = 5 Sep
IT = 9 Sep
Afrikaans = 10 Sep
Results:
LO
IT
Afrikaans
Maths
IT
Afrikaans
Afrikaans
Afrikaans
Afrikaans
As you can see, the result is much more weighted towards the last given subject.
Now I am trying to compare and group the data so I can see how many days were allocated to each subject, so using the above example I need it to look like this:
LO = 1
Maths = 1
IT = 2
Afrikaans = 5
So far I have this:
ArrayList<Day> days = new ArrayList<Day>();
For(int i = 0; i < timeTable.size(); i++) {
// need to group the days here
if(days.contains(timeTable.get(i))) {
days.get(i).incrementNumberOfDays();
} else {
days.add(timeTable.get(i));
}
}
But that is not grouping the data and counting the duplicates.
Please help, my project is due in a week and I have spent two months on it. I am almost finished and am stuck here.
Thanks in advance!

You can use java.util.Collections.frequency:
int count = Collections.frequency(timeTable, value);
Edit: answer to your last question in comment:
Surely there is a quick simple way to say this value occurred 3 times
in the arraylist?

It's necessary to mention that in your timeTable, assuming it contains two same Day - Afrikaans - 1, when you see they are the same, the contains function doesn't think so. Although they have the same value for each property, but not the hashcode.
You need to override the function of equals() to make sure that when comparing two Day, if they have the same value, they are regarded as one object.
Sorry for my poor English, hope you can get it.

Related

How to penalize gaps between days in OptaPlanner constraint stream?

I have a model where each Course has a list of available TimeSlots from which one TimeSlot gets selected by OptaPlanner. Each TimeSlot has a dayOfWeek property. The weeks are numbered from 1 starting with Monday.
Let's say the TimeSlots are allocated such that they occupy days 1, 3, and 5. This should be penalized by 2 since there's one free day between Monday and Wednesday, and one free day between Wednesday and Friday. By using groupBy(course -> course.getSelectedTimeslot().getDayOfWeek().getValue()), we can get a list of occupied days.
One idea is to use a collector like sum(), for example, and write something like sum((day1, day2) -> day2 - day1 - 1), but sum(), of course, works with only one argument. But generally, maybe this could be done by using a custom constraint collector, however, I do not know whether these collectors can perform such a specific action.
Another idea is that instead of summing up the differences directly, we could simply map each consecutive pair of days (assuming they're ordered) to the difference with the upcoming one. Penalization with the weight of value would then perform the summing for us. For example, 1, 4, 5 would map onto 2, 0, and we could then penalize for each item with the weight of its value.
If I had the weeks in an array, the code would look like this:
public static int penalize(int[] weeks) {
Arrays.sort(weeks);
int sumOfDifferences = 0;
for (int i = 1; i < weeks.length; i++) {
sumOfDifferences += weeks[i] - weeks[i - 1] - 1;
}
return sumOfDifferences;
}
How can we perform penalization of gaps between days using constraint collectors?
An approach using a constraint collector is certainly possible, see ExperimentalCollectors in optaplanner-examples module, and its use in the Nurse Rostering example.
However, for this case, I think that would be an overkill. Instead, think about "two days with a gap inbetween" as "two days at least 1 day apart, with no day inbetween". Once you reformulate your problem like that, ifNotExists(...) is your friend.
forEachUniquePair(Timeslot.class,
Joiner.greaterThan(slot -> slot.dayOfWeek + 1))
.ifNotExists(Timeslot.class,
Joiners.lessThan((slot1, slot2) -> slot1.dayOfWeek, TimeSlot::dayOfWeek),
Joiners.greaterThan((slot1, slot2) -> slot2.dayOfWeek, TimeSlot::dayOfWeek))
...
Obviously this is just pseudo-code, you will have to adapt it to your particular situation, but it should give you an idea for how to approach the problem.

Java MOOC 92.3 ( I want to understand how to solve this question, not just be provided an answer)

This exercise is from Java MOOC 92.3
Simply, I have two dates.
And a method which gives me the difference of the two.
(for instance: 3/10/2011 and 3/9/2012)
My method states that as long as the month and the day are greater than the later, then simply subtract the one for which the method is called.
Here's the problem:
If a date given as a parameter has a greater year, then when I subtract the two I come out with a negative number (ex: 2011 - 2012).
public int differenceInYears(MyDate comparedDate){
int result = 0;
if(this.month >= comparedDate.month && this.day >= comparedDate.day){
result = this.year - comparedDate.year;
}else{
result = this.year - comparedDate.year;
result--;
}
return result;
The code beyond the else is for the case in which the year is not what it may look to be (Example: If I was born in May 2000 and I technically should be 20 since it is 2020, but since it is not May yet, I am therefore 19).
My conditions are still met within the first if statement, even though the result is not correct. I have tried finding a case where I can appease both cases where it does not matter what date goes first, but I am struggling with the logic. Would appreciate input.
First, if I understand correctly that this is an exercise, it’s a fine exercise. For production work one would never invent their own date class but would and should use LocalDate from the standard library for a date. And ChronoUnit.YEARS.between() for finding your age.
If you have not yet had your birthday this year, you want to subtract one year from the result. This is correct. So how do we determine whether this year’s birthday is in the future? Take a look at the following possibilities. I have not run your code, so have filled out the last column from what I think will happen from reading the code.
Today Birthday Subtract 1? Does your code subtract 1?
--------------------------------------------------------
Apr 3 Feb 1 No No
Apr 3 Feb 6 No Yes
Apr 3 Apr 1 No No
Apr 3 Apr 6 Yes Yes
Apr 3 May 1 Yes Yes
Apr 3 May 6 Yes Yes
Another way to put the question: if the months are different, do we need to compare the day of month too?
I like your attitude. In accordance with your title I am not giving away the correctly working code. I too am convinced that you will not only learn more from writing it yourself, it will also give you greater pleasure. If you’re still stuck, please leave a comment and I’ll take one more look.
EDIT: For the problem of getting a negative result if the dates are in the opposite order: The simplest solution is to check the result after you’ve calculated. If it is negative, redo the entire calculation with the dates reversed. That is, with this. and comparedDate. in each other’s places. One elegent option is that in this case you tell the other MyDate object to do the calculation instead. Call the differenceInYears method of the other object passing this as argument.

What datatype to use for 40 digit integers in java

For example
first number = 123456.....40 digits
second number = 123456.....40digits
Then I need to store the number
third = first * second;
after that I need to print third and again I need to perform operation like
fourth = third * third;
and print fourth. So how can I handle that much long integers which data type I need to use?
Use BigInteger class in java.math, then use BigInteger.multiply to multiply them together.
Check here for more on how to use it:
https://www.tutorialspoint.com/java/math/biginteger_multiply.htm
See this question its similar Arbitrary-precision arithmetic Explanation
the answer explain it quite good.
The basic is that you work with smaller parts. Just remember how you learned to work with big numbers in school (2-3 grade) you wrote down two numbers and
2351
*12
-----
4702
2351
------
28212
You just do small operations and store them somewhere you can put them in string or better in some array of integers. Where for example
number 123456789123456789 can be
number[0] = 6789
number[1] = 2345
number[3] = 7891
number[4] = 2345
number[5] = 1
String numberToShow = "";
for(int i = 0; i
There are some links for computer arighmetics
https://en.wikipedia.org/wiki/Category:Computer_arithmetic
and for adders
https://en.wikipedia.org/wiki/Category:Adders_(electronics)
In your computer you have basically also just some adders which can work only with some size of numbers and if you need to work with bigger you need to split it in smaller parts.
Some of this parts can be done parallel, so you can speed up your algorithm. These are usually more sophisticated.
But the basic principe is similar to working with big numbers on your primary school.

Taking random defined Strings

I want to do an app that, in function of the parameters checked, gives me a random String that I previusly set. The problem isn't the design of the app so the problem is the methods or classes that do what I want.
-I explain my objective with an example:
We have 100 plans to do this weekend. They are in a box and I want to pick randomly one. So great, I suppose that would be more or less easy, but, this weekend is raining so I want to pick a plan that it could be done even if it rains. And it's ending the month and I don't want to spend money so a free plan would be great. Then, I check the boxes "Free plan" and "Raining" and the app gives to me a random plan that meet the conditions.
How would you do that?
I was thinking about a bigs arrays like "Raining plans", "Free plans", with strings inside and when you check the two boxes the arrays were mixed and a string was randomly picked but I don't know how to do that and I think it could be done in another easiest way.
Thanks in advance.
Do with a two dimentional array as follows:
arr[filter][tasks];
let the filter values be binary strings converted to int
say you have two filters as aforementioned "rainy" and "free", the possible vaues are
00 - 0(decimal value 0) - not rainy, not free
01 - 1(decimal value 1) - not rainy, free
10 - 2(decimal value 2) - rainy, not free
11 - 3(decimal value 3) - rainy, free
when user checks both the values, then you have 1 and 1. Now convert binary 11 to integer which would be your first index. Get the random second index for the task.
You can have any number of filters
Hint: Integer.parseInt(binary_str, 2) for binary to int conversion.

Java Using a for loop to print calendar (logic help)

I have this assignment due by the end of the month and I'm already halfway done. We had to use Zeller's congruence to calculate the day of the week that the 1st landed on. From that point (and accounting for leap years), you have to print off a calendar of the corresponding year using loops. The teacher said that this should be a really short program and we should not try to brute force the the logic of the program (basically, don' t use a bunch of if else and loops for each month). I already have the math calculations and leap year part down, but I can't wrap my head around how to make this for loop work for numerous reasons:
How would I go about factoring in whitespaces for each month? Like how many nested loops will I actually need?
Would I need to write different loops for Leap years, months with 31 days, and months with 30 days, etc or can all this be handled with 1 giant nested loop?
For example, I just started off writing a for loop just to see if I could print off a typical 31 day calendar without any special formatting (whitespaces, Month name, days etc). Here was my first test at using a for loop:
for(int i = 1; i < 31; i++)
{
for(int j = 0; j < 7; j++)
{
System.out.print(i + "\t");
i++;
if(j == 6){
i--;}
if(i > 31)
{
break;
}
}
System.out.print("\n");
}
What is the logic behind using it for multiple months and whitespaces. I welcome all help, but please DO NOT GIVE ME SOURCE CODE. I want the satisfaction of getting this done with code I've written, and like I said, this is also an assignment and I won't really learn from copying and pasting code. Just throw me a bone about the logic I need to use. I can work in all other conditionals for special cases. Thanks guys.
Ok, you need to manage something which varies between a fixed set of values, so you basically need a way to access these variable data from within a loop.
The best tool to fullfil this problem is probably an array.
If you store inside an array, for example the duration of the months you will be able to access them in a straightforward way (through an index) so that you won't need any conditional chain, you will just need the index of the current month, eg monthDurations[i] == 31.
If you want to structure everything better you could define your own Month class or Day class or whatever you need to keep track of printing issues (eg white spaces or names) so that everything will be easily encapsulated and maintainable.
I would write a function to display one month with parameters: dayOfWeek, numberOfDays, [name, firstDayOfWeek]
dayOfWeek - what day of week is 1st day of the month
numberOfDays - number of days in this month
optional parameters You may implement if You like
name - name of the month
firstDayOfWeek - some calendars use Sundays other use Mondays as first day, if You like to have this flexibility You can implement this as well.
And the logic is simple You can do with just one loop that would iterate numberOfDays+dayOfWeek-1 times.
Inside You just need to check for end of week to make new lines and display empty spaces dayOfWeek-1 times in first week.

Categories

Resources