JFormattedTextField | JTable | JSlider |
JRadioButton | JCheckBox | JButton |
JFrame | JPanel | JComponent |
JMenu | JDialog | JContainer |
package extends import virtual method interface type namespaces generic class finally final subtype public Scanner void void * protected subclasses static generational collector composition inheritance iterator stop-and-copy collector Error Throwable Exception RuntimeException IOException event interrupt non-virtual method implements classpath include hotspot compilation import try throw reference counting catch friends polymorphism mark-and-sweep collector Object union vtable setjmp/longjmp
abstract class ExpNode { OperatorNode parent; double value; public abstract double Evaluate(); public double getValue() { return value; } }You might have given consideration to declaring Node as an interface but because it has implementation associated with it, it's better to declare it as an abstract class. It is able to provide a default implementation for getValue (I won't quibble if you declared it abstract) but it must declare Evaluate as pure virtual since every operator node will provide its own implementation. Since the parent is always an interior node, it is correct to declare it as an OperatorNode. I specifically asked you not to include the method bodies in your solution but I am doing so here to make it clear what the default implementations might look like.
All operator nodes have an upToDate variable and use the same implementation for markCacheInvalid and getValue, so it is best to factor out this commonality into an OperatorNode class:
abstract class OperatorNode extends ExpNode { boolean upToDate = false; final void markCacheInvalid() { upToDate = false; if (parent != null) { parent.markCacheInvalid(); } } final public double getValue() { if (!upToDate) { Evaluate(); upToDate = true; } return value; } }Note that this class does not provide an implementation for Evaluate and hence it must be declared abstract. It also overrides the implementation for getValue and hence redeclares it here. I again have provided method bodies to make it clear why I am overriding ExpNode's implementation of getValue and why I am providing an implementation for markCacheInvalid in this class. Also note that I made both methods final as I do not want the subclasses to override their implementation.
An Operand node is a concrete class that can implement the Evaluate method and provides its own SetValue method:
class OperandNode extends ExpNode { public Operand(double val) { value = val; } public double Evaluate() { return value; } public void SetValue(double v) { value = v; parent.markCacheInvalid(); } }There are three types of OperatorNodes and each of these 3 types will use the same constructor for setting up the children pointers, so it is best to factor this common constructor into three different operator node subtypes:
abstract class UnaryOperatorNode extends OperatorNode { ExpNode child; public UnaryOperatorNode(ExpNode parameterNode) { child = parameterNode; child1.parent = this; } } abstract class BinaryOperatorNode extends OperatorNode { ExpNode child1; ExpNode child2; public BinaryOperatorNode(ExpNode param1, ExpNode param2) { child1 = param1; child2 = param2; child1.parent = this; child2.parent = this; } } // An NaryOperator node has two additional methods named addParameter and // removeParameter associated with it and this is common behavior that // should be factored into its class. abstract class NaryOperatorNode extends OperatorNode { ArrayList<ExpNode> children; public NaryOperatorNode(ArrayList<ExpNode> parameters) { children = parameters; for (ExpNode child : parameters) { child.parent = this; } } public void addParameter(ExpNode param) { children.add(param); } public void removeParameter(ExpNode param) { children.remove(param); } }These three classes are abstract because they cannot provide an implementation for the Evaluate method. I would not quibble if you made a binary operator node a subclass of a unary operator node since it is adding an additional child but would reuse the unary operator's child1 variable and constructor.
Finally the PlusNode class is a concrete class that can implement the Evaluate method:
class PlusNode extends BinaryOperatorNode { public PlusNode(ExpNode param1, ExpNode param2) { super(param1, param2); } public double Evaluate() { value = e1.getValue() + e2.getValue(); return value; } }Note that its constructor delegates the construction of the children pointers to the superclass constructor.
java -classpath .:/gov/tn:/com/bvz/ vaccine.Appointment
You need to use the -C flag to "cd" to the appropriate directory and then grab the subdirectory's contents. If you write /gov/tn/vaccine or /com/bvz/gui, then the directories will be represented in the jar file as /gov/tn/vaccine and /com/bvz/gui and the java interpreter will be unable to locate the vaccine/gui directories because it is looking for directories name vaccine/gui and not /gov/tn/vaccine or /com/bvz/gui.
jar -cef vaccine.Appointment Appointment.jar -C /gov/tn vaccine -C /com/bvz/ gui
class Bag<T1,T2> { List<T1> bag1 = new ArrayList<>(); List<T2> bag2 = new ArrayList<>(); public void add(T1 value1, T2 value2) { bag1.add(value1); bag2.add(value2); } public T2 find(T1 value) { int index = bag1.indexOf(value); if (index > 0) return bag2.get(index); else return null; } }
You should use a HashSet to keep track of whether a voter has previously voted and a HashMap to tally the candidate's votes because each of these data structures requires O(1) time to locate a voter/candidate. If you use a SortedSet/Map then your finds will take O(log n) time and if you use an array or linked list, then your finds will take O(n) time. Once you have used the HashMap to tally the candidate's votes, you can dump the map's contents into an ArrayList and sort them into ascending order based on the candidates' vote totals.
I have written this solution in the way that I presented the material in class. However, there are a couple ways to simplify the code:
voteTally.merge(candidateName, 1, Integer::sum);A longer but also very acceptable way to do it is:
if (voteTally.containsKey(candidateName)) { voteTally.put(candidateName, voteTally.get(candidateName) + 1); } else { voteTally.put(candidateName, 1); }
voteCount.sort(Map.Entry.comparingByValue());
import java.util.*; class Vote { public class RepeatVoterException extends Exception { public String voterName; public RepeatVoterException(String name) { voterName = name; } } public static void main(String args[]) { new Vote(); } public Vote() { Set<String> voterList = new HashSet<>(); Map<String, Integer> voteTally = new HashMap<>();; String voterName, candidateName; Scanner console = new Scanner(System.in); String line; boolean readStartOfBallot = true; while (console.hasNextLine()) { line = console.nextLine(); Scanner buffer = new Scanner(line); try { // readStartOfBallot allows the exception handler to know // whether I am processing the first part of the ballot with the voter's // name and the first candidate's name or if I am processing the rest of // ballot with the remaining candidates' names. readStartOfBallot = true; voterName = buffer.next(); candidateName = buffer.next(); // A set's add method returns true if the key is successfully // added to the set and false otherwise if (!voterList.add(voterName)) { throw new RepeatVoterException(voterName); } // read the remaining candidates until the list is exhausted. // The Scanner class will throw a NoSuchElementException when // the list is exhausted readStartOfBallot = false; while (true) { voteTally.put(candidateName, voteTally.getOrDefault(candidateName, 0) + 1); candidateName = buffer.next(); } } catch (NoSuchElementException e) { // ignore the exception if we have reached the end of the // ballot if (readStartOfBallot) { System.out.printf("ballot %s: must have at least one voter and one candidate%n", line); } } catch (RepeatVoterException e) { System.out.printf("voter %s has already voted%n", e.voterName); } finally { buffer.close(); } } // sort the candidate's in ascending order by their vote tally and // print their names/vote counts. List<Map.Entry<String, Integer>> voteCount = new ArrayList<>(voteTally.entrySet()); voteCount.sort(new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) { return e1.getValue() - e2.getValue(); }}); for (Map.Entry<String, Integer> votePair : voteCount) { System.out.printf("%s %d%n", votePair.getKey(), votePair.getValue()); } } }