Unable to calculate discount - java

Hey everyone so I'm new to programming and recently I've been introduced to array's I've been having some problems in my current project. Essentially I am getting an array out of bounds exception when trying to calculate the discount price (afterDiscount located at the bottom) however when I run the program I get this error. I'm not sure how to fix it as I have not dealt with arrays before.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at StarterJ52PartPriceDiscount.main(StarterJ52PartPriceDiscount.java:108)
import java.io.*;
import java.util.*;
public class StarterJ52PartPriceDiscount
{
public static void main(String[] args) throws FileNotFoundException
{
// Constants
final int MAX = 30; // max records on parts.dat
final int SENTINEL = 999;
// File Objects - Parts and Trans files
Scanner inPartsFile = new Scanner(new FileReader("parts.dat"));
Scanner inTransFile = new Scanner(new FileReader("trans.dat"));
// Part file Variables
int stkPartNo;
double stkPartPrice; // ???
// Tx file Variables
int txPartNo;
int txQuantity;
int txDiscountCode;
// Arrays
int[] partNos = new int[MAX];
double[] prices = new double[MAX];
int[] discounts = {0,5,10,15,20,25,30,40,50}; // Discount Percentages
// Other Variables
Scanner console = new Scanner(System.in);
int recCount; // no records on file
int cnt, foundPosition,i,pos; // index
double beforeDiscount, afterDiscount, totalDiscount, cost;
boolean found;
// Initialise
recCount = 0;
foundPosition = 0;
totalDiscount = 0;
found = false;
pos =-1;
// Output Part No and Prices (for)
System.out.println("Part No Part Price");
for(i=0; i <MAX; i++)
{
stkPartNo = inPartsFile.nextInt();
stkPartPrice = inPartsFile.nextDouble();
//System.out.printf("%2d %4.2f %n",stkPartNo,stkPartPrice );
partNos[i] = stkPartNo;
prices[i] = stkPartPrice;
System.out.printf("%6d %7.2f %n",partNos[i],prices[i]);
}//for
// Initial Tx read of first record
txPartNo=inTransFile.nextInt();
System.out.println("Part Quantity Disc Code");
while(txPartNo != SENTINEL)
{
txQuantity = inTransFile.nextInt();
txDiscountCode = inTransFile.nextInt();
System.out.printf("%4d %4d %4d %n",txPartNo,txQuantity,txDiscountCode );
txPartNo=inTransFile.nextInt();
}//While
// Verify Tx trans.dat contents (initially)
inTransFile.close();
inTransFile = new Scanner(new FileReader("trans.dat"));
System.out.println("xxxxxxx");
txPartNo=inTransFile.nextInt();//initial Read
while(txPartNo != SENTINEL)
{
txQuantity = inTransFile.nextInt();
txDiscountCode = inTransFile.nextInt();
System.out.printf("%4d %4d ",txPartNo,txQuantity );
found = false;
pos = -1;
while (pos < partNos.length -1 && found == false)
{
++pos;
if (partNos[pos] == txPartNo){
found = true;
}
else if (partNos[pos] > txPartNo){ // Ordered
pos = partNos.length; // break;
}
} // inner while
if (found) { // == true
beforeDiscount = prices[pos];
//Throws out of bounds exeption
afterDiscount = beforeDiscount - (beforeDiscount * discounts[txDiscountCode]);
System.out.printf("%4.2f %n",beforeDiscount);
System.out.printf("%4.2f %n",afterDiscount);
}
else {
System.out.println("NOT Found");
}//if
txPartNo=inTransFile.nextInt();//Sub Read
}//While
} // main
}

ThankYou for your comments I was able to rectify the problem, my discount array was beginning at position 1 rather than position 2, therefore, cause the out of bounds exception
changed the code from this
afterDiscount = beforeDiscount - (beforeDiscount * discounts[txDiscountCode]);
to this
afterDiscount = beforeDiscount - (beforeDiscount * discounts[txDiscountCode-1]);

Related

Running my world generation code ends up in 2 or more ArrayIndexOutOfBoundsExceptions

So I'm coding my text-based game with world generation and my friend coded the world generation. He's away right now so I have to ask this.
The code should generate an array with the X and Y positions of chests that spawn in random positions. The packages used are: java.util.Scanner,
java.util.Arrays,
java.util.Random,
Class is declared but I'm not including it in this snippet.
The Code for the method worldgen():
static double[] worldgen() {
//coded by *my friend, name censored*
int random_int_1 = 0;
int random_int_2 = 0;
int x;
int y;
int chest_x;
int chest_y;
double[] chest_x_values;
double[] chest_y_values;
int mineral_x;
int mineral_y;
// chest_x_and_y_values[something (or else)] = chest_x_values[something];
// chest_x_and_y_values[something else] = chest_y_values[something];
Random rand1 = new Random();
int num_of_chests = rand1.nextInt(100);
chest_x_values = new double[num_of_chests];
chest_y_values = new double[num_of_chests];
while (random_int_1 <= num_of_chests)
{
Random rand2 = new Random();
chest_x = rand2.nextInt(301);
System.out.println(chest_x);
chest_x_values[random_int_1] = chest_x;
System.out.println(Arrays.toString(chest_x_values));
if(random_int_1 <= num_of_chests) {
random_int_1++;
System.out.println(random_int_1);
}
}
while (random_int_2 <= num_of_chests)
{
Random rand3 = new Random();
chest_y = rand3.nextInt(301);
chest_y_values[random_int_2] = chest_y;
random_int_2 = random_int_2 + 1;
}
int random_int_3 = num_of_chests;
random_int_1 = 0;
random_int_2 = 0;
double[] chest_x_and_y_values = new double[random_int_3 = random_int_3*2+1];
while (random_int_1 <= random_int_3) {
chest_x_and_y_values[random_int_1] = chest_x_values[random_int_1];
random_int_1 = random_int_1 + 1;
}
chest_x_and_y_values[random_int_1+1] = -1;
while (random_int_2 <= random_int_3) {
chest_x_and_y_values[random_int_1 + 1 + random_int_2] = chest_y_values[random_int_2];
random_int_2 = random_int_2 + 1;
}
return chest_x_and_y_values;
}
public static void main(String[] args) {
//coded by EnZon3
Scanner uIn = new Scanner(System.in);
System.out.println("-------------------------------");
System.out.println(" *game name censored* ");
System.out.println(" 1: Generate new world.. ");
System.out.println(" 2: Generate w/ custom seed.. ");
System.out.println(" 3: See world data ");
System.out.println(" 4: Exit ");
System.out.println("-------------------------------");
int option = uIn.nextInt();
if (option > 4) {
System.err.println("Error 0x1: Not an option");
}
while (option != 4) {
if (option == 1) {
double[] world = worldgen();
System.out.println(Arrays.toString(world));
}
}
}
The error I get is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 77 out of bounds for length 77 at
.worldgen(.java:35) at .main(.java:86)
I've tried tweaking the values but that didn't work
while (random_int_1 <= num_of_chests)
This should be < (strictly less than), remember arrays are 0 indexed.
while (random_int_2 <= num_of_chests)
Same thing here
while (random_int_1 <= random_int_3) {
chest_x_and_y_values[random_int_1] = chest_x_values[random_int_1];
random_int_1 = random_int_1 + 1;
}
random_int_3 is 2 * num_of_chests +1, and chest_x_values is a list of length num_of_chests. In this part, random_int_1 can go all the way up to 2 * num_of_chests +1 which is higher than chest_x_values.

Fastest way to find all cycles in a big directed graph

I have to find all the cycles in a directed graph where every node has to only go out to 1 node but it can have more than one come in towards it and print all the nodes that are in a cycle.
Is there anyway I can make [my code][1] run faster?
right now it runs 100k nodes at about 4s but the time-limit is 1.5s
import java.io.*;
import java.util.*;
public class Main {
public static void main (String[] args) throws IOException {
long startTime = 0;
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(System.out));
int numOfPeople = Integer.parseInt(input.readLine());
StringTokenizer following = new StringTokenizer(input.readLine(), " ");
startTime = System.nanoTime();
int[] people = new int[numOfPeople], // index -> personID, value -> personID's friend
winningPotentials = new int[numOfPeople]; // index -> personID, value -> personID's winningPotential
Arrays.fill(winningPotentials, 50);
// adding followings of people
for (int i = 0 ; i < numOfPeople ; i++) {
people[i] = Integer.parseInt(following.nextToken()) - 1;
}
/*
SETTING WINNER POTENTIALS
*/
int numOfWinners = 0;
for (int person : people) {
if (winningPotentials[person] == 50) {
Deque<Integer> path = new ArrayDeque<>();
path.addLast(person);
while (true) {
int friend = people[person];
if (path.contains(friend)) {
// all those in a friend group are winningPot = 100
while (path.getLast() != friend) {
if (winningPotentials[path.peekLast()] != 100) {
numOfWinners++;
winningPotentials[path.peekLast()] = 100;
}
path.removeLast();
}
if (winningPotentials[path.peekLast()] != 100) {
numOfWinners++;
winningPotentials[path.peekLast()] = 100;
}
path.removeLast();
break;
}
// if friend hasn't been checked before, repeat
else {
path.addLast(friend);
person = friend;
}
}
// anyone in the path that wasnt in a friend group is winnerPot=0
for (int person2 : path)
winningPotentials[person2] = 0;
}
}
/*
PRINTING THE RESULTS
*/
StringBuilder sb = new StringBuilder();
sb.append(numOfWinners + "\n");
// print each winner
for (int i = 0 ; i < winningPotentials.length ; i++)
if (winningPotentials[i] == 100)
sb.append((i + 1) + " ");
sb.append("\nExecution Time ->\t" + ((System.nanoTime() - startTime) / 1000000) + "ms");
output.write(sb.toString());
output.flush();
output.close();
}
}
Why do you need a BufferedWriter ? Can you just not do a System.out.println(sb.toString()) ?
This can be implemented as a modified BFS algorithm.
Difference is what whenever you see a point that has already been added to the queue, and isn't the point before the one you were just at, you have found a cycle. So when you add points to the queue you add the current path to that point instead of just the point, but you also add the adjacent point (the last on the path) to a list of already found points.
I would probably wait to calculate the winning Potentials until you have found all the cycles.

Why does my method overwrite positions in my array

