Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Program Background Usage of a Linked List is similar to that of the Array List. Like the Array List, it is a linear collection of

Program Background

Usage of a Linked List is similar to that of the Array List. Like the Array List, it is a linear collection of data, however elements are stored in "nodes" and connected by reference "links". This allows the Linked List to be dynamic, growing and shrinking as use demands with no unused memory allocated.

A Stack is a Linear, Restricted Data Structure. A Restricted Data Structure is one whose operations and accesses are limited to better serve the problem it is being used to solve. Unlike Array Lists and Linked Lists, which allow arbitrary access to all elements, a Stack can only manipulate one end of the structure, referred to as the "Top".

Program Description

A molecule is a grouping of two or more atoms. A molecule can be written as a sequence of the symbols of its atoms. For example, H denotes an atom of hydrogen, C denotes an atom of carbon, and O denotes an atom of oxygen. Formic Acid is defined by the sequence HCOOH, which is a hydrogen, carbon, oxygen, oxygen, hydrogen atoms. If a digit is placed after a symbol it means there are that many of those atoms in the molecule, such as water, H2O is two hydrogen atoms and an oxygen. Digits can also be placed after groupings such as (CH)3 which is three carbon/hydrogen groupings, (CH)(CH)(CH). The weight of a molecule is simply the weight of all the atoms in it. Given the weight of hydrogen is 1, carbon is 12, and oxygen is 16, Formic Acid has a weight of 46, Water has a weight of 18, and (CH)3 has a weight of 39. More complex molecules sequences can be created by nesting groupings such as H((OH)2C3H)2, which has a weight of 143.

Parenthesis and other types of braces must follow pairing rules in order for an expression to be valid. Stacks are often used for processing of parenthesis in text, such as compilers making sure braces match up correctly. A Stack can also be used to evaluate parenthesized expressions like molecules.

Every opening and closing parenthesis must have a matching of the other. It is also important to note that in valid text, the matching opening parenthesis to a closing one is last one encountered. This is what makes the Stack the perfect structure for such problems. Open parenthesis signify the beginning of a grouping, allowing nested groupings to be added to the stack. Once a closing parenthesis is reached it closes the group at the top of the Stack, which can then be evaluated.

Attempting to create molecule's with invalid sequences will result in one of two Exceptions occuring. Sequences with unpaired parenthesis will result in an InvalidSequenceException. For example, the following are invalid:

)(HOC)2

(OH

(((H))))

Additionally, only letters that represent a known atom should be in the sequence. To make things a bit easier, you will only be using Hydrogen, Carbon, and Oxygen with symbols (upper and lower case allowed) and weights described above. A sequence with any other atoms will cause an InvalidAtomException. Both of these cases can be determined while calculating the weight using the algorithm described below.

A Stack of Integers can be used to compute the weight of a molecule whose sequence is stored in a String. To allow for nested groupings, you will need to add something that represents an open parenthesis to the Integer Stack in addition to weights. Since all atom weights are positive, use a -1 to indicate an open parentheis on the Stack. The step-by-step algorithm is given below:

Create a Stack of Integers

