The following is my Brute force code for Sudoku:
public abstract class SudokuBoard
{
protected int ROWS = 9;
protected int COLS = 9;
int solutionsCounter;
double startTime;
double endTime;
String[] data = new String[8];
int puzzleNum = countTotalRows();
// data accessors
public abstract int get(int r, int c);
public abstract void set(int r, int c, int v);
// specific constraints checker, returns true even if the values are not complete
abstract boolean isRowCompatible(int r, int c);
abstract boolean isColCompatible(int r, int c);
abstract boolean isBoxCompatible(int r, int c);
// returns true if element S[r,c] is compatible, even if some values arount it are not filled
public boolean isCompatible(int r, int c)
{
for (int i=0; i<ROWS; i++)
for (int j=0; j<COLS; j++)
if(! (isRowCompatible(r, c) && isColCompatible(r, c) && isBoxCompatible(r, c)))
return false;
return true;
}
// this is the one called to solve the sudoku
public void solve()
{
//convert to seconds
startTime = System.nanoTime() / 1000000000.0;
solve(1,1);
}
// function to incorporate clues
public void incorporateClues(int[] clues)
{
for (int i=0; i<clues.length; i++)
set(clues[i]/100, (clues[i]%100)/10, clues[i]%10);
}
// the recursive backtracking function that does the hardwork
void solve(int r, int c)
{
while (((System.nanoTime() / 1000000000.0) - startTime) < 10) {
System.out.println("Time: " + ((System.nanoTime() / 1000000000.0) - startTime));
if (r<=9 && c<=9)
{
if (get(r,c) == 0)
{
for (int v=1; v<=COLS; v++)
{
set(r,c,v);
if (isCompatible(r,c))
solve((c==9)?(r+1):r, (c==9)?1:(c+1));
}
set(r, c, 0);
}
else
solve((c==9)?(r+1):r, (c==9)?1:(c+1));
}
else
{
solutionsCounter = solutionsCounter + 1;
//convert to seconds
endTime = System.nanoTime() / 1000000000.0;
// print();
}
}
}
// sample display function
void print()
{
for(int i=1; i<=ROWS; i++)
{
for (int j=1; j<=COLS; j++)
System.out.print(get(i,j));
System.out.println();
}
System.out.println("count: " + solutionsCounter);
}
void saveData (String[] data) throws java.io.IOException
{
try
{
java.io.BufferedWriter outfile = new java.io.BufferedWriter(new java.io.FileWriter("15-clue_results.csv", true));
for (int i = 0; i < data.length; i++) {
outfile.write(String.valueOf(data[i]));
outfile.append(',');
}
outfile.append('\n');
outfile.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
static int countTotalRows () {
int count = 0;
try
{
java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new java.io.FileReader("15-clue_results.csv"));
String input;
while((input = bufferedReader.readLine()) != null)
{
count = count + 1;
}
} catch (java.io.IOException e) {
e.printStackTrace();
}
return count;
}
public static void main(String []arg)
{
int numClues;
try {
java.io.BufferedReader csvFile = new java.io.BufferedReader(new java.io.FileReader("clue_set"));
String dataRow;
while ((dataRow = csvFile.readLine()) != null) {
SudokuBoard board = new SB_IntMatrix();
String[] stringSet = new String[15];
int[] PUZZLE1 = new int[15];
board.puzzleNum = board.puzzleNum + 1;
stringSet = dataRow.split(" ");
for (int i = 0; i < stringSet.length; i++) {
PUZZLE1[i] = Integer.parseInt(stringSet[i]);
}
board.incorporateClues(PUZZLE1);
for (int i = 0; i < 1; i++) {
board.solutionsCounter = 0;
board.solve();
board.data[0] = Integer.toString(board.puzzleNum);
board.data[1] = dataRow;
board.data[2] = Integer.toString(board.solutionsCounter);
board.data[3 + i] = Double.toString(board.endTime - board.startTime);
}
try
{
board.saveData(board.data);
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
csvFile.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
}
The requirement is to limit the solving time of solve(int r, int c) to only 1 hour.
To do this, I tried to put it inside a while loop while (((System.nanoTime() / 1000000000.0) - startTime) < 10) . The number 10 is to just test the code.
I understand that I looped it only 5 times in main method but, it resets back to 0 always and never stops and exceeds the limit of my loop in main.
You should use a Future:
final ExecutorService executor = Executors.newFixedThreadPool(4);
final Future<Boolean> future = executor.submit(() -> {
// Call solve here
return true;
});
future.get(60, TimeUnit.MINUTES); // Blocks
You can do something like:
Init the start date:
LocalDateTime startDateTime = LocalDateTime.now();
And check if 1 hour has elapsed:
LocalDateTime toDateTime = LocalDateTime.now();
if (Duration.between(startDateTime, toDateTime).toHours() > 0) {
// stop the execution
}
I decided to optimize the piece of code below but encounter with problem. I tried to change the ArrayList to thread-safe collection by using this discussion but unfortunately something went wrong. The code is compiling but throw the exception.
Exception in thread "main" java.lang.ClassCastException:
java.util.Collections$SynchronizedRandomAccessList cannot be cast to
java.util.ArrayList at
bfpasswrd_multi.PasswordCracker.doItMulti(PasswordCracker.java:73) at
bfpasswrd_multi.PasswordCracker.runMulti(PasswordCracker.java:60) at
bfpasswrd_multi.Test.main(Test.java:16)
Please, tell me what is wrong ?
package bfpasswrd_multi;
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
System.out.print("Type password to be cracked: ");
#SuppressWarnings("resource")
String input = new Scanner(System.in).nextLine();
PasswordCracker cracker = new PasswordCracker();
System.out.println("Multithreaded");
cracker.runMulti(input);
cracker = new PasswordCracker();
System.out.println("Finished...");
}
}
package bfpasswrd_multi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class PasswordCracker
{
String passwordToCrack;
public boolean passwordFound;
int min;
int max;
StringBuffer crackedPassword;
public void prepare(String text)
{
passwordToCrack = text;
passwordFound = false;
min = 48;
max = 57; // http://ascii.cl/
crackedPassword = new StringBuffer();
crackedPassword.append((char) (min - 1));
}
public void result()
{
System.out.println("Cracked Password is: " + crackedPassword.toString());
}
public void incrementString(StringBuffer toCrack, int min, int max)
{
toCrack.setCharAt(0, (char) ((int) toCrack.charAt(0) + 1));
for (int i = 0; i < toCrack.length(); i++)
{
if (toCrack.charAt(i) > (char) max)
{
toCrack.setCharAt(i, (char) min);
if (toCrack.length() == i + 1)
{
toCrack.append((char) min);
}
else
{
toCrack.setCharAt(i + 1, (char) ((int) toCrack.charAt(i + 1) + 1));
}
}
}
}
public void runMulti(String text)
{
prepare(text);
double time = System.nanoTime();
doItMulti();
time = System.nanoTime() - time;
System.out.println(time / (1000000000));
result();
}
public void doItMulti()
{
int cores = Runtime.getRuntime().availableProcessors();
ArrayList<Future<?>> tasks ; // How do I make my ArrayList Thread-Safe? Another approach to problem in Java?
// https://stackoverflow.com/questions/2444005/how-do-i-make-my-arraylist-thread-safe-another-approach-to-problem-in-java
tasks = (ArrayList<Future<?>>) Collections.synchronizedList(new ArrayList<Future<?>>(cores));
// ArrayList<Future<?>> tasks = new ArrayList<>(cores);
ExecutorService executor = Executors.newFixedThreadPool(cores);
final long step = 2000;
for (long i = 0; i < Long.MAX_VALUE; i += step)
{
while(tasks.size() > cores)
{
for(int w = 0; w < tasks.size();w++)
{
if(tasks.get(w).isDone())
{
tasks.remove(w);
break;
}
}
try
{
Thread.sleep(0);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
{
final long j = i;
if (passwordFound == false)
{
tasks.add(executor.submit(new Runnable()
{
public void run()
{
long border = j + step;
StringBuffer toCrack = new StringBuffer(10);
toCrack.append(constructString3(j, min, max));
for (long k = j; k < border; k++)
{
incrementString(toCrack, min, max);
boolean found = toCrack.toString().equals(passwordToCrack);
if (found)
{
crackedPassword = toCrack;
passwordFound = found;
break;
}
}
}
}));
}
else
{
break;
}
}
}
executor.shutdownNow();
}
public String constructString3(long number, long min, long max)
{
StringBuffer text = new StringBuffer();
if (number > Long.MAX_VALUE - min)
{
number = Long.MAX_VALUE - min;
}
ArrayList<Long> vector = new ArrayList<Long>(10);
vector.add(min - 1 + number);
long range = max - min + 1;
boolean nextLetter = false;
for (int i = 0; i < vector.size(); i++)
{
long nextLetterCounter = 0;
while (vector.get(i) > max)
{
nextLetter = true;
long multiplicator = Math.abs(vector.get(i) / range);
if ((vector.get(i) - (multiplicator * range)) < min)
{
multiplicator -= 1;
}
vector.set(i, vector.get(i) - (multiplicator * range));
nextLetterCounter += multiplicator;
}
if (nextLetter)
{
vector.add((long) (min + nextLetterCounter - 1));
nextLetter = false;
}
text.append((char) vector.get(i).intValue());
}
return text.toString();
}
}
Many thanks in advance !
The issue that you're seeing is with this line:
tasks = (ArrayList<Future<?>>) Collections.synchronizedList(new ArrayList<Future<?>>(cores));
Collections.synchronizedList doesn't return an ArrayList; it returns some subclass of List - java.util.Collections$SynchronizedRandomAccessList to be exact - and I don't know anything about that class other than it's a List, but it's not an ArrayList.
The easy solution to this is to declare tasks to be a List<Future<?>>:
List<Future<?>> tasks =
Collections.synchronizedList(new ArrayList<Future<?>>(cores));
Dear community members thanks you for your comments. It seems that now my safe-thread list is working. For the people who interesting in solution I will submit the resolved code below. Also, probably I should mention that I rename task
to futures, please pay attention. Once again everybody thanks !
package bfpasswrd_multi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class PasswordCracker
{
String passwordToCrack;
public boolean passwordFound;
int min;
int max;
StringBuffer crackedPassword;
public void prepare(String text)
{
passwordToCrack = text;
passwordFound = false;
min = 48;
max = 57; // http://ascii.cl/
crackedPassword = new StringBuffer();
crackedPassword.append((char) (min - 1));
}
public void result()
{
System.out.println("Cracked Password is: " + crackedPassword.toString());
}
public void incrementString(StringBuffer toCrack, int min, int max)
{
toCrack.setCharAt(0, (char) ((int) toCrack.charAt(0) + 1));
for (int i = 0; i < toCrack.length(); i++)
{
if (toCrack.charAt(i) > (char) max)
{
toCrack.setCharAt(i, (char) min);
if (toCrack.length() == i + 1)
{
toCrack.append((char) min);
}
else
{
toCrack.setCharAt(i + 1, (char) ((int) toCrack.charAt(i + 1) + 1));
}
}
}
}
public void runMulti(String text)
{
prepare(text);
double time = System.nanoTime();
doItMulti();
time = System.nanoTime() - time;
System.out.println(time / (1000000000));
result();
}
public void doItMulti()
{
int cores = Runtime.getRuntime().availableProcessors();
// ArrayList<Future<?>> task; // HOW IT WAS
//
// tasks = (ArrayList<Future<?>>) Collections.synchronizedList(new ArrayList<Future<?>>(cores)); // HOW IT WAS
List<Future<?>> futures ; // THE SOLUTION
futures = Collections.synchronizedList(new ArrayList<Future<?>>(cores)); // THE SOLUTION
// ArrayList<Future<?>> tasks = new ArrayList<>(cores);
ExecutorService executor = Executors.newFixedThreadPool(cores);
final long step = 2000;
for (long i = 0; i < Long.MAX_VALUE; i += step)
{
while(futures.size() > cores)
{
for(int w = 0; w < futures.size();w++)
{
if(futures.get(w).isDone())
{
futures.remove(w);
break;
}
}
try
{
Thread.sleep(0);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
{
final long j = i;
if (passwordFound == false)
{
futures.add(executor.submit(new Runnable()
{
public void run()
{
long border = j + step;
StringBuffer toCrack = new StringBuffer(10);
toCrack.append(constructString3(j, min, max));
for (long k = j; k < border; k++)
{
incrementString(toCrack, min, max);
boolean found = toCrack.toString().equals(passwordToCrack);
if (found)
{
crackedPassword = toCrack;
passwordFound = found;
break;
}
}
}
}));
}
else
{
break;
}
}
}
executor.shutdownNow();
}
public String constructString3(long number, long min, long max)
{
StringBuffer text = new StringBuffer();
if (number > Long.MAX_VALUE - min)
{
number = Long.MAX_VALUE - min;
}
ArrayList<Long> vector = new ArrayList<Long>(10);
vector.add(min - 1 + number);
long range = max - min + 1;
boolean nextLetter = false;
for (int i = 0; i < vector.size(); i++)
{
long nextLetterCounter = 0;
while (vector.get(i) > max)
{
nextLetter = true;
long multiplicator = Math.abs(vector.get(i) / range);
if ((vector.get(i) - (multiplicator * range)) < min)
{
multiplicator -= 1;
}
vector.set(i, vector.get(i) - (multiplicator * range));
nextLetterCounter += multiplicator;
}
if (nextLetter)
{
vector.add((long) (min + nextLetterCounter - 1));
nextLetter = false;
}
text.append((char) vector.get(i).intValue());
}
return text.toString();
}
}
I'm new with arrays.
This program i have created is throwing an out of bounds error with every method inside of the BlueJays class.
To be honest, im not even sure if im searching through the array right. Any help would be appreciated.
Thanks
This is my main
public class Lab1 {
static final int NBPLAYERS = 11;
static final int NBMONTHS = 6;
public static void main(String[] args) {
String[] month = {"April", "May","June", "July", "August","September"};
String[] players = {"Colabello","Donaldson","Smoak","Martin","Goins","Encarnacion","Carrera","Tulowitzki","Pillar","Bautista","Travis"};
double[][] battingAvg = {
{0,.368,.300,.224,.386,.268},
{.319,.306,.269,.287,.324,.296},
{.229,.310,.213,.191,.203,.262},
{.197,.327,.239,.256,.138,.213},
{.276,.236,.172,.240,.314,.279},
{.205,.225,.303,.241,.407,.279},
{0,.302,.282,.244,.333,.231},
{0,0,0,.357,.214,.237},
{.273,.181,365,.283,.240,.323},
{.164,.295,.226,.219,.286,.293},
{.325,.189,.313,.368,0,0}};
double [][] onBase = {
{.417,.330,.286,.413,.362,.429},
{.370,.373,.322,.370,.408,.403},
{.372,.333,.275,.283,.243,.324},
{.367,.362,.329,.322,.263,.300},
{.323,.278,.221,.286,.442,.347},
{.258,.333,.382,.384,.460,.411},
{0,.357,.333,.277,.333,.313},
{0,0,0,.400,.325,.250},
{.297,.237,.380,.323,.283,.363},
{.325,.418,.388,.300,.370,.436},
{.393,.246,.313,.421,0,0}};
PlayerStats Player;
BlueJays team = new BlueJays(NBPLAYERS, NBMONTHS);
team.getHighestSingleMonthBattingAvg();
team.getHighestOnBase(5);
team.getLowestBattingAvg(6);
team.getBestMonth("Bautista");
team.getBestOverallRecord();
team.getLowestOnBase();
}
}
This is my PlayerStats which has accessor/mutator methods.
class PlayerStats {
private String name;
private int month;
private double battAvg, onBase;
public PlayerStats(String name, int month, double battingAvg, double onBase2) {
this.name = name;
this.month = month;
this.battAvg = battingAvg;
this.onBase = onBase2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public double getAvg() {
return battAvg;
}
public double getOnBase() {
return onBase;
}
public double getBoth() {
return battAvg + onBase;
}
}
And this is the class where the 2d array is created.
class BlueJays {
int nbPlayers;
int nbMonths;
int j = 0;
int highestBattingAvg;
int highestBattingMonth;
String highestBattingPlayer;
int highestOnBase;
int lowestAvg;
String lowestAvgPlayer;
int highestOverall;
String highestOverallPlayer;
int lowestOnBase;
int lowestOnBaseMonth;
String highestOnBasePlayer;
double bestOverAllMonth;
public BlueJays(int nbplayers2, int nbmonths2) {
this.nbPlayers = nbplayers2;
this.nbMonths = nbmonths2;
}
PlayerStats[][] stats = new PlayerStats[nbPlayers][nbMonths];
PlayerStats setPlayerStatsCell(PlayerStats player, int iPlayer, int iMonth) {
return player;
}
PlayerStats getHighestSingleMonthBattingAvg() {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getAvg();
if(highestBattingAvg < stats[i][j].getAvg()) {
highestBattingMonth = stats[i][j].getMonth();
highestBattingPlayer = stats[i][j].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Highest average batting player for the month " + highestBattingMonth + " is " + highestBattingPlayer);
}
}
return null;
}
PlayerStats getHighestOnBase(int month) {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][month].getOnBase();
if(highestOnBase < stats[i][month].getOnBase()) {
highestOnBasePlayer = stats[i][month].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Highest average onBase player for the month " + month + highestOnBasePlayer);
}
}
return null;
}
public PlayerStats getLowestBattingAvg(int month) {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][month].getOnBase();
if(lowestAvg > stats[i][month].getAvg()) {
lowestAvgPlayer = stats[i][month].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Lowest average batting player for the month " + month + " is " + lowestAvgPlayer);
}
}
return null;
}
PlayerStats getBestMonth(String player) {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getBoth();
if(bestOverAllMonth > stats[i][j].getAvg() && stats[i][j].getName().contains(player)) {
bestOverAllMonth = stats[i][j].getBoth();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Best month for the player " + player + " is " + bestOverAllMonth);
}
}
return null;
}
public String getBestOverallRecord() {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getBoth();
if(highestOverall < stats[i][j].getBoth()) {
highestOverallPlayer = stats[i][j].getName();
}
if (i == nbMonths) {
j++;
i = 0;
}
System.out.println("Highest overall record is " + highestOverallPlayer);
}
}
return null;
}
public PlayerStats getLowestOnBase() {
while(j < nbMonths) {
for(int i = 0; i < nbPlayers; i++) {
stats[i][j].getOnBase();
if(lowestOnBase > stats[i][j].getOnBase()) {
double lowestOnBase = stats[i][j].getOnBase();
if(lowestOnBase > 0) {
lowestAvgPlayer = stats[i][j].getName();
} else {
i++;
}
if (i == nbMonths) {
j++;
i = 0;
}
}
System.out.println("Lowest On Base is " + lowestOnBase);
}
}
return null;
}
}
Here is the exception
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at BlueJays.getHighestSingleMonthBattingAvg(BlueJays.java:42)
at Lab1.main(JonathanRoy_Lab1.java:40)
Your problem may lay here:
// ... lots of other stuff
public BlueJays(int nbplayers2, int nbmonths2) {
this.nbPlayers = nbplayers2;
this.nbMonths = nbmonths2;
}
PlayerStats[][] stats = new PlayerStats[nbPlayers][nbMonths];
If you initialize an instance of your BlueJay-class it will create the array before you set the values nbPlayers and nbMonths. So you'll have an array of the size 0 and 0.
To avoid this you have to do following:
// ... lots of other stuff
public BlueJays(int nbPlayers, int nbMonths) {
this.nbPlayers = nbPlayers;
this.nbMonths = nbMonths;
// doesn't matter if you take the parameters or fields
this.stats = new PlayerStats[nbPlayers][nbMonths];
}
Hope I helped you out :)
I don't know what the exception is but here's what I got by scanning through your code.
You never reset j so most of your function calls won't make it past the first comparison.
The function call team.getLowestBattingAvg(6); uses the index 6, but since nbMonths=6, the highest index you can use is 5 (the indices go from 0 to 5 inclusive).
I am using Comb Sort to sort out a given array of Strings. The code is :-
public static int combSort(String[] input_array) {
int gap = input_array.length;
double shrink = 1.3;
int numbOfComparisons = 0;
boolean swapped=true;
//while(!swapped && gap>1){
System.out.println();
while(!(swapped && gap==1)){
gap = (int)(gap/shrink);
if(gap<1){
gap=1;
}
int i = 0;
swapped = false;
String temp = "";
while((i+gap) < input_array.length){
numbOfComparisons++;
if(Compare(input_array[i], input_array[i+gap]) == 1){
temp = input_array[i];
input_array[i] = input_array[i+gap];
input_array[i+gap] = temp;
swapped = true;
System.out.println("gap: " + gap + " i: " + i);
ArrayUtilities.printArray(input_array);
}
i++;
}
}
ArrayUtilities.printArray(input_array);
return numbOfComparisons;
}
The problem is that while it sorts many arrays , it gets stuck in an infinite loop for some arrays, particularly small arrays. Compare(input_array[i], input_array[i+gap]) is a small method that returns 1 if s1>s2, returns -1 if s1
try this version. The string array is changed to integer array (I guess you can change it back to string version). The constant 1.3 is replaced with 1.247330950103979.
public class CombSort
{
private static final int PROBLEM_SIZE = 5;
static int[] in = new int[PROBLEM_SIZE];
public static void printArr()
{
for(int i=0;i<in.length;i++)
{
System.out.print(in[i] + "\t");
}
System.out.println();
}
public static void combSort()
{
int swap, i, gap=PROBLEM_SIZE;
boolean swapped = false;
printArr();
while ((gap > 1) || swapped)
{
if (gap > 1)
{
gap = (int)( gap / 1.247330950103979);
}
swapped = false;
for (i = 0; gap + i < PROBLEM_SIZE; ++i)
{
if (in[i] - in[i + gap] > 0)
{
swap = in[i];
in[i] = in[i + gap];
in[i + gap] = swap;
swapped = true;
}
}
}
printArr();
}
public static void main(String[] args)
{
for(int i=0;i<in.length;i++)
{
in[i] = (int) (Math.random()*PROBLEM_SIZE);
}
combSort();
}
}
Please find below implementation for comb sort in java.
public static void combSort(int[] elements) {
float shrinkFactor = 1.3f;
int postion = (int) (elements.length/shrinkFactor);
do {
int cursor = postion;
for(int i=0;cursor<elements.length;i++,cursor++) {
if(elements[i]>elements[cursor]) {
int temp = elements[cursor];
elements[cursor] = elements[i];
elements[i] = temp;
}
}
postion = (int) (postion/shrinkFactor);
}while(postion>=1);
}
Please review and let me know your's feedback.
The method "aboveAverage" in the following code is not displaying correctly and I've tried everything I can. Could someone please explain what's going wrong?
My code:
import java.util.*;
public class DailyCatch
{
private int fishermanID, fisherID;
private String dateOfSample, date;
private double[] fishCaught = new double[10];
private int currWeight = 0;
private String summary;
private double average;
private int aboveAvg;
public DailyCatch() { }
public DailyCatch (int fishermanID, String dateOfSample)
{
fisherID = fishermanID;
date = dateOfSample;
}
public DailyCatch (int fishermanID, String dateOfSample, String weight)
{
this(fishermanID, dateOfSample);
readWeights(weight);
}
public void addFish(double weight)
{
if (currWeight > 10)
{
// array full
}
else
{
fishCaught[currWeight] = weight;
currWeight += 1; // update current index of array
}
}
private void readWeights(String weightsAsString)
{
String[] weightsRead = weightsAsString.split("\\s+");
for (int i = 0; i < weightsRead.length; i++)
{
this.addFish(Double.parseDouble(weightsRead[i]));
}
}
public String toString()
{
return "Fisherman ID: " + fisherID + "\nDate:" + date + "\nFish Caught with Weights: " + Arrays.toString(fishCaught);
}
public void printWeights()
{
for (int i = 0; i < fishCaught.length; i++)
{
System.out.println(fishCaught[i]);
}
}
public double averageWeight()
{
double sum = 0;
double count = 0;
for (int i = 0; i < fishCaught.length; i++)
{
if (fishCaught[i] != 0)
{
sum += fishCaught[i];
count += 1;
average = sum/count;
}
}
return average;
}
public String getSummary()
{ int storyTellerCount = 0;
int keeperCount = 0;
int throwBackCount = 0;
for (int i = 0; i < fishCaught.length; i++)
{
if (fishCaught[i] > 5)
{
storyTellerCount++;
}
else if (fishCaught[i] >=1 && fishCaught[i] <= 5)
{
keeperCount++;
}
else if (fishCaught[i] < 1 && fishCaught[i] > 0)
{
throwBackCount++;
}
} String summary = ("\nStoryteller - " + storyTellerCount+ "\nKeeper - " + keeperCount + "\nThrowback - " + throwBackCount);
return summary;
}
public int aboveAverage()
{
int greatAvgCount = 0;
for (int i = 0; i < fishCaught.length; i++)
{
if (fishCaught[i] > average)
{
aboveAvg = greatAvgCount++;
}
}
return aboveAvg;
}
}
Test Code:
public class BigBass
{
public static void main (String[]args)
{
//Part 1
DailyCatch monday1 = new DailyCatch(32, "4/1/2013", "4.1 5.5 2.3 0.5 4.8 1.5");
System.out.println(monday1);
//Part 2
DailyCatch monday2 = new DailyCatch(44, "4/1/2013");
System.out.println(monday2);
monday2.addFish(2.1);
monday2.addFish(4.2);
System.out.println(monday2);
//Part 3
System.out.println("\n\nSUMMARY OF FISHERMAN 32");
System.out.println(monday1.getSummary());
//Part 4
double avg = monday1.averageWeight();
System.out.printf("\nThere are %d fish above the average weight of %.1f.", monday1.aboveAverage(), avg);
}
}
I just need to get Part 4 to work here. What it does is return that there have been 2 fish caught that are above average when I know it should be 3. The average is 3.1.
A simple mistake.
public int aboveAverage() {
int greatAvgCount = 0;
for (int i = 0; i < fishCaught.length; i++) {
if (fishCaught[i] > 3.1) {
greatAvgCount++; // no 'return'
}
}
return greatAvgCount;
}
if (fishCaught[i] > 3.1)
{
return greatAvgCount++;
}
First try : 4.1 > 3.1
true
returns 0 ++ which is 0 basically
You can increment the counter inside the loop and keep the return statement for the end only.
try
public int aboveAverage() {
int greatAvgCount = 0;
for (int i = 0; i < fishCaught.length; i++) {
if (fishCaught[i] > 3.1) {
greatAvgCount++;
}
}
return greatAvgCount;
}
This line is your problem,
return greatAvgCount++;
you are incrimenting greatAvgCount then returning its initial value, there should be no "return" on this line
The aboveAverage method should be
public int aboveAverage()
{
int greatAvgCount = 0;
for (int i = 0; i < fishCaught.length; i++)
{
if (fishCaught[i] > 3.1)
{
greatAvgCount++;
}
}
return greatAvgCount;
}
Also, you may just be doing it for debug, in which case fair enough, but hardcoding the "average" as 3.1 is generally considered bad practice. If you want average to be always 3.1 (i.e. its a global average that you've looked up from a book then its more usual to declare a static variable called double AVERAGE=3.1 and then use that where ever average is required, that way if the "book value" changes you only need to change average in one place in your code. If average is calculated from your data obviously you should use the calculated value.
Also not directly related to your problem but why are you using an array for your caught fish with a predefined maximum of 10. If you used an ArrayList you could add to it as you saw fit and it would auto expand to accommodate
private double[] fishCaught = new double[10];
becomes
private ArrayList<Double> fishCaught = new ArrayList<Double>();