how to print an array elements index position - java

let say I have an array of 31 element each holds expenses of a day of January for example; assuming that I don't have any expenses in certain days.
how can print the element and the index or subscript of that element.
for example day 25 has $100
day 31 has $200
but it print like this
day 1 $100
day 2 $200
for(daysCounter=0; daysCounter<31; daysCounter++) {
if(januaryExpenses[daysCounter]>0) {
System.out.println(" expense for day " + (daysCounter +1) + " is $" + januaryExpenses[daysCounter]);
monthTotal=monthTotal+januaryExpenses[daysCounter];
} else {
System.out.print("");
}
}
System.out.println("Your January expenses are: $" +monthTotal);

The issue is you were insert to array $100 in 0 index not in 24 index and insert $200 in 1 index not in 30 index for that you have:
day 1 $100
day 2 $200
You need to insert data with value 0 in range 0-23 index and insert in 24 index insert $100 and so on with $200.

It seems like you are adding value only for the day which holds expenses i. e.
int[] januaryExpenses = {100,200};
instead of your array januaryExpenses must contain 31 elements. i. e.
int[] januaryExpenses = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,200};
then your code will work
int[] januaryExpenses = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,200};
for(int daysCounter=0; daysCounter<31; daysCounter++) {
if(januaryExpenses[daysCounter]>0) {
System.out.println(" expense for day " + (daysCounter +1) + " is $" + januaryExpenses[daysCounter]);
monthTotal=monthTotal+januaryExpenses[daysCounter];
} else {
System.out.print("");
}
}
System.out.println("Your January expenses are: $" +monthTotal);

Related

Trying to change a loop to a recursive method. Having some toruble

I need to include recursion into my final project. It was recommended to me to simply change one of my loops to a recursive method. Here's what I have so far. It returning a value of 0 every time.
public static double GetCostTotal(Liquor[] inv, int index) {
if ( index >= inv.length) return 0;
else return GetCostTotal(inv, index + 1);
}
Here's where I call it in my main method:
//beer. regular 1d array
System.out.println("\nNow for beer. How many beers are you taking inventory of?: ");
int sizeBeers = keyboard.nextInt();
Beer[] invBeers = new Beer[sizeBeers];
for (int i = 0; i < invBeers.length; i++) {
invBeers [i] = new Beer();
System.out.println("Enter product name: ");
invBeers [i].setLiquorName(keyboard.next());
System.out.println("Enter the count: ");
invBeers [i].setLiquorCount(keyboard.nextDouble());
System.out.println("Enter the cost: ");
invBeers [i].setLiquorCost(keyboard.nextDouble());
}
//calls GetCostTotal method and passes invBeers array
double beerCost = GetCostTotal(invBeers, sizeBeers);
System.out.println("The total cost of the beer inventory is: $" + beerCost);
I'm still trying to find my own solution but obviously looking for some help from you guys too. Thanks!
Just add the total cost of the current item and the result of the recursive call:
public static double GetCostTotal(Liquor[] inv, int index) {
if (index >= inv.length) return 0;
else return (inv.getLiquorCount() * inv.getLiquorCost()) + GetCostTotal(inv, index + 1);
}
Note: this is not tail recursive, and, anyway, Java doesn't optimize tail calls, so if your array is too long, you'll get a StackOverflowError.
If you modify it to use an accumulator, as in hfontanez's answer, and write it in a language and on a platform that does proper tail call elimination, it will not overflow. Hopefully one day Java will add TCO/TCE.
Your recursive method should be something like this:
public static double GetCostTotal(Liquor[] inv, int index, double total) {
if (index >= inv.length)
return total;
else
total = inv[index].amount() * inv[index].cost();
return GetCostTotal(inv, index + 1, total);
}
You can see that total is a parameter passed to the function so that you could effectively accumulate the sum of the costs. Otherwise, you will overwrite the amount with each call. Second, the else clause is performing the necessary calculation.
Lastly, your initial call was triggering the default (base) case because you were passing the length of the array instead of starting at zero.
double beerCost = GetCostTotal(invBeers, 0, 0);
Since your recursive call is incrementing index by one, you need to pass zero for the index and zero for the total.
If you do this, you should get the right result. This is my sample input and result:
Now for beer. How many beers are you taking inventory of?:
3
Enter product name:
Bud
Enter the count:
1
Enter the cost:
2
Enter product name:
Miller
Enter the count:
2
Enter the cost:
3
Enter product name:
Michelob
Enter the count:
3
Enter the cost:
4
The total cost of the beer inventory is: $20.0
You can see that for the first iteration the cumulative cost is 2.00 (12), for the second is 6.00 (23), and for the last is 12.00 (3*4), which totals 20.00 (2 + 6 + 12)
NOTE: I created a Java record for Beer instead of a conventional class. That's why the methods I am calling in GetCostTotal are cost() and amount(). You will need to change them to match your correct method names OR change Liquor and Beer to be Java records which I HIGHLY recommend if you are using the latest Java.
Solution here. Wasn't performing necessary calculations and was calling the method incorrectly.
public static double GetCostTotal(Liquor[] inv, int index, double totalCost) {
if ( index >= inv.length) return totalCost;
else totalCost = inv[index].getLiquorCount()*inv[index].getLiquorCost();
return GetCostTotal(inv, index + 1, totalCost);
}
double beerCost = GetCostTotal(invBeers, 0, 0);
System.out.println("The total cost of the beer inventory is: $" + beerCost);