Create a new sequence String with ( ) surrounding it (if original sequence is H20, create new local String (H20), DO NOT change the original sequence data member

For each character in the new sequence String from left to right do the following:

If the character is an open parenthesis push it onto the Stack

If the character is an atom push its weight onto the Stack

If the character is a digit pop the top value off the Stack and multiply this by the digit, push the result onto the Stack

If the character is a close parenthesis pop all values off the Stack, summing them up as you go until an open parenthesis is reached, pop the open parenthesis off the Stack, push the sum onto the Stack

The final weight will be the only item left on the Stack once all characters have been processed IF the sequence was valid. If there are additional items on the Stack then the sequence was improperly formed.

This assignment will have you creating a program that collects molecules and reports their weights. Further, collections of molecules can be stored and restored by the user.

This is the driver that runs my two classes, DO NOT CHANGE IT:

package molecule;

import molecule.exceptions.InvalidAtomException;

import molecule.exceptions.InvalidSequenceException;

import java.util.Iterator;

import java.util.LinkedList;

import java.util.Scanner;

import java.util.InputMismatchException;

/**

* Menu driven interface for the use of a Molecule Collection.

* @author Mr. Cavanaugh

*/

public class MoleculeDriver

{

/**

* Scanner for user input.

*/

private static Scanner input = new Scanner(System.in);

/**

* Enumerated type representing menu options.

*/

private enum MenuSelection

{

/**

* Corresponds to "Add Molecule" menu option.

*/

ADD,

/**

* Corresponds to "Change Molecule" menu option.

*/

CHANGE,

/**

* Corresponds to "Calculate Total Weight" menu option.

*/

WEIGHT,

/**

* Corresponds to "Store List" menu option.

*/

STORE,

/**

* Corresponds to "Output Stored List" menu option.

*/

OUTPUT_STORE,

/**

* Corresponds to "Restore List" menu option.

*/

RESTORE,

/**

* Corresponds to "Exit" menu option.

*/

EXIT

};

/**

* MoleculeCollection maintained by the application.

*/

private static MoleculeCollection molecules = new MoleculeCollection();

/**

* Reference to a stored list of Molecules.

*/

private static LinkedList storedList;

/**

* Program entry point.

* @param args Not use

*/

public static void main(String[] args)

{

//For user input

MenuSelection menuChoice;

//Display menu options until user quits

do

{

//Output current Molecules in list

System.out.println("***CURRENT MOLECULES***");

printMoleculeList(molecules.getMoleculeList());

//Display menu and retrieve choice

menuChoice = menu("Add Molecule", "Change Molecule", "Calculate Total Weight",

"Store List", "Output Stored List", "Restore List", "Exit");

//Perform action based on user choice

switch (menuChoice)

{

case ADD:

addMolecule(); //Add a Molecule to the list

break;

case CHANGE:

changeMolecule(); //Update a Molecule's sequence

break;

case WEIGHT:

totalWeight(); //Report total weight of all Molecules

break;

case STORE:

storeList(); //Store the current list

break;

case OUTPUT_STORE:

System.out.println("***STORED MOLECULES***");

printMoleculeList(storedList); //Output Molecules in stored list

break;

case RESTORE:

restoreList(); //Restore saved list

break;

case EXIT:

break; //Exit program

default: //This shouldn't ever happen but Checkstyle demanded it

System.out.println("***INVALID MENU SELECTION");

break;

}

} while (menuChoice != MenuSelection.EXIT);

}

/**

* Outputs a numbered list of all Molecules in a LinkedList of Molecules.

* @param printList List of Molecules to be printed

*/

public static void printMoleculeList(LinkedList printList)

{

//Make sure the list is populated

if (printList != null && printList.size() != 0)

{

//Iterator to traverse the list

Iterator itr = printList.iterator();

//While there are more items in the list

for (int i = 1; itr.hasNext(); i++)

{

//Output number in list and the next Molecule

System.out.printf("%d. %s ", i, itr.next());

}

}

//No Molecules to output

else

{

System.out.println("***NO MOLECULES IN LIST***");

}

System.out.println();

}

/**

* Prompts user for sequence of a new Molecule and adds it to the list if valid.

*/

private static void addMolecule()

{

//For user input

String sequence;

//Prompt user and retrieve sequence

System.out.print("***ADD MOLECULE*** Enter Sequence: ");

sequence = input.next();

try

{

//Attempt to create and add Molecule to collection

molecules.addMolecule(new Molecule(sequence));

}

catch (InvalidSequenceException | InvalidAtomException ise) //Sequence was invalid

{

System.out.printf("***ERROR: %s, Molecule Not Added*** ", ise.getMessage());

}

/* catch (InvalidAtomException iae) //Sequence contained unknown atom

{

System.out.println("***ERROR: Invalid Atom used, Molecule Not Added***");

}*/

System.out.println();

}

/**

* Prompts user for Molecule number to update and new sequence for that Molecule.

* If the new sequence is invalid the original Molecule should be retained.

*/

private static void changeMolecule()

{

//For user input

int changeIndex;

String newSequence;

try

{

//Get index of Molecule to update

System.out.print("***CHANGE MOLECULE*** Enter Molecule Number: ");

changeIndex = input.nextInt();

//Get new sequence

System.out.print("Enter New Sequence: ");

newSequence = input.next();

//Attempt to change sequence at entered index

molecules.changeSequence(changeIndex - 1, newSequence);

}

//int not give for index or index not in bounds

catch (InputMismatchException | IndexOutOfBoundsException ex)

{

System.out.println("***ERROR: Invalid Input For Molecule Number***");

}

//Provided sequence was invalid

catch (InvalidSequenceException | InvalidAtomException ise) //Sequence was invalid

{

System.out.printf("***ERROR: %s, Original Molecule Retained*** ", ise.getMessage());

}

System.out.println();

}

/**

* Reports total weight of all Molecules in collection.

*/

private static void totalWeight()

{

System.out.printf("***TOTAL WEIGHT*** Weight of All Molecules is %d ", molecules.moleculeWeights());

}

/**

* Stores a copy of the current list of Molecules.

*/

private static void storeList()

{

storedList = molecules.getMoleculeList();

System.out.println("***CURRENT MOLECULE LIST STORED***");

System.out.println();

}

/**

* Reverts the MoleculeCollection to the stored list.

*/

public static void restoreList()

{

//Make sure a list is stored

if (storedList != null)

{

//Create a new MoleculeCollection with the stored list

molecules = new MoleculeCollection(storedList);

//Stored list is not retained

storedList = null;

System.out.println("***STORED MOLECULE LIST RESTORED***");

}

else //No list is stored

{

System.out.println("***ERROR: No List Stored***");

}

System.out.println();

}

/**

* Utility class for retrieving menu option from player, allows for different menus via variable length

* argument list.

* @param options List of Strings in the menu.

* @return Player's menu choice.

*/

private static MenuSelection menu(String... options)

{

//Variable for player input

int choice = 0;

System.out.println("***MENU***");

//Output all menu options

for (int line = 0; line < options.length; line++)

{

System.out.printf("%d. %s ", line + 1, options[line]);

}

//Attempt to retrieve player choice, validates input is in range.

do

{

try

{

System.out.print("Enter Choice: ");

choice = input.nextInt();

}

catch (InputMismatchException ime)

{

input.nextLine();

}

} while (!(choice > 0 && choice <= options.length));

return MenuSelection.values()[choice - 1];

}

}

This is my code that I have that needs to work with all of the menu interactions:

package molecule;

import molecule.exceptions.InvalidAtomException;

import molecule.exceptions.InvalidSequenceException;

import java.util.Stack;

import java.util.Iterator;

/**

* Objects of the Molecule class represent a single chemical molecule

* made up of any number of hydrogen, carbon, and oxygen atoms.

*

*/

public class Molecule implements java.lang.Comparable, java.lang.Cloneable

{

/**

* Variable to store the total weight of the sequence.

*/

private int weight;

/**

* A String to represent the sequence of molecules.

*/

private java.lang.String sequence;

/**

* Creates a new Molecule made up of the H, C, and O atoms in the configuration specified by sequenceIn.

* @param sequenceIn The sequence of atoms for this Molecule.

* @throws InvalidAtomException - if any non C, H, O atom exists in sequenceIn

* @throws InvalidSequenceException - if unmatched parentheses exist in sequenceIn

*/

public Molecule(java.lang.String sequenceIn) throws InvalidAtomException, InvalidSequenceException

{

setSequence(sequenceIn);

}

/**

* Updates the sequence of atoms represented by this Molecule.

* @param sequenceIn The new molecular sequence to be used for this Molecule.

* @throws InvalidAtomException - if any non C, H, O atom exists in sequenceIn

* @throws InvalidSequenceException - if unmatched parentheses exist in sequenceIn

*/

public void setSequence(java.lang.String sequenceIn) throws InvalidAtomException, InvalidSequenceException

{

sequence = sequenceIn;

weight = getWeight();

}

/**

* Retrieves a String containing this Molecule's sequence of atoms.

* @return Molecular sequence of the Molecule.

*/

public java.lang.String getSequence()

{

return sequence;

}

/**

* Retrieves this Molecule's weight, which is calculated based

* on the Molecule's sequence per the algorithm specified.

* @return Weight of the Molecule.

*/

public int getWeight()

{

Stack moleculeStack = new Stack();

java.lang.String molecule = "(" + sequence + ")";

java.lang.String moleculeCopy = molecule;

Iterator itrStack = moleculeStack.iterator();

int openParen = 0;

int closeParen = 0;

moleculeCopy = moleculeCopy.replace("(", "");

moleculeCopy = moleculeCopy.replace(")", "");

if (moleculeCopy.length() == 0)

{

throw new InvalidSequenceException();

}

moleculeCopy = molecule;

while (moleculeCopy.contains("("))

{

openParen++;

moleculeCopy = moleculeCopy.substring(moleculeCopy.indexOf('(') + 1);

}

moleculeCopy = molecule;

while (moleculeCopy.contains(")"))

{

closeParen++;

moleculeCopy = moleculeCopy.substring(moleculeCopy.indexOf(')') + 1);

}

if (openParen != closeParen)

{

throw new InvalidSequenceException();

}

for (int i = 0; i < molecule.length(); i++)

{

char atom = molecule.charAt(i);

if (atom == '(')

{

moleculeStack.push(-1);

}

else if (Character.isDigit(atom))

{

try

{

int totalAtomWeight = moleculeStack.pop()

* Integer.valueOf(java.lang.String.valueOf(atom));

moleculeStack.push(totalAtomWeight);

}

catch (NullPointerException e)

{

throw new InvalidSequenceException();

}

}

else if (atom == ')')

{

int totalMoleculeWeight = 0;

int item = moleculeStack.pop();

while (item != -1)

{

totalMoleculeWeight += item;

item = moleculeStack.pop();

}

moleculeStack.push(totalMoleculeWeight);

}

else

{

moleculeStack.push(atomWeight(atom));

}

}

return moleculeStack.pop();

}

/**

* Generates and returns a String with the Molecule's sequence and weight.

*/

@Override

public java.lang.String toString()

{

return String.format("%-25s : %", sequence, weight);

}

/**

* Static utility method to return the atomic weight of a given atom.

* @param atom Character for atom abbreviation

* @return Atomic weight of passed atom

* @throws InvalidAtomException Thrown if an unsupported atom is passed

*/

public static int atomWeight(char atom) throws InvalidAtomException

{

int weight = 0;

if (atom == 'H' || atom == 'h')

{

weight = 1;

}

else if (atom == 'C' || atom == 'c')

{

//Magic number is given weight value.

weight = 12;

}

else if (atom == 'O' || atom == 'o')

{

//Magic number is given weight value.

weight = 16;

}

else

{

throw new InvalidAtomException(atom);

}

return weight;

}

/**

* Compares this Molecule to a passed Molecule, determining natural order.

* @param other Incoming Molecule to be compared with this (local) Molecule.

* @return Returns an int less than 0 if the local Molecule is less than the passed Molecule,

* an int greater than 0 if the local Molecule is greater than the passed Molecule,

* and a 0 if the Molecules are equal.

*/

@Override

public int compareTo(Molecule other)

{

int compare;

if (weight < other.weight)

{

compare = -1;

}

else if (weight == other.weight)

{

compare = 0;

}

else

{

compare = 1;

}

return compare;

}

/**

* Returns a deep copy of the Molecule.

* @return Deep copy of the calling Molecule.

*/

@Override

public java.lang.Object clone()

{

Molecule clone = null;

try

{

clone = (Molecule) super.clone();

}

catch (CloneNotSupportedException e)

{

e.printStackTrace();

}

Molecule cloned = new Molecule(clone.sequence);

return cloned;

}

}

package molecule;

import java.util.Collections;

import java.util.Iterator;

import java.util.LinkedList;

import molecule.exceptions.InvalidAtomException;

import molecule.exceptions.InvalidSequenceException;

/**

* A collection of Molecules maintained in a LinkedList.

* Allows for adding, sorting, and updating Molecules in the collection.

*

*/

public class MoleculeCollection

{

/**

* Linked list to hold the collection of molecules.

*/

private LinkedList collection = new LinkedList();

/**

* An iterator to move through the collection.

*/

private Iterator itrColl = collection.iterator();

/**

* Creates a new MoleculeCollection containing no Molecules yet.

*/

public MoleculeCollection()

{

collection.clear();

}

/**

* Creates a new MoleculeCollection based upon an existing list of Molecules.

* @param moleculeListIn LinkedList of Molecules used to create a new MoleculeCollection.

*/

public MoleculeCollection(java.util.LinkedList moleculeListIn)

{

Iterator listIn = moleculeListIn.iterator();

while (listIn.hasNext())

{

collection.add(listIn.next());

}

}

/**

* Adds a copy of a given Molecule to this MoleculeCollection.

* @param add Molecule to be added to the Collection

*/

public void addMolecule(Molecule add)

{

collection.add((Molecule) add.clone());

}

/**

* Reorders the MoleculeCollection based on atomic weight.

*/

public void sort()

{

Collections.sort(collection);

}

/**

* Sums the weights of all Molecules in the MoleculeCollection.

* @return The sum of all weights in the collection

*/

public int moleculeWeights()

{

int total = 0;

while (itrColl.hasNext())

{

total += itrColl.next().getWeight();

}

return total;

}

/**

* Generates and returns a deep copy of a list containing all of the Molecules in this MoleculeCollection.

* @return Deep copy of the Molecules

*/

public java.util.LinkedList getMoleculeList()

{

int index = 0;

Molecule temp;

LinkedList deepCopy = new LinkedList<>();

while (itrColl.hasNext())

{

temp = collection.get(index);

deepCopy.add((Molecule) temp.clone());

index++;

}

return deepCopy;

}

/**

* Changes the sequence of a Molecule in the collection at the specified index.

* @param index Location of the Molecule to update

* @param newSequence New sequence of the specified Molecule

* @throws InvalidAtomException Thrown if the new sequence is invalid due to unknown atom

* @throws InvalidSequenceException Thrown if the new sequence is invalid due to format

*/

public void changeSequence(int index, java.lang.String newSequence)

throws InvalidAtomException,

InvalidSequenceException

{

collection.get(index).setSequence(newSequence);

}

}

package molecule.exceptions;

/**

* Exception used when an unknown atom is encountered.

*/

public class InvalidAtomException extends RuntimeException

{

/**

* Generates an InvalidAtomException with the message: "Invalid Atom Value: ",

* followed by the offending atom character.

* @param atom Character value for atom the cause the Exception

*/

public InvalidAtomException(char atom)

{

super("Invalid Atom Value: " + atom);

}

}

package molecule.exceptions;

/**

* Exception used when it is determined that a Molecule sequence is improperly formatted.

*/

public class InvalidSequenceException extends RuntimeException

{

/**

* Generates and InvalidSequenceException with the message: "Invalid Molecule Sequence".

*/

public InvalidSequenceException()

{

super("Invalid Molecule Sequence");

}

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions