I am working on a bonus for one of my assignments. I'm supposed to create a really large array, but the user doesn't have to use all the slots in the array. Previously I used an enhanced for loop for a regular array that had all its indexes filled. I'm not really sure how to change that to fit the new criteria.
Whenever I enter the numbers in the tester, the toString returns the empty spots and the minimum value returns 0 because the empty spot's values are 0s.
public class NumberSetBonus
{
private int[] numbers;
private int count;
/**
* Constructs an empty NumberSet of a specified size
* #param size the number of elements in the set
*/
public NumberSetBonus(int size)
{
numbers = new int[size];
count = 0;
}
/**
* addNumber adds a number to the number set
* #param num new number
*/
public void addNumber(int num)
{
numbers[count] = num;
count++;
}
/**
* getMin finds the minimum value stored in the NumberSet
* #return the minimum value
* precondition: array is full of values
*/
public int getMin()
{
int min = numbers[0];
for(int n : numbers)
if(n < min)
min = n;
return min;
}
/**
* getMax finds the maximum value stored in the NumberSet
* #return the maximum value
* precondition: array is full of values
*/
public int getMax()
{
int max = numbers[0];
for(int n : numbers)
if(n > max)
max = n;
return max;
}
/**
* find determines whether a specified value exists in the set.
* #param num the number to find
* #return whether the value exists
*/
public boolean find(int num)
{
boolean find = true;
for(int n : numbers)
if(n == num)
find = true;
return find;
}
/**
* getSum calculates the sum of the values in the set.
* #return the sum
*/
public int getSum()
{
int sum = 0;
for(int n : numbers)
sum += n;
return sum;
}
/**
* getMean calculates the mean of the values in the set.
* #return the mean as a double
* precondition: array is full of values
* NOTE: use the length field of the array
*/
public double getMean()
{
return getSum() / (double) numbers.length;
}
/**
* count counts the occurrence of a specified number within the set.
* #param num the number to find
* #return the number of times num occurs in the set
*/
public int count(int num)
{
int quantity = 0;
for(int n : numbers)
if(n == num)
quantity++;
return quantity;
}
/**
* toString returns a String containing the values in the set on a
* single line with a space between each value.
* #return the String version of the set
*/
public String toString()
{
String set = " ";
for(int n : numbers)
set += n + " ";
return set;
}
}
Here's my tester, where I ask for the user's input, and where the toString() returns the 0s
public class NumberSetBonusTester
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
final int LENGTH = 100;
NumberSetBonus list = new NumberSetBonus(LENGTH);
int arraySize = 0;
System.out.print("You can enter up to 100 numbers in this array. \nType in a negative number if you want to stop adding numbers.\nEnter a number: ");
while(arraySize < LENGTH)
{
int number = input.nextInt();
if(number <= 0)
break;
list.addNumber(number);
arraySize++;
}
System.out.print("\nset 1:\t\t");
System.out.println(list);
System.out.println("list sum:\t" + list.getSum());
System.out.println("list mean:\t" + list.getSum() / arraySize);
System.out.println("list max:\t" + list.getMax());
System.out.println("list min:\t" + list.getMin());
System.out.println();
System.out.print("Enter a number to find ==> ");
int searchNum = input.nextInt();
if (list.find(searchNum))
System.out.println(searchNum + " is in the set " + list.count(searchNum) + " times");
else
System.out.println(searchNum + " is not in the set");
}
}
You can simply change all your for loops to the form for (int i = 0; i < count; i++) - this way the loops will only loop the numbers that were actually set, not all numbers in the array.
BTW: If you ever need some variable-sized array in the future you can use a List (from the java.util package). In your example I would use an ArrayList<Integer>. This is a list that uses an array internally, but increases its size if the array gets too small (by creating a new array and copying the contents).
Related
Okay so this is one of my last assignments and of course this is creating the most stress for me but the only thing keeping me from turning this assignment in is being able to apply heapsort on the Heap that the user inputs their own integer values into an array list which is displayed and here is the code for that:
The heap propgram works fine but the Heapsort doesn't work or i can't use it or make a call for it in the HeapApp class
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Scanner;
/**
*/
public class Heap<T extends Comparable<T>> {
private ArrayList<T> items;
public Heap() {
items = new ArrayList<T>();
}
private void siftUp() {
int k = items.size() - 1;
while (k > 0) {
int p = (k-1)/2;
T item = items.get(k);
T parent = items.get(p);
if (item.compareTo(parent) > 0) {
// swap
items.set(k, parent);
items.set(p, item);
// move up one level
k = p;
} else {
break;
}
}
}
public void insert(T item) {
items.add(item);
siftUp();
}
private void siftDown() {
int k = 0;
int l = 2*k+1;
while (l < items.size()) {
int max=l, r=l+1;
if (r < items.size()) { // there is a right child
if (items.get(r).compareTo(items.get(l)) > 0) {
max++;
}
}
if (items.get(k).compareTo(items.get(max)) < 0) {
// switch
T temp = items.get(k);
items.set(k, items.get(max));
items.set(max, temp);
k = max;
l = 2*k+1;
} else {
break;
}
}
}
public T delete()
throws NoSuchElementException {
if (items.size() == 0) {
throw new NoSuchElementException();
}
if (items.size() == 1) {
return items.remove(0);
}
T hold = items.get(0);
items.set(0, items.remove(items.size()-1));
siftDown();
return hold;
}
public int size() {
return items.size();
}
public boolean isEmpty() {
return items.isEmpty();
}
public String toString() {
return items.toString();
}
//----------------------------------------------------------------------------------------------------------------------------------------
public class Heapsort<T extends Comparable<T>> {
/**
* Sort the array a[0..n-1] by the heapsort algorithm.
*
* #param a the array to be sorted
* #param n the number of elements of a that have valid values
*/
public void sort(T[] a, int n) {
heapsort(a, n - 1);
}
/**
* Sort the ArrayList list by the heapsort algorithm.
* Works by converting the ArrayList to an array, sorting the
* array, and converting the result back to the ArrayList.
*
* #param list the ArrayList to be sorted
*/
public void sort(ArrayList<T> items) {
// Convert list to an array.
#SuppressWarnings("unchecked")
T[] a = (T[]) items.toArray((T[]) Array.newInstance(items.get(0).getClass(), items.size()));
sort(a, items.size()); // sort the array
// Copy the sorted array elements back into the list.
for (int i = 0; i < a.length; i++)
items.set(i, a[i]);
}
/**
* Sort the array a[0..lastLeaf] by the heapsort algorithm.
*
* #param items the array holding the heap
* #param lastLeaf the position of the last leaf in the array
*/
private void heapsort(T[] items, int lastLeaf) {
// First, turn the array a[0..lastLeaf] into a max-heap.
buildMaxHeap(items, lastLeaf);
// Once the array is a max-heap, repeatedly swap the root
// with the last leaf, putting the largest remaining element
// in the last leaf's position, declare this last leaf to no
// longer be in the heap, and then fix up the heap.
while (lastLeaf > 0) {
swap(items, 0, lastLeaf); // swap the root with the last leaf
lastLeaf--; // the last leaf is no longer in the heap
maxHeapify(items, 0, lastLeaf); // fix up what's left
}
}
/**
* Restore the max-heap property. When this method is called, the max-heap
* property holds everywhere, except possibly at node i and its children. When
* this method returns, the max-heap property holds everywhere.
*
* #param items the array holding the heap
* #param i index of the node that might violate the max-heap property
* #param lastLeaf the position of the last leaf in the array
*/
private void maxHeapify(T[] items, int i, int lastLeaf) {
int left = leftChild(i); // index of node i's left child
int right = rightChild(i); // index of node i's right child
int largest; // will hold the index of the node with the largest element
// among node i, left, and right
// Is there a left child and, if so, does the left child have an
// element larger than node i?
if (left <= lastLeaf && items[left].compareTo(items[i]) > 0)
largest = left; // yes, so the left child is the largest so far
else
largest = i; // no, so node i is the largest so far
// Is there a left child and, if so, does the right child have an
// element larger than the larger of node i and the left child?
if (right <= lastLeaf && items[right].compareTo(items[largest]) > 0)
largest = right; // yes, so the right child is the largest
// If node i holds an element larger than both the left and right
// children, then the max-heap property already held, and we need do
// nothing more. Otherwise, we need to swap node i with the larger
// of the two children, and then recurse down the heap from the larger
// child.
if (largest != i) {
swap(items, i, largest);
maxHeapify(items, largest, lastLeaf);
}
}
/**
* Form array a[0..lastLeaf] into a max-heap.
*
* #param items array to be heapified
* #param lastLeaf position of last valid data in a
*/
private void buildMaxHeap(T[] items, int lastLeaf) {
int lastNonLeaf = (lastLeaf - 1) / 2; // nodes lastNonLeaf+1 to lastLeaf are leaves
for (int j = lastNonLeaf; j >= 0; j--)
maxHeapify(items, j, lastLeaf);
}
/**
* Swap two locations i and j in array a.
*
* #param items the array
* #param i first position
* #param j second position
*/
private void swap(T[] items, int i, int j) {
T t = items[i];
items[i] = items[j];
items[j] = t;
}
/**
* Return the index of the left child of node i.
*
* #param i index of the parent node
* #return index of the left child of node i
*/
private int leftChild(int i) {
return 2 * i + 1;
}
/**
* Return the index of the right child of node i.
*
* #param i index of the parent node
* #return the index of the right child of node i
*/
private int rightChild(int i) {
return 2 * i + 2;
}
/**
* For debugging and testing, print out an array.
*
* #param a the array to print
* #param n number of elements of a to print
*/
public void printArray(T[] items, int n) {
for (int i = 0; i < n; i++)
System.out.println(items[i]);
}
}
}
import java.util.Scanner;
public class HeapApp{
/**
* #param args
*/
public static void main(String[] args) {
Heap<Integer> hp = new Heap<Integer>();
Scanner sc = new Scanner(System.in);
System.out.print("Enter next int, 'done' to stop: ");
String line = sc.next();
while (!line.equals("done")) {
hp.insert(Integer.parseInt(line));
System.out.println(hp);
System.out.print("Enter next int, 'done' to stop: ");
line = sc.next();
}
while (hp.isEmpty()) {
//int max = hp.delete();
System.out.println( " " + hp);
}
System.out.println(hp);
System.out.println("After sorting " + hp);
}
}
Now i'm not asking anyone to do it for me but i just need help figuring out how to get the Heapsort to work with the heap PLEASE HELP! The most i have tried is setting the parameters within the Heap sort method.
My question and code is not a duplicate for one this is based on a Heap and heapsort from the user input:
public static void main(String[] args) {
Heap<Integer> hp = new Heap<Integer>();
Scanner sc = new Scanner(System.in);
System.out.print("Enter next int, 'done' to stop: ");
String line = sc.next();
while (!line.equals("done")) {
hp.insert(Integer.parseInt(line));
System.out.println(hp);
System.out.print("Enter next int, 'done' to stop: ");
line = sc.next();
}
Also the entire Heap is implemented using an ArrayList:
public class Heap<T extends Comparable<T>> {
private ArrayList<T> items;
public Heap() {
items = new ArrayList<T>();
}
Add a sort method to your Heap class like this:
public void sort()
{
new Heapsort<T>().sort(items);
}
Then in your HeapApp class call the sort method before printing it out:
hp.sort();
System.out.println("After sorting " + hp);
I have to distribute i. no. of items into n no. of boxes where each box has different capacity level c1, c2 ... cn. I want to distribute the items in ratio of their capacity. So the box with highest capacity will contain highest no. of items and vice versa. The capacities may not be in ascending order. The capacities can also be 0. Also, if the no. of items exceed the total capacity, then fill all the boxes upto their maximum capacity.
Is there already a solution for this problem?
Because I've written following algo. But it's not efficient. Also its looping infinitely at following input. Since the -2 difference is never settled. So there must also be other use cases where it breaks.
int[] arrCap = {1,1,0,1,1};
new Distributor(arrCap, 2).distribute();
import java.util.Arrays;
public class Distributor {
/** Capacity of each box */
private final int[] boxCapacity;
/** Total no. of boxes */
private final int NO_OF_BOXES;
/** Total no. of items that are to be distributed into each box */
private final int NO_OF_ITEMS;
/** Total capacity available. */
private long totalCapacity;
/** Fractionally ratio distributed items according to capacity */
private float[] fractionalRatios;
/** Ratio distributed items according to capacity */
private int[] ratioDistributedCapacity;
/** Sorted Rank of distributed items in ascending / descending order */
private int[] rankIndex;
/** The difference between the totalCapacity and total of ratioDistributedCapacity */
private int difference;
/**
* Validates the total capacity and no. of items to be distributed.
* Initializes the distributor with box capacity array, no of items.
* Implicitly calculates no. of boxes as length of box capacity array.
* #param boxCapacity Array of capacity of each box.
* #param noOfItems No. of Items to be distributed.
*/
public Distributor(int[] boxCapacity, int noOfItems) {
calculateBoxes(boxCapacity);
this.boxCapacity = boxCapacity;
this.NO_OF_ITEMS = noOfItems;
NO_OF_BOXES = boxCapacity.length;
ratioDistributedCapacity = new int[NO_OF_BOXES];
rankIndex = new int[NO_OF_BOXES];
}
/**
* Calculates the ratio into which the items are to be distributed.
* Actually assigns the items into each box according to the ratio.
* #return Array of int[] containing ratio distributed items according to its capacity.
*/
public int[] distribute() {
// If NO_OF_ITEMS to be distributed is more than totalCapacity then distribute all the items upto full capacity
if (NO_OF_ITEMS >= totalCapacity) {
ratioDistributedCapacity = boxCapacity;
} else {
calculateRatioAndDistribute();
}
return ratioDistributedCapacity;
}
/**
* Calculates the ratio & distributes the items according to the capacity.
*/
private void calculateRatioAndDistribute() {
fractionalRatios = new float[NO_OF_BOXES];
for (int i=0; i<NO_OF_BOXES; i++) {
fractionalRatios[i] = ((float) boxCapacity[i] * (float) NO_OF_ITEMS) / (float) totalCapacity;
ratioDistributedCapacity[i] = Math.round(fractionalRatios[i]);
}
print(fractionalRatios);
print(ratioDistributedCapacity);
// keep redistributing the difference until its not 0
while ((difference = rectifyAndGetDistributionResult()) != 0) {
redistribute();
}
print(ratioDistributedCapacity);
}
/**
* Redistributes the difference between the already allotted ratioDistributedCapacity array.
* Also if the difference is 0 that means everything is already settled.
* No more further need to do anything.
* #param difference the difference that needs to be settled to equal the no. of items with total distributed items.
*/
private void redistribute() {
if (difference > 0) {
// calculate distribution ranks in ascending order
calculateDistributionRanks(true); // orderDescending = true
// eliminate the invalid ranks from rankIndex
eliminateInvalidRanks();
// In case all the ranks have become invalid. In this case the rankIndex will be empty.
// So we need to re calculate the distribution ranks in opposite order.
if (rankIndex.length == 0) {
calculateDistributionRanks(false); // orderDescending = false
}
} else if (difference < 0) {
// calculate distribution ranks in descending order
calculateDistributionRanks(false); // orderDescending = false
// eliminate the invalid ranks from rankIndex
eliminateInvalidRanks();
// In case all the ranks have become invalid. In this case the rankIndex will be empty.
// So we need to re calculate the distribution ranks in opposite order.
if (rankIndex.length == 0) {
calculateDistributionRanks(true); // orderDescending = true
}
}
// add / substract 1 from the ratioDistributedCapacity of the element in order of the rankIndex
// according to negative / positive difference until the difference becomes 0.
final int len = rankIndex.length;
for (int i=0; i<len; i++) {
if (difference == 0) {
break;
} else if (difference > 0) {
ratioDistributedCapacity[ rankIndex[i] ]++;
difference--;
} else if (difference < 0) {
ratioDistributedCapacity[ rankIndex[i] ]--;
difference++;
}
}
}
/**
* If the value of any ratioDistributedCapacity element exceeds its capacity or is less than 0,
* revert it with its initial capacity value.
*/
private void rectify() {
for (int i=0; i<NO_OF_BOXES; i++) {
ratioDistributedCapacity[i] = ((ratioDistributedCapacity[i] > boxCapacity[i]) || (ratioDistributedCapacity[i] < 0)) ? boxCapacity[i] : ratioDistributedCapacity[i];
}
}
/**
* Calculates the distribution ranks i.e. indexes of fractionalRatios array.
* Sorts them into ascending or descending order.
* #param orderDesc Sort order. true for descending and false for ascending.
*/
private void calculateDistributionRanks(boolean orderDesc) {
// Copy fractionalRatios array to another tmp array. Note:- Use fractionalRatios so ranking can be more accurate.
float[] tmp = Arrays.copyOf(fractionalRatios, NO_OF_BOXES);
// Sort the array in ascending order
Arrays.sort(tmp);
// re-initialize the rankIndex array
rankIndex = new int[NO_OF_BOXES];
for (int i=0; i<NO_OF_BOXES; i++) {
innerLoop: for (int j=0; j<NO_OF_BOXES; j++) {
if (tmp[i] == fractionalRatios[j]) {
// Store the array index of unsorted array if its value matches value of sorted array.
rankIndex[i] = j;
break innerLoop;
}
}
}
// reverse the rank array if orderDesc flag is true
if (orderDesc) reverse();
print(rankIndex);
}
/**
* Remove the indexes from rank which are already full or equal to 0
* or are not eligible for increment / decrement operation.
*/
private void eliminateInvalidRanks() {
final int len = rankIndex.length;
int invalidRankCount = 0;
final int markInvalidRank = -1;
for (int i = 0; i < len; i++) {
if (boxCapacity[rankIndex[i]] <= 0) {
// mark this rank number as invalid, for removal
rankIndex[i] = markInvalidRank;
invalidRankCount++;
continue;
}
if (difference > 0) {
if ((ratioDistributedCapacity[rankIndex[i]] >= boxCapacity[rankIndex[i]])) {
// mark this rank number as invalid, for removal
rankIndex[i] = markInvalidRank;
invalidRankCount++;
continue;
}
} else if (difference < 0) {
if (ratioDistributedCapacity[rankIndex[i]] <= 0) {
// mark this rank number as invalid, for removal
rankIndex[i] = markInvalidRank;
invalidRankCount++;
continue;
}
}
}
int[] tmp = new int[(len - invalidRankCount)];
int j = 0;
for (int i = 0; i < len; i++) {
if (rankIndex[i] != markInvalidRank) {
tmp[j++] = rankIndex[i];
}
}
rankIndex = tmp;
print(rankIndex);
}
/**
* Rectifies the elements value inside ratioDistributedCapacity.
* Calculates the total of already distributed items.
* #return Difference between total distributed items and initial no. of items that were to be distributed.
*/
private int rectifyAndGetDistributionResult() {
rectify();
int remaining = NO_OF_ITEMS;
for (int tmp: ratioDistributedCapacity) {
remaining -= tmp;
}
return remaining;
}
/**
* Validates the capacity array and no. of items to be distributed.
* #param arrCapacity Array of capacity of each box.
*/
private void calculateBoxes(int[] arrCapacity) {
for (int i: arrCapacity) {
totalCapacity += i;
}
}
/**
* Prints the array elements and the total of the elements within it.
* #param x
*/
private void print(int[] x) {
final int len = x.length;
final StringBuilder sb = new StringBuilder("");
for (int i=0; i<len; i++) {
sb.append(x[i]).append(", ");
}
System.out.println(sb.toString());
}
/**
* Prints the array elements and the total of the elements within it.
* #param x
*/
private void print(float[] x) {
final int len = x.length;
final StringBuilder sb = new StringBuilder("");
for (int i=0; i<len; i++) {
sb.append(x[i]).append(", ");
}
System.out.println(sb.toString());
}
private void reverse() {
final int len = rankIndex.length;
for (int i=0; i < (len/2); i++) {
rankIndex[i] += rankIndex[len - 1 - i]; // a = a+b
rankIndex[len - 1 - i] = rankIndex[i] - rankIndex[len - 1 - i]; // b = a-b
rankIndex[i] -= rankIndex[len - 1 - i]; // a = a-b
}
}
}
I wonder if you do simple math to find out ratio would solve the problem easily.
So Ni is number of items you have to distribute, B sum of all boxes capacity(ie c1+c2+...+cn)
So R = Ni/B would be your ration.
R*cn would be number of items you would want to put into box n
Example:
you have total of 8 items. and 2 boxes capacity 4, 12(N1 = 16).
R = 8/(4+12) = 1/2
for box would have R*4 = 2
second box would have R*12 = 6
Of course you would have to handle rounding issues, there will be +/-1 items in the boxes.
PS
For fixing rounding issue you will do following.
you create a variable sumSoFar = 0 //initial value
box1 contains R*c1
then you add sumSoFar+=Math.round(R*c1)
box2 contains Math.round(R*c2)
then you add sumSoFar+=Math.round(R*c2)
for last box you put N1-sumSoFar So you distribute all values.
here is the code:
static int[] distribute(int[] boxes, int items) {
int[] result = new int[boxes.length];
int sumSoFar = 0;
int totalCapacity = 0;
for (int box : boxes) {
totalCapacity += box;
}
float R = (float) items / totalCapacity;
for (int i = 0; i < boxes.length - 1; i++) {
int box = boxes[i];
result[i] = Math.round(R * box);
sumSoFar += result[i];
}
result[boxes.length - 1] = items - sumSoFar;
return result;
}
Calling:
System.out.println(Arrays.toString(distribute(new int[]{1, 2}, 10)));
System.out.println(Arrays.toString(distribute(new int[]{4, 12}, 8)));
Results:
[3, 7]
[2, 6]
Two approaches come to mind
Optimal Rounding
Treat the problem like an optimal rounding problem. Since you want the items distributed in the boxes "in ratio of their capacity", then for each box compute their share which is "capacity / sum of all capacities". Then multiply that share by the number of items. That'll usually give you a fractional number of items for each box. I assume your items are indivisible. Now you just have to determine how to "optimally round" these values. Here is one SO question that discusses how to do that. You can also search for "optimal rounding under integer constraints" to find several papers on the subject.
Fair Division
Treat the problem using fair division. The link covers numerous approaches (most are approximations). However, the key part will be how will each of your boxes ascribe a value to each item, so that the algorithms will know how to parcels the items. You can use a metric that is proportional to their capacity.
So as the title, I've got different results running my Magic Square program from Eclipse and cmd command. The eclipse one does not make sense.
(The position of sentence "Wrong number..." should be wrong in the eclipse one)
Anyone know how to fix it? Thanks a lot!
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class MagicSquare{
// the two-dimensional array to restore my own magic square.
private int[][] myMagicSquare;
private int n;
public MagicSquare(){
}
/**
* Function: this constructor takes and positive, odd integer parameter to generate a new
* magic square.</br>
* #param n the length of magic square</br>
* #throws IllegalArgumentException for negative or even parameter.
* Preston Jul 5, 20151:15:40 AM</br>
*/
public MagicSquare(int n){
//throws runtime error.
if(!rangeCheck(n)){
throw new IllegalArgumentException("Illegal number");
}else{
// create my magic square array with length of given integer.
this.n = n;
myMagicSquare = new int[n][n];
// generate the magic square.
createMagicSquare();
}
}
/**
*
* Function: this constructor takes a 2D array as a parameter. If the 2D array can generate
* a magic square, then put the values into <i>my magic square</i></br>, if not then throws
* the exception.
* #param newMagicSquare the tested 2D array</br>
* #throws IllegalArgumentException
* Preston Jul 5, 20151:23:10 AM</br>
*/
public MagicSquare(int[][] newMagicSquare){
this.n = newMagicSquare.length;
// determine whether or not the 2D array can generate a magic square.
if(isMagic(newMagicSquare))
myMagicSquare = newMagicSquare;
else
throw new IllegalArgumentException("This is not a magic square");
}
/**
*
* Function:Range check for the input of magic square length</br>
* #param n the length of magic square
* #return true if the length is a positive, odd number</br>
* Preston Jul 5, 20152:53:29 PM</br>
*/
private static boolean rangeCheck(int n){
return !((n>0&&n%2==0)||n<=0);
}
/**
*
* Function: return the magic number of the magic square.</br>
* #return the value magic number.</br>
* Preston Jul 5, 20151:29:02 AM</br>
*/
private int getMagicNumber(){
return (n*(n*n+1))/2;
}
/**
*
* Function: For challenging level: check if all numbers for 1 to n*n only appeared once
* in the given 2D array.</br>
* #param temp the temporary 2D array as parameter.
* #return true if all numbers from 1 to n*n only appeared once</br>
* Preston Jul 5, 20151:30:03 AM</br>
*/
private static boolean noRepeatedNum(int[][] temp){
int n = temp.length;
// Set up the standard Set for comparison.
Set<Integer> standardSet = new HashSet<>();
for(int i=1;i<=n*n;i++){
standardSet.add(i);
}
// the Set made of all numbers from temp. All repeated numbers show only once in Set.
Set<Integer> arraySet = new HashSet<>();
for(int[] x : temp){
for(int a : x){
arraySet.add(a);
}
}
// return if two Sets are equal.
return arraySet.equals(standardSet);
}
/**
*
* Function: Check if the given 2D array can consist a magic square</br>
* #param temp a parameter 2D array.
* #return true if numbers in the parameter array could consist a magic square</br>
* Preston Jul 5, 20151:36:44 AM</br>
*/
private static boolean isMagic(int[][] temp){
//store the return value
boolean isMagic = true;
int tempN = temp.length;
int magicNumber = (tempN*(tempN*tempN+1))/2;
// accumulator for two diagonals
int diagonalOneSum = 0;
int diagonalTwoSum = 0;
// check rows and columns
for(int i=0; i<tempN;i++){
int rowSum = 0;
int columnSum = 0;
for(int j=0;j<tempN;j++){
// single-row sum
rowSum += temp[i][j];
// single-column sum
columnSum += temp[j][i];
}
if(rowSum!=magicNumber||columnSum!=magicNumber){
isMagic = false;
// return false immediately if there's inequality. Save calculations and performance.
return isMagic;
}
}
// counter for the second diagonal
int diagonalTwoCounter = tempN-1;
// sum of two diagonals
for(int i=0;i<temp.length;i++){
diagonalOneSum += temp[i][i];
diagonalTwoSum += temp[diagonalTwoCounter][diagonalTwoCounter];
diagonalTwoCounter--;
}
if(diagonalOneSum!=magicNumber||diagonalTwoSum!=magicNumber){
isMagic = false;
return isMagic;
}
// check if there are repeated numbers in the pretty magic square already.
return noRepeatedNum(temp);
}
/**
*
* Function: check if the position of the number in the magic square is at boundary</br>
* #param boundary the row OR column number of the position
* #return true if the value of<code>boundary</code> is zero</br>
* Preston Jul 5, 20151:53:24 PM</br>
*/
private boolean Boundary(int boundary){
return boundary==0;
}
/**
*
* Function: Put numbers from 1 to n*n into my own 2D array using Siamese Method.</br>
* Preston Jul 5, 20153:20:56 PM</br>
*/
private void createMagicSquare(){
// starting Row number -> middle
int startRow = this.n/2;
// starting Column number -> the first column
int startColumn = 0;
// start to put number from 2
int startNum = 2;
// put 1 in the starting position
myMagicSquare[startRow][startColumn] = 1;
while(startNum<=n*n){
// the positions on upper boundary
if(Boundary(startRow)&&!Boundary(startColumn)){
myMagicSquare[n-1][startColumn-1] = startNum;
startRow = n-1;
startColumn -= 1;
}
// the positions on left boundary
else if(Boundary(startColumn)&&!Boundary(startRow)){
myMagicSquare[startRow-1][n-1] = startNum;
startRow -= 1;
startColumn = n-1;
}
// upper left corner.
else if(Boundary(startRow)&&Boundary(startColumn)){
myMagicSquare[startRow][startColumn+1] = startNum;
startColumn += 1;
}
else{
// if the coming position is filled with number.
if(myMagicSquare[startRow-1][startColumn-1]!=0){
myMagicSquare[startRow][startColumn+1] = startNum;
startColumn += 1;
}
// general movement
else{
myMagicSquare[startRow-1][startColumn-1] = startNum;
startRow -= 1;
startColumn -= 1;
}
}
startNum++;
}
}
public String toString() {
// align my 2D array.
return toString(myMagicSquare);
}
/**
*
* Function:align the numbers in the parameter 2D array pretty</br>
* #param temp the parameter 2D array.
* #return the beautifully aligned String</br>
* Preston Jul 5, 20153:26:15 PM</br>
*/
public static String toString(int[][] temp){
int largestNum = 0;
// get the largest number in temp.
for(int[] x : temp){
for(int a : x){
if(a>=largestNum)
largestNum = a;
}
}
// how many digits does the biggest number have?
int longestDigit = String.valueOf(largestNum*largestNum).length();
// store the final String
StringBuilder printOut = new StringBuilder();
printOut.append('\n');
for(int[] x : temp){
for(int a : x){
// space between each number
printOut.append('\t');
// add spaces for alignment.
for(int i=0;i<longestDigit-String.valueOf(a).length();i++){
printOut.append(" ");
}
printOut.append(String.valueOf(a));
}
printOut.append('\n').append('\n');
}
// return the big String
return printOut.toString();
}
/**
*
* Function: the main function scans user input as the length of 2D array to make my
* own magic square. If the <code>userInput</code> is out of range, print out the error
* message and ask for the number again. Enter the code 0 to exit.</br>
* #param args</br>
* Preston Jul 5, 20153:28:57 PM</br>
*/
public static void main(String[] args) {
int userInput;
do{
// title
System.out.println("Enter a positive, odd number");
System.out.print("Exit code is 0, enter 0 to quit: ");
// user input
userInput = new Scanner(System.in).nextInt();
// if the userInput is out of range, show error message.
if(rangeCheck(userInput)){
MagicSquare m = new MagicSquare(userInput);
System.out.println(m.toString());
}else
if(userInput==0)
System.out.println("The magic square is not generated. QUIT");
else
System.err.println("Wrong number: Please enter a positive, odd number");
// restart
System.out.println("-------------------");
}while(userInput != 0); // enter 0 to exit.
}
}
The reason for above issue is that bug in handling of stdout and stderr in eclipse.Follow this link. (Not sure whether this is fixed or not.)
I also tried to reproduce this issue, but it is occurring in some cases and in some cases output and error output is showing at correct places.
Just for check :-
You may get this issue at very first run on eclipse, so don't exit the code, try again with wrong number (i.e. 2/4/6 ...) ;you may see error and output gets correctly printed.
/*
* One common programming activity is to find the minimum and maximum values
* within a list. In this challenge activity we will do just that. It will also
* demonstrate how arrays and for loops compliment each other nicely.
*
* First, execute the main() method as is so you can understand how the for loop
* works with the array. If you must, set a breakpoint and step through the code.
*
* Notice the min and max values are not correct. That's where you come in your
* job is to write these methods. Regardless of min or max, your approach should
* be the same: (Here's the pseudocode for min)
*
* set min to the value of the first element in the array
* for each element in the array
* if the current element is less than min
* set min to the current element
* end for
* return min
*/
package minandmax;
import java.util.Scanner;
public class MinAndMax {
public static void main(String[] args) {
Scanner input = new Scanner(System. in );
int[] array = new int[10];
// Read inputs into the array
System.out.println("Enter 10 Integers.");
for (int i = 0; i < array.length; i++) {
System.out.printf("Enter Integer %d ==>", i + 1);
array[i] = input.nextInt();
}
// Print out the array
System.out.print("You Entered :");
for (int i = 0; i < array.length; i++) {
System.out.printf("%d ", array[i]);
}
System.out.println();
// find the min / max and print
System.out.printf("Min = %d\n", getMin(array));
System.out.printf("Max = %d\n", getMax(array));
}
/**
* returns the smallest value in the array
* #param array array of integer
* #return integer representing the smallest
*/
public static int getMin(int[] array) {
//TODO: write code here
int min = array[0];
for (int a: array) {
if (a < min) {
min = a;
} else {
break;
}
}
return min;
}
/**
* returns the largest value in the array
* #param array array of integer
* #return integer representing the largest
*/
public static int getMax(int[] array) {
//TODO: write code here
int max = array[0];
for (int a: array) {
{
if (a > max) {
max = a;
return max;
}
I keep getting missing return statement and reach the end of file while parsing , however I already have my return statements and my code correctly closes brackets. Please help , thanks
In your getMax method, you get the error because return max is not reachable if (a <=max)
Looks at getMax, you have two open curly braces
public static int getMax(int[] array) {
//TODO: write code here
int max = array[0];
for(int a : array)
{
{ <===== HERE
if (a > max )
{
On a side note, you should not return max as soon as you encounter a number bigger than max, you should wait until you've looked at them all.
If the if condition is not at all true, Or if the control never goes into the forloop, then the method getMax() will not return anything. but as per the method definition, It should return an integer. And there are few braces which are not closed/openned properly.
Try this
public static int getMax(int[] array) {
int max = array[0];
for (int a: array) {
if (a > max) {
max = a;
}
}
return max;
}
Just think about what your code is realy doing in your 2 find methods.
you will never test all your int values in your array in that way you implemented this.
just test your values with a simple if(min < a) or if(max > a) and only return after your for() loop not in the loop.
I'm a first year computer science student having a problem with part of an assignment. The goal of the assignment was to store the coefficients for a polynomial and find its roots using both an array and a linked list. I was able to successfully complete the array version; however the linked list is giving me a headache.
I am able to successfully store the initial round of variables provided in polynomial.java; however, things go a bit crazy once the root calculations begin and the program ends up terminating without giving any roots. I have a feeling this might be being cause by the way the Polynomial.java calculates the roots causing problems with the linked list; however, I am not allowed to change polynomial.java, only LinkedIntList.java. I have been banging my head against the computer for the past 7 hours trying to find the bug and am about ready to just give up on the assignment as I can't reach the professor for help.
I'd greatly appreciate anyone who can spot the bug or are willing to look over the code to provide tips on what I may be doing wrong or how I can work around my problem.
File 1: Node.Java
package lists;
public class Node
{
int element;
Node next = null;
/**
* Constructor which creates a new node containing the value specified by item
*
*/
public Node (int item)
{
element = item;
}
/**
* Returns the current value of the data item contained inside this node
*/
public int getElement ()
{
return element;
}
/**
* Sets the current value of the data item contained inside this node to
* the value specified by newVal
*/
public void setElement (int newVal)
{
element = newVal;
}
/**
* Links this node to the node passed in as an argument
*/
public void setNext (Node n)
{
next = n;
}
/**
* Returns a reference to the node that follows this node in the
* linked list, or null if there is no such node
*/
public Node getNext ()
{
return next;
}
/**
* Returns a string based representation of the data item contained
* in this node.
*/
public String toString()
{
return Integer.toString(element);
}
}
File 2: LinkedIntList.Java
package lists;
public class LinkedIntList implements IntList
{
Node head = null;
int count = 0;
/**
* Standard Java toString method that returns a string
* equivalent of the IntList
*
* #return a string indicating the values contained in
* this IntList (ex: "[5 3 2 9 ]")
*/
public String toString()
{
String retVal = "";
String intermediary = "";
Node n;
for (n = head; n.getNext() != null; n = n.getNext())
{
intermediary = Integer.toString(n.getElement());
retVal = intermediary + " " + retVal;
}
retVal = n.getElement() + " " + retVal;
return retVal;
}
/**
* Adds the given value to the <b>end</b> of the list.
*
* #param value the value to add to the list
*/
public void add (int value)
{
Node newNode = new Node (value);
if (head == null)
head = newNode;
else
{
Node n = head;
while (n.getNext() != null)
{
n = n.getNext();
}
n.setNext(newNode);
}
count++;
}
/**
* Returns the number of elements currently in the list.
*
* #return the number of items currently in the list
*/
public int size()
{
return count;
}
/**
* Returns the element at the specified position in this list.
*
* #param index index of the element to return (zero-based)
* #return the element at the specified position in this list.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public int get(int index) throws IndexOutOfBoundsException
{
Node reference = head;
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
for (int i = 0; i != index; i++)
{
reference.getNext();
}
return reference.getElement();
}
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* #param index index of the element to return (zero-based)
* #param value element to be stored at the specified position.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public void set (int index, int value) throws IndexOutOfBoundsException
{
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
Node newNode = new Node (value);
Node trailingReference = head;
Node leadingReference = head.getNext();
for(int i = 1; i != index; i++)
{
trailingReference = leadingReference;
leadingReference = leadingReference.getNext();
}
trailingReference.setNext(newNode);
newNode.setNext(leadingReference);
count++;
}
}
File 3: IntList.Java
package lists;
public interface IntList
{
/**
* Standard Java toString method that returns a string
* equivalent of the IntList
*
* #return a string indicating the values contained in
* this IntList (ex: "[5 3 2 9 ]")
*/
public String toString();
/**
* Adds the given value to the <b>end</b> of the list.
*
* #param value the value to add to the list
*/
public void add (int value);
/**
* Returns the number of elements currently in the list.
*
* #return the number of items currently in the list
*/
public int size();
/**
* Returns the element at the specified position in this list.
*
* #param index index of the element to return (zero-based)
* #return the element at the specified position in this list.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public int get(int index);
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* #param index index of the element to return (zero-based)
* #param value element to be stored at the specified position.
* #throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index >= size()).
*/
public void set (int index, int value);
}
File 4: Polynomial.java
/**
* A program which finds the integer (whole number) roots of a
* polynomial with integer coeffecients. The method used is based
* upon the ideas presented at:
*
*/
import lists.*;
public class Polynomial
{
public static void main (String [] args)
{
// trick to get out of static context
new Polynomial().runMe();
}
public void runMe()
{
IntList poly = new LinkedIntList();
// Create the polynomial:
// 3x^10 + 12x^9 - 496x^8 - 211x^7 + 18343x^6 -43760x^5 +
// 11766x^4 + 26841x^3 - 126816x^2 + 37278x - 84240
poly.add (-84240);
poly.add (37278);
poly.add (-126816);
poly.add (26841);
poly.add (11766);
poly.add (-43760);
poly.add (18343);
poly.add (-211);
poly.add (-496);
poly.add (12);
poly.add (3);
System.out.print ("Finding the integer roots of the polynomial: ");
System.out.println (poly);
IntList roots = findRoots (poly);
for (int x = 0; x < roots.size(); x++)
System.out.println ("Root found: " + roots.get(x));
}
/**
* Find all *integer* roots of the polynomial represented by the IntList.
*
* #param poly a polynomial encoded as a list of coefficients
* #return a list of all roots of the given polynomial. Note that
* the returned list may have duplicate entries.
*/
public IntList findRoots (IntList poly)
{
IntList l = new LinkedIntList();
int q = poly.get(poly.size() - 1);
int p = poly.get(0);
IntList pVals = divTerms(Math.abs(p));
IntList qVals = divTerms(Math.abs(q));
IntList possibleZeros = findPotentialZeros(pVals, qVals);
//for (Integer i : possibleZeros)
for (int x = 0; x < possibleZeros.size(); x++)
if (eval (poly, possibleZeros.get(x)) == 0)
l.add (possibleZeros.get(x));
return l;
}
/**
* Evaluates the polynomial represented by the IntList with the given
* value.
*
* #param poly a
* #param val the value to evaluate the polynomial with.
* #return f(val), where f is the polynomial encoded as poly
*/
private int eval (IntList poly, int val)
{
int result = 0;
for (int x = poly.size() - 1; x >= 0; x--)
result += poly.get(x) * (int) Math.pow (val, x);
return result;
}
private IntList findPotentialZeros (IntList plist, IntList qlist)
{
IntList result = new LinkedIntList();
for (int p = 0; p < plist.size(); p++)
{
for (int q = 0; q < qlist.size(); q++)
{
// add it only if q evenly divides p (we're looking
// for integer roots only
if (plist.get(p) % qlist.get(q) == 0)
{
int x = plist.get(p) / qlist.get(q);
result.add (x);
result.add (-x);
}
}
}
return result;
}
/**
* Find all integers that evenly divide i.
*
* #param i the integer to find all divisors of
* #return a list of all integers that evenly divide i
*/
private IntList divTerms (int i)
{
IntList v = new LinkedIntList();
// 1 divides all numbers
v.add(1);
// find all divisors < i and >= 2
for (int x = 2; x < i; x++)
if (i % x == 0)
v.add(x);
// all numbers are evenly divisible by themselves
if (i > 1)
v.add(i);
return v;
}
}
I think, the mistake (or one of them) is in your LinkedList imlementation, exactly in get method:
public int get(int index) throws IndexOutOfBoundsException
{
Node reference = head;
if (index < 0 || index >= count)
{
throw new IndexOutOfBoundsException("Index out of bounds.");
}
for (int i = 0; i != index; i++)
{
reference.getNext(); // <--- the mistake is here
}
return reference.getElement();
}
Your reference always refers on the head of the list.
If you're allowed to use any java packages - use java.util.LinkedList. Otherwise, use java.util.LinkedList until all other parts of your programm would be finished and tested and work as you wish. After that carefully replace it with your LinkedList implementation.
The set method in the LinkedIntList isn't adhering to the contract specified in the Javadoc. It says replace the element at the given index but I see code that adds a new Node.
Have a look at what methods the Node class provides to help you make the set method a lot easier and correct.
Take a good look at your get implementation. It does not do what you think.