So I have this method here
while(oMenu == 1 || oMenu == 2){
oMeny = Kbd.readInt("\nClick 1 to make an account\nClick 2 to login\nClick 3 to exit the program");
if(oMeny == 1){
for(int i = 0; Account[i] != null; i++){
if(Account[i] == null){
pos = i;
}
}
Account[pos] = new Account();
}
if(oMeny == 2){
String s = Kbd.readString("Input your accountnumber: ");
for(int i = 0; Account[i] != null; i++){
if(Account[i] != null && s.equals(Account[i].getAccountNumber())){
System.out.println("Welcome!");
// Here is rest of my code , the "inner" menu that works menyMetod(iMeny,mMeny);
}
else{
System.out.println("There are no accounts with that given accountnumber!");
}
}
}
}
}
I want to understand why if I access the oMeny == 1 and make 2 accounts Why I can't seem to access the first one I make but rather the latest one? It seems that somehow my array "overwrites" the first empty position. Basically I want to find the first empty position in my array, so in the first case it's always index 0 and then the next time I make an account again, it should be Index 1 logically.
EDIT : Heres my code for the Account class
public class Account{
private int money, transactions;
private String AccountNumber;
public Account(){
money = Kbd.readInt("\nHow much money do you want to put in?");
AccountNumber = Kbd.readString("\nWhat account number do you want?");
}
The error is here:
for (int i = 0; accounts[i] != null; i++) {
if (accounts[i] == null)
The for loop repeats as long i points to a non-null entry. Therefore the if-condition is never true.
This becomes quickly obvious when you run the program line by line in a debugger.
Next time please provide a complete code example that can be compiled. Your code is full of error, It took me a lot of time to fix it before I was able to execute it.
Corrected code:
import java.util.Scanner;
class Main
{
static Scanner kbd = new Scanner(System.in);
static Account[] accounts = new Account[100];
static class Account
{
//public int money;
public String accountNumber;
public Account()
{
//System.out.println("\nHow much money do you want to put in?");
//money = Kbd.nextInt();
System.out.println("\nWhat account number do you want?");
accountNumber = kbd.next();
}
}
public static void main(String[] args)
{
int oMenu = 1;
int pos = 0;
while (oMenu == 1 || oMenu == 2)
{
System.out.println("\nClick 1 to make an account\nClick 2 to login\nClick 3 to exit the program");
oMenu = kbd.nextInt();
if (oMenu == 1)
{
for (int i = 0; i<accounts.length; i++)
{
if (accounts[i] == null)
{
accounts[i] = new Account();
break;
}
}
}
if (oMenu == 2)
{
System.out.println("Input your accountnumber: ");
String s = kbd.next();
Account found=null;
for (int i = 0; i<accounts.length; i++)
{
if (accounts[i] != null && s.equals(accounts[i].accountNumber))
{
found=accounts[i];
}
}
if (found!=null)
{
System.out.println("Welcome! nr. "+found.accountNumber);
}
else
{
System.out.println("There are no accounts with that given accountnumber!");
}
}
}
}
}
Notice how I also fixed the second for-loop.
You did not show the declaration or initialization of pos, so I think it is not working how you expect because you do not go into the for loop where Account[i] is null to set pos. Try this
if(oMenu == 1){
int pos = 0;
while (Account[pos] != null && pos < Account.length)
pos++;
if (pos < Account.length)
Account[pos] = new Account();
else{
//expand array and add account or throw error
}
}

Sorting array list

public class Saleitem {
public Product product = null;
public int numberofproduct = 0;
static ArrayList<Saleitem> Saleitemarray = new ArrayList<Saleitem>();
static ArrayList<Integer[]> total = new ArrayList<Integer[]>();
//read the sales data
public static void salesData() {
String SalesDataCSV = "SalesData.csv";
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
System.out.println("\nThe Sales Data file has been opened\n");
try {
int currentcustomer = 1;
int lastcustomer = 1;
double sum = 0;
br = new BufferedReader(new FileReader(SalesDataCSV));
line = br.readLine();
System.out.println("-----------------------------------------------");
System.out.println("Sales Data File");
System.out.println("Customer ID, Product ID, Number of Units");
System.out.println("-----------------------------------------------");
while ((line = br.readLine()) != null) {
String field[] = line.split(cvsSplitBy);
if(field.length>1) {
String currentcustomerID = field[0];
String currentproductID = field[1];
String currentunitnumber = field[2];
Product currentproduct = null;
currentcustomer = Integer.parseInt(currentcustomerID);
int currentproductid = Integer.parseInt(currentproductID);
int currentproductunit = Integer.parseInt(currentunitnumber);
//-------------------------------------
// START OF PRODUCT/SALE ITEM PROCESSING
//-------------------------------------
System.out.println(currentcustomer + " , " + currentproductid + " , " + currentproductunit);
////////////////////
if (lastcustomer == currentcustomer) {
Saleitem salesItemObject = new Saleitem(currentproductid, currentproductunit,
Product.getUnitPrice(currentproductid));
Saleitemarray.add(salesItemObject);
} else {
// sale receipt date, time, etc.
Salereceipt salesReceiptObject = new Salereceipt(lastcustomer, lastcustomer,
sum, "2/20/16", (int) (Math.random() * 2000));
Salereceipt.receipt.add(salesReceiptObject);
lastcustomer = currentcustomer;
Saleitemarray.clear();
sum = 0;
}
///////////////////////////
//Find the correct product that the customer ordered
for (int i = 0; i < Product.productData.size(); i++){
if (((Product.productData).get(i)).productID == currentproductid){
currentproduct = Product.productData.get(i);
}
}
Saleitem salesItemObject = new Saleitem(currentproduct, currentproductunit);
Saleitemarray.add(salesItemObject);
boolean found = false;
//update total
for (int i = 0; i < total.size(); i++){
//total is an array of arrays =)
//in the array, index 0 is the productID
// index 1 is the total sold of that product
//Find the correct product total
if ((total.get(i))[0] == salesItemObject.product.productID){
//if we found it then we will mark found
//so that we can add in the item if it doesnt exist
//in our total array
found = true;
//increment the total number of prodcuts sold
(total.get(i))[1] += salesItemObject.numberofproduct;
}
}
if (found == false){
Integer[] array = new Integer[2];
// index 0 = product id
// index 1 = total number of products sold
array[0] = salesItemObject.product.productID;
array[1] = salesItemObject.numberofproduct;
total.add(array);
}
//-------------------------------------
// END OF PRODUCT/SALE ITEM PROCESSING
//-------------------------------------
//this is done inside of the constructor
if (currentcustomer == lastcustomer){
sum += currentproduct.productPrice * currentproductunit;
}
}
}
The Sales Data is imported from a file that has Customer_ID[0], Product_ID[1], Units_ordered[2]
I want to sort the ArrayList total by the Product_ID in ascending order. What would be the best way to do this. Im new to java so I don't know much of the syntax.
total.sort((item1, item2) -> item1.getProductId() - item2.getProductId());
You can use Collections#sort like below.
Add a getter for ProductId and you're done
Collections.sort(total, new Comparator<Saleitem>(){
#Override
public int compare(Saleitem s1, Saleitem s2) {
return s1.getProductId() - s2.getProductId();
}
});

Several errors keep occurring in eclipse

I'm trying to write a program that opens a txt file and display information from that txt file. Java is my first language, and I'm taking java as a second language class since there's no beginning java class in my school. I'm struggling with this code for about an week. Any little help would be helpful. Appreciate for your help.
It keeps saying :
Exception in thread "main"java.lang.ArrayIndexOutOfBoundsException:6
at store.Franchise.<init>(Franchise.java:10)
at store.FileIO.readData(FileIO.java:10)
at store.Driver.main(Driver.java:9)
Here is what I've got:
Sample txt file:
Day1 Day2 Day3 Day4 Day5
2541.56 2258.96 2214 2256 2154
2041.56 1758.96 1714 1756 1654
3041.56 2758.96 2714 2756 2654
3563.54 3280.94 3235.98 3277.98 3175.98
2547.21 2264.61 2219.65 2261.65 2159.65
4040.55 3757.95 3712.99 3754.99 3652.99
Store.java:
package store;
import java.io.IOException;
public class Store {
private float salesByWeek[][];
public Store() {
salesByWeek = new float[5][7];
// assign the array value at index 5, t to salesByWeek
}
public void setSaleForWeekDayIntersection(int week, int day, float sale) {
salesByWeek[week][day] = sale;
// store the sale value to SalesByWeek array at the index pointed to by week, day
// for exaample, it can be week 2 and day 3 (Wednesday)
}
float[] getSalesForEntireWeek(int week) {
// this will find the total sales for the whole week - all 5 days or 7 days including week ends Saturday and Sunday
float[] sales = new float[7];
// declare an array of type float and of size 7 - name the array as sales
for (int d = 0; d < 7; d++)
{
sales[d] = salesByWeek[week][d];
// the index d runs from 0 to 7
}
return sales;
}
float getSaleForWeekDayIntersection(int week, int day) {
return salesByWeek[week][day];
// the return value is the arraycontent pointed to by index week and day
}
float getTotalSalesForWeek(int week) {
float total = 0;
for (int d = 0; d < 7; d++)
{
total += salesByWeek[week][d];
// increment total by adding the array content salesByWeek at index week, d ( if d is the day)
}
return total;
// send the value of total back to the caller function
}
float getAverageSalesForWeek(int week) {
return getTotalSalesForWeek(week) / 7;
// divide the total sales for the whole week by 7 so that we get the average sales and return it
}
float getTotalSalesForAllWeeks() {
float total = 0; // declare a total variable of type float and initialize to 0 ( zero)
for (int w = 0; w < 5; w++)
{
total += getTotalSalesForWeek(w);
// sum up the total for the whole week and store it to the total variable
}
return total;
// return the sum computed above
}
float getAverageWeeklySales() {
return getTotalSalesForAllWeeks() / 5;
// AVERAGE for 5 days - just Monday to Friday only - excludes the week ends
}
int getWeekWithHighestSaleAmount() {
// top performing sales in the whole week
int maxWeek = 0;
float maxSale = -1;
for (int w = 0; w < 5; w++)
// run the for loop from 0 to 5 in steps of 1
{
float sale = getTotalSalesForWeek(w);
// first store the total sales in to the sale variable of type float
if (sale > maxSale)
{ // if at all if we find any amount greater than the max sale then replace max sale with the new sale amount
// and also note down the contributor - in the sense that which w ( week) achieved top sales
maxSale = sale;
maxWeek = w;
}
}
return maxWeek;
}
int getWeekWithLowestSaleAmount() {
int minWeek = 0;
float minSale = Float.MAX_VALUE;
for (int w = 0; w < 5; w++)
{
float sale = getTotalSalesForWeek(w);
if (sale < minSale)
{
minSale = sale;
minWeek = w;
}
}
// comments are same as the top sales except in reverse order
// first store an arbitary minimum sale figure
// then compare each running week's vaue with the lowest
// if at all when we encounter any value lower than the preset value then replace it
return minWeek;
// finally return the minimum value in that week
}
public void analyzeResults() {
for (int w = 0; w < 5; w++) // run the for loop from 0 to 5
{
System.out.printf("---- Week %d ----\n", w); // print a title decoration
System.out.printf(" Total sales: %.2f\n", getTotalSalesForWeek(w)); // display or print out the total sales summed earlier in called function
System.out.printf(" Average sales: %.2f\n", getAverageSalesForWeek(w)); // display the average sales figure
}
System.out.printf("\n");
System.out.printf("Total sales for all weeks: %.2f\n", getTotalSalesForAllWeeks()); // print sum of the sales for the entire week
System.out.printf("Average weekly sales: %.2f\n", getAverageWeeklySales()); // print weekly average sales
System.out.printf("Week with highest sale: %d\n", getWeekWithHighestSaleAmount()); // print highest performing or top sales
System.out.printf("Week with lowest sale: %d\n", getWeekWithLowestSaleAmount()); // print lowest sales or the struggling week
}
public void setsaleforweekdayintersection(int week, int day, float f) {
}
}
Franchise.java:
package store;
public class Franchise {
private Store stores[];
public Franchise(int num) { // now for a franchise store
stores = new Store[num]; // instantiate an array object of type class Store
// the class is Store
// the objects are named as stores
for(int i=0; i<=num; i++) stores[i] = new Store();
}
public Store getStores(int i) { // GETTER display or return values
return stores[i];
}
public void setStores(Store stores, int i) { // setter assign values
this.stores[i] = stores;
}
}
FileIO.java:
package store;
import java.io.*;
import java.util.StringTokenizer;
public class FileIO {
// Franchise readData(String filename)
Franchise readData(String filename, int numstores) {
Franchise f1 = new Franchise(numstores);
boolean DEBUG = true;
int ctr = 0;
// open the file
// read the line
// parse the line - get one value
// and set it in the correct location in 2 d array
try {
FileReader file = new FileReader(filename); // file is equivalent to a file pointer in c/c++
BufferedReader buff = new BufferedReader(file); // buffered reader will read a chunk in to the variable buff
boolean eof = false;
while (!eof) {
String line = buff.readLine();
ctr++;
if (line == null)
eof = true;
else {
if (DEBUG)
System.out.println(line);
if (ctr > 1) {
StringTokenizer a = new StringTokenizer(line);
for (int week = 0; week < 5; week++) {
for (int day = 0; day < 7; day++) {
String l = a.nextToken();
float f = Float.parseFloat(l); // parseFloat will store to variable f of type float
f1.getStores(ctr - 2)
.setsaleforweekdayintersection(week,
day, f);
if (DEBUG)
System.out.print("f" + f + " ");
}
}
}
}
}
} catch (IOException f2) {
}
return f1;
}
}
Driver.java:
package store;
public class Driver
{
public static void main(String[] args)
{
FileIO readdata = new FileIO();
Franchise f1 = readdata.readData("E:/Files/Salesdat.txt", 6);
System.out.println("Data read");
}
}
DriverImpl.java ( I got no idea why I need this subclass, but my tutor told me that I need this):
package store;
public class DriverImpl extends Driver {
}
I would like to change the line 10 in Franchise.java to
for(int i=0; i<num; i++) stores[i] = new Store();
Notice I removed the <= and put an = instead. Whenever dealing with array indices, one should always use the < comparator with the size as a good practice.
Valid indexes in an array are 0 to length - 1. Change <= to < like,
stores = new Store[num];
// the class is Store
// the objects are named as stores
for(int i=0; i<num; i++) stores[i] = new Store(); //stores[num] is invalid.

Categories

Resources