I searched throughout the forums and could not find what I was looking for. I am doing an assignment for school and I need to implement some methods. I did most of them and am getting the output I need. However, I'm having trouble implementing the Cartesian Product (xproduct) method.
Here is my code so far:
import java.util.*;
public class Set
{
private ArrayList<String>elements;
/**
* creates an empty set
*/
public Set()
{
elements = null;
}
/**
* creates a set using the elements of the ArrayList s.
* #param s the ArrayList whose elements are used to create this set.
* #throws IllegalArgumentException if s contains duplicity.
*/
public Set(ArrayList<String> s)
{
int i;
elements = new ArrayList<String>();
for(i=0;i<s.size();i++)
{
if(elements.contains(s.get(i)))
{throw new IllegalArgumentException("Set(ArrayList<String>)duplicity not allowed in sets");}
elements.add(s.get(i));
}
}
/**
* creates a set using the elements of the array s.
* #param s the array whose elements are used to create this set.
* #throws illegalArgumentException if s contains duplicity.
*/
public Set(String[] s)
{
int i;
elements = new ArrayList<String>();
for(i=0; i<s.length; i++)
{
if (elements.contains(s[i]))
{throw new IllegalArgumentException("Set(String[]):duplicity not allowed in sets");}
elements.add(s[i]);
}
}
/**
* determines whether a set contains the specified element
* #param elt an element
* #return true if elt is an element of this set; otherwise, false
*/
public boolean isElement(String elt)
{
return elements.contains(elt);
}
/**
* determines the size of this set.
* #return the size of this set.
*/
public int cardinality()
{
return elements.size();
}
/**
* computes the intersection of this set and the
* specified set.
* #param s a set
* #return a set representing the intersection of this set
* and s.
*/
public Set intersect(Set s)
{
int i;
ArrayList<String> result = new ArrayList<String>();
for (i=0;i<s.cardinality();i++)
{
if (this.isElement(s.elements.get(i)))
{result.add(s.elements.get(i));}
}
return new Set(result);
}
/**
* computes the union of this set and the specified set.
* #param s a sets
* #return a set representing the union of this set
* and s.
*/
public Set union(Set s)
{
int i;
ArrayList<String> result = new ArrayList<String>();
result.addAll(this.elements);
result.addAll(s.elements);
for(i=0;i<s.cardinality();i++)
{
if (this.isElement(s.elements.get(i)))
{result.remove(s.elements.get(i));}
}
return new Set(result);
}
/**
* computes the difference between this set and the
* specified set.
* #param s a set
* #return a set representing the difference between
* this set and s.
*/
public Set diff(Set s)
{
int i;
ArrayList<String> result = new ArrayList<String>();
result.addAll(this.elements);
for(i=0;i<s.cardinality();i++)
{
if (this.isElement(s.elements.get(i)))
{result.remove(s.elements.get(i));}
}
return new Set(result);
}
/**
* computes the symmetric difference between this set
* and the specified set.
* #param s a set
* #return a set representing the symmetrical difference
* between this set and s.
*/
public Set symDiff(Set s)
{
int i;
ArrayList<String> result = new ArrayList<String>();
result.addAll(this.elements);
result.addAll(s.elements);
for(i=0;i<s.cardinality();i++)
{
if (this.isElement(s.elements.get(i)) && s.isElement(this.elements.get(i)))
{result.remove(this.elements.get(i));
result.remove(s.elements.get(i));}
}
return new Set(result);
}
/**
* computes the Cartesian product for this set
* and the specified set.
* #param s a set
* #return a set representing the Cartesian product
* of this set and s.
*/
public Set xProduct(Set s)
{
int i;
ArrayList<String> result = new ArrayList<String>();
result.addAll(this.elements);
result.addAll(s.elements);
}
/**
* determines whether a set is empty
* #return true if this set is empty; otherwise, false
*/
public boolean isEmpty()
{
return elements.isEmpty();
}
/**
* determines whether this set is equal to the specified
* set.
* #param s a set
* #return true if this set is equal to s; otherwise, false
*/
public boolean equals(Set s)
{
return elements.equals(s.elements);
}
/**
* determines whether this set is a subset of the specified set.
* #param s a set
* #return true if this set is a subset of s; otherwise, false
*/
public boolean subset(Set s)
{
return elements.containsAll(s.elements);
}
/**
* determines whether this set is a proper subset of the specified set.
* #param s a set
* #return true if this set is a proper subset of s; otherwise, false
*/
public boolean properSubset(Set s)
{
if(elements.equals(s.elements) && elements.containsAll(s.elements))
{return false;}
else{
return true;
}
}
/**
* returns a string {x1,x2,...,xn} representing this set,
* where x1,x2,...,xn are elements of this set.
* #return a string representation of this set formatted
* as specified.
*/
#Override
public String toString()
{
return "{"+this.elements+"}";
}
public static void main(String[] args)
{
String[]a1 = {"2","4","6","8"};
String[]a2 = {"2","3","5","7"};
String[]a3 = {"1","3","5"};
Set s1 = new Set(a1);
Set s2 = new Set(a2);
Set s3 = new Set(a3);
System.out.print("S1 ="); System.out.printf("%s",s1);
System.out.println();
System.out.print("S2 ="); System.out.printf("%s",s2);
System.out.println();
System.out.print("S3 ="); System.out.printf("%s",s3);
System.out.println();System.out.println();
System.out.println("(S1 \u222A S2:)");
System.out.printf("%s \u222A %s = %s%n",s1,s2,s1.union(s2));
System.out.println();
System.out.println("(S1 \u2296 S2) \u222a (S1 \u2229 S2) \u222a (S2 \u2296 S1)");
System.out.printf("%s \u2296 %s \u222a %s \u2229 %s \u222a %s \u2296 %s = %s%n",s1,s2,s1,s2,s2,s1,s1.diff(s2).union(s1.intersect(s2).union(s2.diff(s1))));
//Cartesian Product of s1 and s2
//Cartesian product of s2 and s1
}
}
Any guidance would be appreciated.
I do not understand why you have diffculties, but the cartezian product of Set1 x Set2 could be computed something like this:
Product = {}
Set1. iterate with i
Set2.iterate with j
Product.append (pair(i,j))
If you still have difficulties, please tell me to code it in Java. For now I posted only the pseudocode.
Related
This question already has answers here:
What does a "Cannot find symbol" or "Cannot resolve symbol" error mean?
(18 answers)
Closed 3 years ago.
I am not able to print out the info of the candy bar. Whenever I try to use the method I get an error: cannot find symbol-method printINFO.
I have tried using n.printInfo() and system.out.println(n.printinfo()), but still it doesnt work. What can I do?
Method class:
public class CandyBar
{
public enum Color
{
BLUE, BROWN, GOLD, GREEN, ORANGE,
PURPLE, RED, SILVER, WHITE, YELLOW
}
// instance variables
private String name;
private double weight;
private Color wrapper;
/**
* Constructor for objects of class CandyBar
*/
public CandyBar(String n, Color c, double w)
{
this.name = n;
this.weight = w;
this.wrapper = c;
}
public String getName()
{
return this.name;
}
public double getWeight()
{
return this.weight;
}
public Color getWrapperColor()
{
return this.wrapper;
}
public void printInfo()
{
System.out.println(this.name);
System.out.printf("%.1f oz with a ", this.weight);
System.out.println(this.wrapper + " wrapper");
}
}
Main class:
import java.util.ArrayList;
public class Lab16
{
public static void main(String[] args)
{
ArrayList<CandyBar> bars = new ArrayList<CandyBar>();
addCandyBarsToList(bars);
/**
* Use the methods you wrote below to answer all of
* the following questions.
*/
/**
* Part A:
*/
/**
* Is Twix in the list?
* If so, print all information about it.
* If not, print a message to the user.
*/
/**
* Is Mounds in the list?
* If so, print all information about it.
* If not, print a message to the user.
*/
/**
* Part B:
*/
/**
* Print all the names of candy bars with yellow wrappers.
*/
/**
* Part C:
*/
/**
* Count how many candy bars are 1.75 oz or more.
*/
/**
* Part D:
*/
/**
* Is there a candy bar that is 1.86 oz?
* If so, print the information.
* If not, print a message to the user.
* Write a binary search method to get the answer.
*/
}
/**
* This method searches a list to find a candy bar by name.
*
* #param list the list to search
* #param n a name to find
* #return the index of the candy bar
*/
public static int findCandyBar(ArrayList<CandyBar> list, String n)
{
for(int i = 0; i < list.size(); i++){
if(list.get(i).getName() == n){
return n.printInfo(i);
}else{
System.out.println("The list doesnt have that Candy");
}
}
return 1;
}
/**
* This method prints the names of the candy bars that have a certain
* wrapper color.
*
* #param list the list to search
* #param c the color wrapper to find
*/
public static void findByColor(ArrayList<CandyBar> list, CandyBar.Color c)
{
}
/**
* This method counts the number of candy bars that weigh greater than
* or equal to the weight input parameter.
*
* #param list the list to search
* #param w the weight to compare to
* #return the count of candy bars
*/
public static int countByWeight(ArrayList<CandyBar> list, double weight)
{
return 0;
}
/**
* This method searches a list using binary search.
*
* #param list the list to search
* #param first the first index
* #param last the last index
* #param w the value to search for
* #return the index of the candy bar
*/
public static int binaryFind(ArrayList<CandyBar> list, int first, int last, double w)
{
return -1;
}
/**
* This method adds candy bars to a list.
*
* #param list the list to add to
*/
public static void addCandyBarsToList(ArrayList<CandyBar> list)
{
CandyBar kitkat = new CandyBar("KitKat", CandyBar.Color.RED, 1.5);
list.add(kitkat);
CandyBar grand = new CandyBar("One-hundred Grand", CandyBar.Color.RED, 1.5);
list.add(grand);
CandyBar crunch = new CandyBar("Crunch", CandyBar.Color.BLUE, 1.55);
list.add(crunch);
CandyBar hershey = new CandyBar("Hershey", CandyBar.Color.BROWN, 1.55);
list.add(hershey);
CandyBar krackel = new CandyBar("Krackel", CandyBar.Color.RED, 1.55);
list.add(krackel);
CandyBar caramello = new CandyBar("Caramello", CandyBar.Color.PURPLE, 1.6);
list.add(caramello);
CandyBar what = new CandyBar("Whatchamacallit", CandyBar.Color.YELLOW, 1.6);
list.add(what);
CandyBar almond = new CandyBar("Almond Joy", CandyBar.Color.BLUE, 1.61);
list.add(almond);
CandyBar goodbar = new CandyBar("Mr. Goodbar", CandyBar.Color.YELLOW, 1.75);
list.add(goodbar);
CandyBar twix = new CandyBar("Twix", CandyBar.Color.GOLD, 1.79);
list.add(twix);
CandyBar henry = new CandyBar("Oh Henry", CandyBar.Color.YELLOW, 1.8);
list.add(henry);
CandyBar milkyWay = new CandyBar("Milky Way", CandyBar.Color.GREEN, 1.84);
list.add(milkyWay);
CandyBar payDay = new CandyBar("PayDay", CandyBar.Color.ORANGE, 1.85);
list.add(payDay);
CandyBar snickers = new CandyBar("Snickers", CandyBar.Color.BLUE, 1.86);
list.add(snickers);
CandyBar butterfinger = new CandyBar("Butterfinger", CandyBar.Color.YELLOW, 1.9);
list.add(butterfinger);
CandyBar musketeers = new CandyBar("Three Musketeers", CandyBar.Color.SILVER, 1.92);
list.add(musketeers);
CandyBar reeses = new CandyBar("Reese's FastBreak", CandyBar.Color.ORANGE, 2);
list.add(reeses);
CandyBar babyRuth = new CandyBar("Baby Ruth", CandyBar.Color.SILVER, 2.1);
list.add(babyRuth);
}
}
The printInfo() method is declared on the CandyBar object, but here you are trying to call printInfo() on a String object. This method does not exist on String.
/**
* This method searches a list to find a candy bar by name.
*
* #param list the list to search
* #param n a name to find
* #return the index of the candy bar
*/
public static int findCandyBar(ArrayList<CandyBar> list, String n)
{
for(int i = 0; i < list.size(); i++){
if(list.get(i).getName() == n){
return n.printInfo(i); <-- calling n.printInfo(i) will not work as printInfo() does not exist on String
You instead need to pay attention to the method signature of printInfo():
It exists on CandyBar, not on String.
It does not accept any parameter arguments.
It is a void method, i.e. does not return an object.
So instead of:
return n.printInfo(i);
Use this:
i.printInfo();
I was given the following code to return an enumeration of the elements of a dictionary.
public class ArrayDictionary extends Dictionary implements Cloneable {
protected Object[] keys ;
protected Object[] values;
protected int incr;
protected int nelems;
public Enumeration elements() {
return new ArrayEnumeration(values,nelems);
}
ArrayEnumeration is not defined within the rest of the code, none of the methods that are defined take an Array of Objects[] and an int, we're expected to do code inspection, and the way the question is written implies we shouldn't add new methods, I'll post the full code below. The only solution my friend and I can come up with is using a for loop to go through each item in the dictionary and use the get method that is defined?
Edit: There may be many other errors in the code we've not been through it all yet, as we can't get round this problem.
public class ArrayDictionary extends Dictionary implements Cloneable {
/** The array of keys */
protected Object[] keys ;
/** The array of corresponding values */
protected Object[] values ;
/** How many real elements are in */
protected int nelems ;
/** By how much to grow */
protected int incr ;
/**
* Create an ArrayDictionary using default values for initial size and
* increment.
*/
public ArrayDictionary() {
this(10,10) ;
}
/**
* Create an ArrayDictionary using the given initial size.
* (The increment is set to the same value).
* #param init The initial size
*/
public ArrayDictionary(int init) {
this(init,init) ;
}
/**
* Clone this array dictionary.
* <p>As for hashtables, a shallow copy is made, the keys and elements
* themselves are <em>not</em> cloned.
* #return The clone.
*/
public Object clone() {
try {
ArrayDictionary cl = (ArrayDictionary) super.clone();
cl.values = new Object[values.length];
System.arraycopy(values, 0, cl.values, 0, values.length);
cl.keys = new Object[values.length];
System.arraycopy(keys, 0, cl.keys, 0, keys.length);
return cl;
} catch (CloneNotSupportedException ex) {
throw new InternalError();
}
}
/**
* Create an ArrayDictionary using the given initial size and
* the given increment for growing the array.
* #param init the initial size
* #param incr the increment
*/
public ArrayDictionary(int init, int incr) {
keys = new Object[init] ;
values = new Object[init] ;
this.incr = incr ;
nelems = 0 ;
}
/**
* Create an ArrayDictionary, contructing the arrays of keys and
* values from the two given vectors.
* The two vectors should have the same size.
* The increment is set to the number of elements.
* #param keys the vector of keys
* #param values the vector of values
*/
public ArrayDictionary(Vector keys,Vector values) {
this(keys,values,values.size()) ;
}
/**
* Create an ArrayDictionary, contructing the arrays of keys and
* values from the two given vectors.
* The two vectors should have the same size.
* #param keys the vector of keys
* #param values the vector of values
* #param incr the increment for growing the arrays
*/
public ArrayDictionary(Vector keys, Vector values, int incr) {
this.incr = incr ;
nelems = keys.size() ;
this.keys = new Object[nelems] ;
this.values = new Object[nelems] ;
keys.copyInto(this.keys) ;
values.copyInto(this.values) ;
}
/**
* Create an ArrayDicitonary, <em>using</em> (not copying) the given pair
* of arrays as keys and values. The increment is set to the length of the
* arrays.
* #param keys the array of keys
* #param values the array of values
*/
public ArrayDictionary(Object[] keys, Object[] values) {
this(keys,values,values.length) ;
}
/**
* Create an ArrayDicitonary, <em>using</em> (not copying) the given pair
* of arrays as keys and values.
* #param keys the array of keys
* #param values the array of values
* #param incr the increment for growing the arrays
*/
public ArrayDictionary(Object[] keys, Object[] values, int incr) {
this.incr = incr ;
nelems = keys.length ;
this.keys = keys ;
this.values = values ;
}
protected final void grow() {
grow(keys.length+incr) ;
}
protected void grow(int newCapacity) {
Object[] newKeys = new Object[newCapacity] ;
Object[] newVals = new Object[newCapacity] ;
System.arraycopy(keys,0,newKeys,0,keys.length) ;
System.arraycopy(values,0,newVals,0,values.length) ;
keys = newKeys ;
values = newVals ;
}
/**
* Returns an enumeration of the elements of the dictionary.
* #return the enumeration
*/
public Enumeration elements() {
return new ArrayEnumeration(values,nelems);
}
/**
* Returns the value that maps to the given key.
* #param key the key
* #return the value
*/
public Object get(Object key) {
int n,i;
for(i=0,n=0;i<keys.length;i++) {
if(n >= nelems)
break ;
if ( keys[i] == null )
continue;
if(keys[i].equals(key))
return values[i] ;
n++ ;
}
return null;
}
/**
* "Optimized" method to obtain the values
* corresponding to several keys, in one swoop.
* #param rKeys An array of requested keys
* #return An array of corresponding values
*/
public Object[] getMany(Object[] rKeys) {
Object[] rValues = new Object[rKeys.length] ;
int i,n ;
for(i=0,n=0;i<keys.length;i++) {
if(n >= nelems) break ;
if(keys[i]==null)
continue ;
inloop:
for(int j=0;j<rKeys.length;j++)
if(keys[i].equals(rKeys[j])) {
rValues[j] = values[i] ;
break inloop ;
}
n++ ;
}
return rValues ;
}
/**
* Are there any entries in the dictionary?
* #return <strong>true</strong> if there are no entries,
* <strong>false></strong> otherwise.
*/
public final boolean isEmpty() {
return nelems==0 ;
}
/**
* Increases the capacity of this dictionary to at least the
* specified number of key/value mappings.
* #param minCapacity the desired minimum capacity
*/
public final void ensureCapacity(int minCapacity) {
if(minCapacity>keys.length) grow(minCapacity) ;
}
/**
* Returns an enumeration of the keys of the dictionary.
* #return the enumeration
*/
public Enumeration keys() {
return new ArrayEnumeration(keys,nelems) ;
}
/**
* Adds a mapping between a key and a value to the dictionary.
* Will grow the arrays if necessary.
* #param key the key
* #param value the corresponding value
* #return the previous value corresponding to the key, or null if
* the key is new.
*/
public Object put(Object key,Object value) {
int empty = -1 ;
int i,n ;
for(i=0,n=0;i<keys.length;i++) {
if(n >= nelems)
break ;
if(keys[i] == null) {
empty = i ;
continue ;
}
if(keys[i].equals(key)) {
Object prev = values[i] ;
values[i]=value;
return prev ;
}
n++ ;
}
if(empty!=-1) {
keys[empty]=key ;
values[empty]=value ;
nelems++ ;
} else {
grow() ;
keys[nelems] = key ;
values[nelems++] = value ;
}
return null ;
}
/**
* Removes a key (and its value) from the dictionary;
* #param key the key to remove
* #return the value that used to map to that key
*/
public Object remove(Object key) {
int i,n ;
for(i=0,n=0;i<keys.length;i++) {
if(n >= nelems)
break ;
if(keys[i] == null)
continue ;
if(keys[i].equals(key)) {
nelems-- ;
Object prev = values[i] ;
keys[i] = values[i] = null ;
return prev ;
}
n++ ;
}
return null ;
}
/**
* Returns the number of elements in the dictionary
* #return the number of elements
*/
public final int size() { return nelems ; }
/**
* Returns the maximum number of keys the dictionary can hold
* without reallocating an array.
* #return the capacity of the dictionary
*/
public final int capacity() { return keys.length ; }
/**
* Returns the nth key.
* #param n the index of the desired key
* #return the nth key, or null if no key in that place.
*/
public final Object keyAt(int n) {
return keys[n] ;
}
/**
* Returns the nth element (value).
* #param n the index of the desired element
* #return the nth element, or null if no element in that place.
*/
public final Object elementAt(int n) {
return values[n] ;
}
/**
* Sets the element at the nth place in the array.
* #param n the index of the element to change
* #param newVal the value to change it to
* #return the old value
*/
public Object setElementAt(int n,Object newVal) {
Object prev = values[n] ;
values[n] = newVal ;
return prev ;
}
/**
* Removes the nth mapping (key/value pair) in the dictionary.
* #param n the index of the element to remove
* #return the old value of the element at the nth place
*/
public Object removeElementAt(int n) {
if(values[n]!=null) {
Object prev = values[n] ;
values[n] = keys[n] = null ;
nelems--;
return prev;
} else return null ;
}
/**
* Creates a string representation of the dictionary
* #return the string representation.
*/
public String toString() {
StringBuffer buf = new StringBuffer(100) ;
buf.append('[') ;
for(int i=0;i<keys.length;i++) {
if(keys[i]==null)
continue ;
buf.append(keys[i]) ;
buf.append('=') ;
buf.append(values[i]) ;
buf.append(' ') ;
}
buf.append(']') ;
return buf.toString() ;
}
}
I need to find a fast and efficient way to create unique pairs out of array items if there is more than two of them.
My first question is that this code I came up with is throwing sometimes java.lang.StackOverflowError, why? I know it is going to deep with the recursive calls in the helper, but how to fix it?
My second question is how to make the code more efficient. I don't need to use array - it could be some other collection type.
This is what I have come up with:
import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom;
/**
* Generates unique pairs from items in array. Each item cannot occur more than
* once as key nor value.
*
* #author lkallas
*/
public class UniquePairs {
private static final String[] NAMES
= new String[]{"Aaron", "Barney", "Charlie", "Desiré", "Edward"};
private static final HashMap<String, String> PAIRS = new HashMap<>();
public static void main(String[] args) {
// Check if there is more than one item in array.
if (NAMES.length > 1) {
// Find pairs
for (String name : NAMES) {
if (!PAIRS.containsKey(name)) {
PAIRS.put(name, helper(name));
}
}
// Show results.
PAIRS.entrySet().stream().forEach((pair) -> {
System.out.println(pair.getKey() + " - " + pair.getValue());
});
} else {
System.out.println(NAMES[0]);
}
}
/**
* Helper for finding partner.
*
* #param key Name that need partner.
* #return Unique partner.
*/
private static String helper(String key) {
// Get random partner from array.
String partner = NAMES[getRandomInt(0, NAMES.length - 1)];
// Cannot pair up a name with itself. Also partner cannot occur more than once.
if (key.equals(partner) || PAIRS.containsValue(partner)) {
partner = helper(key);
}
return partner;
}
/**
* Random integer in the given range.
*
* #param min Minimum value of the random integer.
* #param max Maximum value of the random integer.
* #return Random integer in given range.
*/
private static int getRandomInt(int min, int max) {
return ThreadLocalRandom.current().nextInt(min, max + 1);
}
}
EDIT:
Using
return ThreadLocalRandom.current().nextInt(min, max + 1);
instead of
return new Random().nextInt((max - min) + 1) + min;
EDIT 2:
Created special class for this kind of operation. Feel free to use it if necessary.
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
/**
*
* #author lkallas
*/
public class MatchMaker {
private final Map<Object, Object> PAIRS;
private List<? extends Object> items;
public MatchMaker() {
this.PAIRS = new HashMap<>();
}
/**
* Pairs items uniquely and randomly so that keys nor values are repeated.
* For proper pairing of Objects it is recommended to provide your own
* implementation of <code>equals()</code> method. Also bear in mind that
* you should also override <code>hashCode()</code> if there's any chance of
* your objects being used in a hash table.
*
* #param input List with objects that are paired with each other.
* #return Map with generated pairs.
* #throws IllegalArgumentException When input List is empty or contains
* only one item.
*/
public Map<?, ?> getPairs(List<? extends Object> input)
throws IllegalArgumentException {
if (input.size() > 1) {
items = input;
for (int i = 0; i < input.size() - 1; i++) {
Object k = input.get(i);
PAIRS.put(k, getPartner(k));
}
Object k = items.get(items.size() - 1);
if (PAIRS.containsValue(k)) {
PAIRS.put(k, getPartner(k));
} else {
Object k1 = items.get(getRandomInt(0, items.size() - 1));
PAIRS.put(k, PAIRS.get(k1));
PAIRS.put(k1, k);
}
} else {
throw new IllegalArgumentException("Can't pair one or less items.");
}
return PAIRS;
}
/**
* Helper for finding a random partner.
*
* #param key Object that needs partner.
* #return Unique partner that is not used by other keys.
*/
private Object getPartner(Object key) {
// Get random partner from array.
Object partner = items.get(getRandomInt(0, items.size() - 1));
// Cannot pair up a key with itself. Also partner cannot occur more than once.
if (key.equals(partner) || PAIRS.containsValue(partner)) {
partner = getPartner(key);
}
return partner;
}
/**
* Random integer in the given range.
*
* #param min Minimum value of the random integer.
* #param max Maximum value of the random integer.
* #return Random integer in given range.
*/
private static int getRandomInt(int min, int max) {
return ThreadLocalRandom.current().nextInt(min, max + 1);
}
}
Change this
for (String name : NAMES) {
if (!PAIRS.containsKey(name)) {
PAIRS.put(name, helper(name));
}
}
to
for (int i = 0; i < NAMES.length - 1; i++) {
String name = NAMES[i];
PAIRS.put(name, helper(name));
}
String name = NAMES[NAMES.length - 1];
if (PAIRS.containsValue(name)) {
PAIRS.put(name, helper(name));
} else {
String otherKey = NAMES[ThreadLocalRandom.current().nextInt(0, NAMES.length - 1)];
PAIRS.put(name, PAIRS.get(otherKey));
PAIRS.put(otherKey, name);
}
What's going on with your version is explained in this answer. Essentially, you are running out of options at the last step, so helper calls itself repeatedly until a StackOverflowError occurs.
It seems that 20 regiments were in a continuous process of formation. The first had 1000 men, the second had 950, the third 900, and so on down to the twentieth regiment, which garrisoned only 50. During each week, 100 men were added to each regiment, and at week's end, the largest regiment was sent off to the front.This lasted for a total of 20 weeks.
For this program I have already managed to print out the original number of men for each regiment. But I am having difficult adding 100 men to each regiment.The adding men must be a method in the army class. I am getting the regiment objects using a .txt file. All this files contains is the names of regiments numbered 1-20.
public class Regiment {
private String name; //name of regiment
private int regNumber; //regiment number
private int men; // regiment men
/**
* Creates a Regiment object.
*
* #param regNumber the regiment number
* #param name the name of the regiment
* #param men the number of men in a regiment
*/
public Regiment(int regNumber, String name, int men) {
this.name = name;
this.regNumber = regNumber;
this.men = men;
}
/**
* Returns the name of the regiment.
*
* #return the regiment name
*/
public String getName() {
return name;
}
/**
* Returns the number of the regiment.
*
* #return regiment number
*/
public int getregNumber() {
return regNumber;
}
/**
* Returns the number of men in a regiment.
*
* #return men in regiment
*/
public int getMen() {
return men;
}
/**
* Computes the number of men in a regiment
*/
public int addMen2(int RegNumber) {
int men = 1050 - (regNumber * 50);
return men;
}
}
class ArmyDataList {
public ArrayList<Regiment> list; // list of regiment objects
/**
* Creates an empty list
*/
public ArmyDataList() {
list = new ArrayList<Regiment>();
}
/**
* Appends a regiment object to the list.
*
* #param current the object to be appended to the list
*/
public void AddToList(Regiment current) {
list.add(current);
}
/**
* Removes a regiment object to the list.
*
* #param current the object to be removed from the list
*/
public void RemoveFromList(Regiment current) {
list.remove(current);
}
/**
* Gets the largest regiment based on men.
*/
public Regiment getLargest() {
if (list.isEmpty()) {
return null;
}
Regiment Reg1 = list.get(0);
for (int i = 1; i < list.size(); i++) {
Regiment current = list.get(i); // get next regiment
// is current regiment > largest
if (current.getMen() > Reg1.getMen()) {
Reg1 = current;
}
}
return Reg1;
}
/**
* Adds men to each regiment.
*/
public void addMen() {
}
/**
* Converts the list to a multi-line string, with each line containing the
* data for one regiment.
*
* #return the String containing all the data on the list
*/
public String toString() {
String out
= String.format("%28s%12s%n", "Regiments", " Men")
+ String.format("%12s%n", "Number")
+ String.format("%12s%16s%14s%n", "=======", "===============",
"=========");
for (int i = 0; i < list.size(); i++) {
Regiment regim = list.get(i);
int regNumber = regim.getregNumber();
String name = regim.getName();
int men = regim.addMen2(regNumber);
out = out + String.format("%12s", regNumber)
+ String.format("%16s", name)
+ String.format("%10s", men)
+ "\n";
}
return out + "\n";
}
}
public class RegimentTest {
public static void main(String[] args) throws IOException
{
ArmyDataList army = new ArmyDataList();
// create Scanner object to read each line of file until eof
Scanner fileScan = new Scanner(new File("regiments.txt"));
System.out.println("Report Summary:\n");
while (fileScan.hasNext()) // while not eof...
{
// read next line
String line = fileScan.nextLine();
// "echo print" data entered
System.out.println(line);
// 1. create a Scanner object
Scanner in = new Scanner(line) ;
// 2. extract tokens from current line
int regNumber = in.nextInt();
String name = in.next();
int men = 0 ; //men is set to 0 only because I havent add the men yet
// 3. create Regiment object passing the tokens to the constructor
Regiment adder = new Regiment(regNumber, name, men );
// 4. add object to list
army.AddToList(adder) ;
}
System.out.println(army.toString());
}
You can write addNewMen() method in Regiment Class where you can add 100 more men as men is the property of regiment.
package edu.tests.model;
/**
* TestResult represents the grade on a test for one student.
*
* #author
* #version
*/
public class TestResult {
private String id;
private int grade;
/**
* Creates a new instance of TestResult with the specified
* ID of the student who took the test and the grade the
* student earned.
*
* #requires id != null && id.length() > 0 && grade >= 0
* #ensures getId().equals(id) && getGrade() == grade
*
* #param id the student's ID
* #param grade the student's grade on the test
*/
public TestResult(String id, int grade) {
this.id = id;
this.grade = grade;
}
/**
* Returns the ID of the student.
*
* #requires nothing
*
* #return the student's ID
*/
public String getId() {
return this.id;
}
/**
* Returns the grade earned by the student.
*
* #requires nothing
*
* #return the student's test grade
*/
public int getGrade() {
return this.grade;
}
/**
* Returns true if the specified object is a TestResult instance
* with the same student ID, and false otherwise.
*
* #requires nothing
*
* #return true iff someObject is a TestResult with the same student ID
*/
#Override
public boolean equals(Object someObject) {
if (this == someObject) {
return true;
}
if (someObject == null) {
return false;
}
if (this.getClass() != someObject.getClass()) {
return false;
}
TestResult aTestResult = (TestResult) someObject;
return this.getId().equals(aTestResult.getId());
}
}
package edu.westga.tests.model;
import java.util.ArrayList;
/**
* Gradebook represents the test results for all students who took a test.
*
* #author
* #version
*/
public class Gradebook {
// TODO #1: declare an instance variable called results, which is an
// ArrayList of TestResult objects
ArrayList<TestResult> results;
/**
* Creates a new Gradebook object with no test results.
*
* #requires nothing
* #ensures size() = 0
*/
// TODO#2: implement a constructor with 0 parameters that
// initializes the instance variable as an empty ArrayList
public Gradebook() {
this.results = new ArrayList<TestResult>();
}
/**
* Returns the number of test results that have been added to this
* Gradebook.
*
* #requires nothing
*
* #return how many test results this Gradebook records
*/
// TODO#3: implement the method size, which returns an int and takes
// 0 parameter
public int size() {
return this.results.size();
}
/**
* Adds the specified test result to this Gradebook.
*
* #requires aResult != null && !contains(aResult)
* #ensures size() == size()#prev + 1 && contains(aResult)
*
* #param aResult
* the test result to add to this Gradebook
*/
// TODO#4: implement the method add, with 1 parameter called aResult of type
// TestResult
// Please read the comments for the method to understand what it does
public int add(TestResult aResult) {
return this.add(aResult);
}
/**
* Returns true if a TestResult with the same ID as the specifed test result
* has previously been added to this Gradebook, and false otherwise.
*
* #requires aResult != null
*
* #return true iff the aResult has the same ID as a TestResult that has
* already been added
*
* #param aResult
* the test result to check
*/
// TODO#5: implement the method contains, which returns a boolean
// and takes 1 parameter of type TestResult
public boolean contains(TestResult aResult) {
return this.contains(aResult);
}
/**
* Returns the average grade of the test results that have been added to
* this Gradebook, or 0 if none have been added.
*
* #requires nothing
*
* #return the mean grade
*/
// TODO#6: implement method averageGrade, which returns an int
// and takes 0 parameters
public int averageGrade() {
for (int i = 0; i < results.size(); i++);
{
TestResult theResult = results.get(i);
int averageGrade = theResult.getGrade();
}
}
}
Hey everyone, I am trying to write a for-each loop which will return the average grade of the test results that have been added to the grade book. I am new to writing these loops so bear with me, but I am getting a compile error on the results.get when I put the i in the brackets of the get method. I was thinking that I had it right, I obviously do not, so any help is greatly appreciated. Thanks in advance,
you have
for (int i = 0; i < results.size(); i++);
{
TestResult theResult = results.get(i);
int averageGrade = theResult.getGrade();
}
You can't have a semicolon after the for loop, and you need to return an int... so you most likely need need
int averageGrade;
for (int i = 0; i < results.size(); i++)
{
TestResult theResult = results.get(i);
averageGrade = theResult.getGrade();
}
return averageGrade;
They way to have it, Java thinks the For loop is on it's own. Then it sees these random braces and is very confused about why they are there, hence a compile time error. It also thinks your going to return an int, and you don't so it gets confused again.
First, I doubt your code compiles since your averageGrade() method does not return anything...
Try this one:
public int averageGrade() {
int totalGrade=0;
int i = 0;
for (; i < results.size(); i++);
{
TestResult theResult = results.get(i);
totalGrade += theResult.getGrade();
}
if (i>0)
return totalGrade/i;
else return 0;
}