Fairness in Optaplanner, but with hours instead of shifts

Im having some trouble with my fairness constraint, I want to make sure employees get:
Even amount of shifts during weeks.
Even amount of shifts in total.
Basically I want to avoid that fairness is only checking weeks (so that if there's 2 extra shifts, it won't be the same two employees getting those every week, potentially)
And I want to avoid fairness checking only the total (so that maybe one employee get much more shifts one week, then none the next, but overall theyd all still get even hours)
So I tried to follow what the docs for Optaplanner said in regards to a fairness constraint, and made two constraints for that, but unlike the docs preview that uses shifts, I need mine to be estimated in hours... So now, my code:
public int accumulateFairnessInHoursPerEmployeePerWeek(Week week)
{
//System.out.println("WEEK FAIRNESS CONSTRAINT:");
int actualWorkload = 0;
int totalAssignmentsDuringWeek = 0;
for(Employee emp : getEmployees())
{
List<Assignment> assignmentsForEmployeeDuringWeek = new ArrayList<>();
for(Assignment currentAss : getAssignmentsForSpecificWeek(week))
{
if(currentAss.getEmployee() == emp)
{
assignmentsForEmployeeDuringWeek.add(currentAss);
}
}
totalAssignmentsDuringWeek += getDurationForAssignments(assignmentsForEmployeeDuringWeek)/3600;
actualWorkload += (int) Math.pow(getDurationForAssignments(assignmentsForEmployeeDuringWeek)/3600, 2);
//System.out.println(emp.getName() + " has " + getDurationForAssignments(assignmentsForEmployeeDuringWeek)/3600 + " hours. Score: " + actualWorkload + " total: " + actualWorkload + " " + ass.getShift().getStartDate());
}
int idealWorkLoad = (int) Math.pow(totalAssignmentsDuringWeek, 2)/getEmployees().size();
//System.out.println("IDEAL: " + idealWorkLoad + " ACTUAL: " + actualWorkload + " FAIRNESS: " + (actualWorkload -idealWorkLoad));
return (actualWorkload - idealWorkLoad);
}
public int accumulateFairnessInHoursPerEmployeeInTotal()
{
System.out.println("TOTAL FAIRNESS CONSTRAINT:");
int actualWorkload = 0;
int totalDuration = 0;
for(Employee emp : getEmployees())
{
List<Assignment> assignmentsForEmployee = new ArrayList<>();
for(Assignment currentAss : getAssignments())
{
if(currentAss.getEmployee() == emp)
{
assignmentsForEmployee.add(currentAss);
}
}
totalDuration += getDurationForAssignments(assignmentsForEmployee)/3600;
actualWorkload += (int) Math.pow(getDurationForAssignments(assignmentsForEmployee)/3600, 2);
System.out.println(emp.getName() + " has " + getDurationForAssignments(assignmentsForEmployee)/3600 + " hours. Score: " + actualWorkload);
}
int idealWorkLoad = (int) Math.pow(totalDuration, 2)/getEmployees().size();
System.out.println("IDEAL: " + idealWorkLoad + " ACTUAL: " + actualWorkload + " FAIRNESS: " + (actualWorkload - idealWorkLoad));
return (actualWorkload - idealWorkLoad);
}
And here's the drools:
rule "EvenWorkloadPerEmployeeTotal"
when
$service : Service
(
$service.accumulateFairnessInHoursPerEmployeeInTotal() != 0
)
then
if(isDroolActivated(kcontext.getRule().getName(), $service))
{
setDroolRating(scoreHolder, kcontext, $service.getDroolStrength(drools), $service.accumulateFairnessInHoursPerEmployeeInTotal());
}
end
rule "EvenWorkloadPerEmployeePerWeek"
when
$week : Week()
$service : Service
(
$service.accumulateFairnessInHoursPerEmployeePerWeek($week) != 0
)
then
if(isDroolActivated(kcontext.getRule().getName(), $service))
{
setDroolRating(scoreHolder, kcontext, $service.getDroolStrength(drools), $service.accumulateFairnessInHoursPerEmployeePerWeek($week));
}
end
It seemingly works most of the time, especially in smaller datasets... However, when I use a bigger dataset...
This is my results:
A has 76.0 hours. Score: 5776
B has 118.0 hours. Score: 19700
C has 76.0 hours. Score: 25476
D has 83.0 hours. Score: 32365
E has 88.0 hours. Score: 40109
F has 72.0 hours. Score: 45293
G has 68.0 hours. Score: 49917
H has 64.0 hours. Score: 54013
I has 96.0 hours. Score: 63229
J has 94.0 hours. Score: 72065
K has 92.0 hours. Score: 80529
L has 67.0 hours. Score: 85018
M has 98.0 hours. Score: 94622
N has 95.0 hours. Score: 103647
O has 101.0 hours. Score: 113848
P has 90.0 hours. Score: 121948
Q has 93.0 hours. Score: 130597
R has 108.0 hours. Score: 142261
S has 124.0 hours. Score: 157637
T has 116.0 hours. Score: 171093
IDEAL: 157560 ACTUAL: 171093 FAIRNESS: 13533
The numbers go pretty high...
And I doubt anyone finds it fair that G and H gets only 64-68 hours, but S must work for 124 hours
I'm wondering if theres another/better way to estimate fairness when using time instead of shifts to calculate fairness?
EDIT: Probably worth noting that I tried with days as well, but the numbers seemed far too small using those, it was like it didn't care much for a single day too much on one employee compared to another.
I'm using these constraints at the same time, but not with other constraints involved
Take a look at the tennis example, specifically this line.
rule "fairAssignmentCountPerTeam"
when
accumulate(
$t : Team()
and accumulate(
TeamAssignment(team == $t);
$assignmentCount : count() // This could be a sum of hours too
);
$result : loadBalance($assignmentCount)
)
then
scoreHolder.addMediumConstraintMatch(kcontext, - (int) $result.getMeanDeviationSquaredSumRootMillis());
end

Rising tuition cost after ten years

Suppose that the tuition for a university is $10,000 this year and increases 5% every year. In one year, the tuition will be $10,500. Write a program that computes the tuition in ten years and the total cost of four years' worth of tuition after the tenth year.
I can calculate the tenth year tuition easily enough. What has me stumped is how to add the unique tuition values at years 11, 12, 13 and 14.
double Fee = 10000;
double Year = 1;
double TotalFee;
double Rate = 5;
double TotalCost = 15000 + 15500 + 16000 + 16500;
System.out.println("Year " + " Total Fee ");
System.out.println();
while (Year <= 14) {
TotalFee = Fee + ((Fee * ((Year * Rate) - Rate)) / 100);
System.out.println(Year + " " + " "+ TotalFee);`
Year++;
}
System.out.println("Total cost tuition of 4 years starting 10 years from now is " + TotalCost);
The last while loop is my attempt at adding the 4 years. How could I pull out the unique values of TotalCost at iterations 11 to 14 and add them?
Since you want to increase the amount 5% every year, instead of having rate = 5
You should have rate = 1.05.
With the rate as 1.05 you can do this
FeeAtYear1 = 10000*1.05^0 = 10000
FeeAtYear2 = 10000*1.05^1 = 10500
FeeAtYear3 = 10000*1.05^2 = 11025
FeeAtYear4 = 10000*1.05^3 = 11576.25
...
FeeAtYear10 = 10000*1.05^9 = ~16288.95
You don't even need a while loop.
TotalCost = 10000 *1.05^10 + 10000 *1.05^11 + 10000 *1.05^12 + 10000 *1.05^13;

Use Math.random() to display percentage number in Java

Currently coding simple program. I want to display percentage of each visit to the store in 52 weeks. For example, "In 52 weeks store number 1 was inspected 20%".
Here is the code so far.
public class StoreSelection {
public static void main(String[] args) {
for( int i=1; i<=52;i++){
int randomSelection = 1+(int)(Math.random()*4);
System.out.println(i+" week"+" Store number "+randomSelection+" will be inspected");
}
// here should be stated "In 52 weeks store number 1 was visited (number of percentage)
// and then below "In 52 weeks store number 2 was visited (number of percentage)
//and same for number 3 and 4.
}
}
You should use an int array to store the number of selections each store received.
public static void main(String[] args) {
int[] storeVisits = new int[4];
for (int i = 1; i <= 52; i++) {
int randomSelection = 1 + (int) (Math.random() * 4);
storeVisits[randomSelection - 1]++; // randomSelection -1 is used because arrays start at 0
System.out.println(i + " week" + " Store number " + randomSelection + " will be inspected");
}
for (int i = 0; i < storeVisits.length; i++) {
System.out.println("In 52 weeks store number " + (i + 1) + " was visited "
+ ((storeVisits[i] * 100) / 52) + "%");
}
}
which outputs (will change each time):
1 week Store number 4 will be inspected
2 week Store number 3 will be inspected
3 week Store number 3 will be inspected
4 week Store number 2 will be inspected
5 week Store number 3 will be inspected
6 week Store number 3 will be inspected
7 week Store number 3 will be inspected
8 week Store number 2 will be inspected
9 week Store number 2 will be inspected
10 week Store number 1 will be inspected
11 week Store number 3 will be inspected
12 week Store number 4 will be inspected
13 week Store number 4 will be inspected
14 week Store number 4 will be inspected
15 week Store number 1 will be inspected
16 week Store number 2 will be inspected
17 week Store number 3 will be inspected
18 week Store number 4 will be inspected
19 week Store number 4 will be inspected
20 week Store number 3 will be inspected
21 week Store number 4 will be inspected
22 week Store number 1 will be inspected
23 week Store number 2 will be inspected
24 week Store number 1 will be inspected
25 week Store number 4 will be inspected
26 week Store number 4 will be inspected
27 week Store number 2 will be inspected
28 week Store number 2 will be inspected
29 week Store number 2 will be inspected
30 week Store number 1 will be inspected
31 week Store number 1 will be inspected
32 week Store number 4 will be inspected
33 week Store number 4 will be inspected
34 week Store number 4 will be inspected
35 week Store number 1 will be inspected
36 week Store number 3 will be inspected
37 week Store number 1 will be inspected
38 week Store number 2 will be inspected
39 week Store number 1 will be inspected
40 week Store number 4 will be inspected
41 week Store number 1 will be inspected
42 week Store number 4 will be inspected
43 week Store number 1 will be inspected
44 week Store number 2 will be inspected
45 week Store number 1 will be inspected
46 week Store number 1 will be inspected
47 week Store number 1 will be inspected
48 week Store number 3 will be inspected
49 week Store number 4 will be inspected
50 week Store number 4 will be inspected
51 week Store number 4 will be inspected
52 week Store number 4 will be inspected
In 52 weeks store number 1 was visited 26%
In 52 weeks store number 2 was visited 19%
In 52 weeks store number 3 was visited 19%
In 52 weeks store number 4 was visited 34%
Hope this helps.
public class StoreSelection {
public static void main(String[] args) {
int weeks = 52;
int storeCount = 4;
int[] stores = new int[storeCount];
for (int i = 0; i < weeks; i++) {
int randomSelection = 1 + (int) (Math.random() * storeCount);
System.out.println((i+1) + " week: " + " Store number " + randomSelection
+ " will be inspected");
stores[randomSelection-1]++;
}
for (int i = 0; i < storeCount; i++) {
System.out.println("Store " + (i+1) + " was visited "
+ (stores[i] / 52.0 * 100.0) + "% times");
}
}
}

How do I add String elements from a text file into an ArrayList?

The text file contains numbers separated by commas (ex. 458.58, 1598.45...).
I want to add an entire line from the text file into an ArrayList.
Here is my code so far:
// to calculate final output
ArrayList<String> weeklySales = new ArrayList<String>(7);
// week 1 sales
while(file.hasNext()) {
weeklySales.add(file.nextLine());
System.out.println("I ran!");
}
System.out.println(weeklySales);
EDIT: Sorry my question wasn't clear. My question is after running this code, it adds ALL the elements of the ENTIRE text file into my array, BUT I need to only add 1 LINE to its own individual ArrayList. So in total I will have as many array lists as there are lines of text in the file.
This is code, you can use :
String line = "458.58, 1598.45";
String array[] = line.split(", ");
Changing from String to double is possible by this way :
Double.valueOf(array[i]);
Changing array into list can be done with this :
ArrayList<String> list = new ArrayList<>();
list.addAll(Arrays.asList(array));
I finally got it working. I realized that the most convenient method for working with individual lines and separating individual numbers from the text file was using StringTokenizer. Here is the fully working code, all you will need is the text file, which is named 'SalesData.txt' and mine includes the following 3 lines:
1245.67,1490.07,1679.87,2371.46,1783.92,1461.99,2059.77
2541.36,2965.88,1965.32,1845.23,7021.11,9652.74,1469.36
2513.45,1963.22,1568.35,1966.35,1893.25,1025.36,1128.36
This program outputs the following:
-Total sales for each week
-Daily average for each week
-Total sales of all the weeks
-Average weekly total
-The week with the highest sales
-The week with the lowest sales
DecimalFormat formatter = new DecimalFormat("#0.00");
// create file object
File salesData = new File("SalesData.txt");
// open file
Scanner file = new Scanner(salesData);
// declare 2 dimensional array
double[][] weeklySales = new double[3][7];
// loop to initialize token
int row = 0;
while(file.hasNext()) {
// initialize token
String line = file.nextLine();
StringTokenizer tokens = new StringTokenizer(line, ",");
// fill columns and rows
int col = 0;
while(tokens.hasMoreTokens()) {
// convert to double and assign to token
weeklySales[row][col] = Double.parseDouble(tokens.nextToken());
// move up 1 column
col++;
}
// move down 1 row
row++;
}
// calculate weekly sales
double week1Sales = 0, week2Sales = 0, week3Sales = 0;
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 5; j++) {
double daily = weeklySales[i][j];
if(i == 0)
week1Sales += daily;
else if(i == 1)
week2Sales += daily;
else if(i == 2)
week3Sales += daily;
}
}
// week 1 sales
System.out.println("Week 1 total sales: $" +formatter.format(week1Sales));
// week 2 sales
System.out.println("Week 1 total sales: $" +formatter.format(week2Sales));
// week 3 sales
System.out.println("Week 1 total sales: $" +formatter.format(week3Sales));
// average daily for week 1
System.out.println("Daily average for week 1: $" +formatter.format(week1Sales / 7));
// average daily for week 2
System.out.println("Daily average for week 2: $" +formatter.format(week2Sales / 7));
// average daily for week 3
System.out.println("Daily average for week 3: $" +formatter.format(week3Sales / 7));
// total for all weeks
double weeklyTotal = week1Sales + week2Sales + week3Sales;
System.out.println("Total sales of all the weeks: $" +formatter.format(weeklyTotal));
// average weekly sales
System.out.println("Average weekly total: $" + formatter.format(weeklyTotal / 3));
// week number with highest sales
if(week1Sales > week2Sales)
if(week1Sales > week3Sales)
System.out.println("The week with the highest sales is week 1.");
else
System.out.println("The week with the highest sales is week 3.");
else if(week2Sales > week3Sales)
if(week2Sales > week1Sales)
System.out.println("The week with the highest sales is week 2.");
else
System.out.println("The week with the highest sales is week 1.");
else
System.out.println("The week with the highest sales is week 3.");
// week number with the lowest
if(!(week1Sales > week2Sales))
if(!(week1Sales > week3Sales))
System.out.println("The week with the lowest sales is week 1.");
else
System.out.println("The week with the lowest sales is week 3.");
else if(!(week2Sales > week3Sales))
if(!(week2Sales > week1Sales))
System.out.println("The week with the lowest sales is week 2.");
else
System.out.println("The week with the lowest sales is week 1.");
else
System.out.println("The week with the lowest sales is week 3.");

Categories

Resources