Question

In: Computer Science

The first part of this lab is making your stack generic. Take the code from your...

The first part of this lab is making your stack generic. Take the code from your working StringStack class and paste it into the GenericStack class. Change the name of the constructors to match the new name of the class (this has been done to this point), then modify the whole class so it uses generics, and can store any type that a programmer asks for.

Until you successfully complete this, the main method will give you nasty compiler errors. Once they stop, you should be good to move on!

Numbers and Readers

To take advantage of polymorphism, Java has a lot of inheritance hierarchies built-in. You may not have known that simple numeric classes, like Integer and Float, are actually part of one! Java contains a generic number class creatively called Number, and pretty much any class in Java whose purpose is to store numbers inherits from this class. (Note that this does not include the primitive int, float, and so on, since there are not classes)

Deep within Java's I/O packages, there's another interesting hierarchy of classes; the Reader and its many children. There are many types of Readers that can extract characters from different things, such as Strings, Files, and arrays. A function that takes in a Reader as a parameter, for example,

Scrolls of Numbers

A few years back, I bought a box of random numbers from an intrepid salesman who insisted they were special. I'd like to find out if that's really the the case. Unfortunately, I've stored the numbers in a bunch of different places - some of them are in Strings, others are in files, it's a bit of a mess.

So I created a generic calculator that, using Readers, can read in a list of numbers from any source, put them into a stack, and then add them all up. Since I'm a good programmer, I put each of these steps in their own functions... but it looks like I accidentally erased some of them. Your next task in the lab is to repair my generic stack calculator by fixing the functions.

  1. makeStack is supposed to take in a Reader, of any kind, and return a stack of Numbers from the data in that Reader. Luckily, the only thing broken here is the function signature - fix it by specifying the appropriate return type, function name, and parameters, using generics if appropriate.
  2. evaluate is supposed to take a stack of Numbers and add all of the numbers together, returning the result as a double. At some point, it looks like I replaced this entire function with a single return 0.0. Whoops. You'll have to re-implement this function as well as re-write its signature, again using generics if appropriate.
    A tip for this function: the Number class can't be directly added to a primitive (like a double, int, etc.) However, a Number object can be converted into a primitive with the use of the doubleValue() function. You may need to use this!
  3. I use the parse function to help with makeStack, but I must have scuffed off the return type at some point. Find the right return type by looking at the function and how it is used in makeStack.

Wrapping up

You'll know when you've successfully completed this lab once you can compile and run the code without errors, and you get output that looks somewhat like this (exact numbers may vary due to floating point rounding):

76.4
76.39999961853027
4584425.0
15.324
-------------------------------------------

package src;

import java.util.*;

public class GenericStack<T> {

/* YOUR CODE HERE

   * Just like in the ArrayList lab, copy your StringStack code, excluding the

   * main method, here.

   * Then, modify it so it's generic!

   */

private String[] stack;

public int size;

public int top;

/* Puts the stack into a valid state, ready for us to call methods on.

* The size parameter tell the... well, size of the stack.

*/

public GenericStack(int size) {

this.top = -1;

this.size=size;

this.stack = new String[size];

}

/* If someone calls the constructor with no argument, they should get a

* stack with a default size of 10.

*/

public GenericStack() {

this.size=10;

this.stack = new String[this.size];

this.top = -1;

}

/* Return true if the stack has no elements, and false otherwise.

*/

public boolean empty() {

return this.top == -1;

}

/* Return the object at the top of the stack, WITHOUT removing it.

* If there are no elements to peek, throw a NoSuchElementException.

*/

public String peek() {

if(this.top == -1) {

throw new NoSuchElementException("Empty stack!");

}

return this.stack[this.top];

}

/* Return the object at the top of the stack, AND ALSO remove it.

* If there are no elements to pop, throw a NoSuchElementException.

*/

public String pop() {

if(this.top == -1) {

throw new NoSuchElementException("Empty stack!");

}

return this.stack[this.top--];

}

/* Add a new object to the top of the stack.

* If there is no room in the stack, throw a IllegalStateException.

*/

public void push(String s) {

if(this.top == this.size-1) {

throw new IllegalStateException("Stack is full!");

}

this.stack[++this.top] = s;

}

/* Return the position of an object on the stack. The position of an object

* is just its distance from the top of the stack. So, the topmost item is

* distance 0, the one below the topmost item is at distance 1, etc.

*/

public int search(String s) {

int distance = 0;

int top = this.top;

while (top >= 0) {

if(this.stack[top] == s) {

return distance;

}

distance++;

--top;

}

return -1;

}

public static void main(String[] args) {

// If any of these lines cause a compilation error, your stack hasn't

// been properly made generic.

GenericStack<Integer> intStack = new GenericStack<>();

GenericStack<String> stringStack = new GenericStack<>();

GenericStack<ArrayList<String>> listStack = new GenericStack<>();

}

}

---------------------------

package src;

import java.util.*;
import java.io.*;
import java.math.*;

public class Calculator {

public static void main(String[] args) throws FileNotFoundException, IOException {

String numbers = "56 3 7 2.0 8.4";
char[] moreNumbers = "1.0 2 3 4 5 0.324".toCharArray();

GenericStack<Number> stack1 = makeStack(new StringReader(numbers));
System.out.println(evaluate(stack1));

GenericStack<Float> stack2 = new GenericStack<>();
for (String token : numbers.split(" ")) {
stack2.push(Float.parseFloat(token));
}
System.out.println(evaluate(stack2));

GenericStack<Number> stack3 = makeStack(new FileReader("numbers.txt"));
System.out.println(evaluate(stack3));

GenericStack<Number> stack4 = makeStack(new CharArrayReader(moreNumbers));
System.out.println(evaluate(stack4));
}
  
/* This function is meant to take in a Reader called "reader" and return a
* stack of Numbers.
*
* Remember: don't change anything that's already there. Just add your new
* code where the comment is to fix the function's signature.
*/
public static /* ??? */ throws IOException {
GenericStack<Number> stack = new GenericStack<>(64);
char[] data = new char[64];
reader.read(data);
String tokens = new String(data);
for (String token : tokens.split(" ")) {
stack.push(parse(token));
}
return stack;
}

/* This function is meant to take in a stack of ANY KIND of Number
* called "stack", and return the double you get if you add all of the
* numbers together.
* The function must be able to accept a stack of ANY KIND of Number!
*
* Hint: use wildcard generics!
*/
public static /* ??? */ {
/* implement me! */
return 0.0;
}

/* This function is missing a return type.
* Examine it, and see if you can tell what type it should return.
* (Spoiler: it's probably what you think it is.)
*/
public static /* ??? */ parse(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) { }

try {
return Double.parseDouble(s);
} catch (NumberFormatException e) { }

return new BigDecimal(s);
}

}

Solutions

Expert Solution

// GenericStack.java

// Make the below changes to GenericStack methods to make it generic

package src;

import java.util.*;

public class GenericStack<T> {
  
   /*
   * Just like in the ArrayList lab, copy your StringStack code, excluding the
   * main method, here.
   * Then, modify it so it's generic!
   */
  
   // convert the array to generic type T
   private T [] stack;
   public int size, top;

   /* Puts the stack into a valid state, ready for us to call methods on.
   * The size parameter tell the... well, size of the stack.  
   */
   public GenericStack(int size) {
   this.top=-1;
   this.size=size;
   stack= (T[])new Object[size]; // create an array of size of generic type T
  
   }
  
   /* If someone calls the constructor with no argument, they should get a
   * stack with a default size of 10.
   */
   public GenericStack() {
   this.size=10;
   this.top=-1;
   stack= (T[])new Object[this.size]; // create an array of size 10 of generic type T
  
   }
  
   /* Return true if the stack has no elements, and false otherwise.
   */
   public boolean empty() {
       return this.top == -1;
   }
  
   /* Return the object at the top of the stack, WITHOUT removing it.
   * If there are no elements to peek, throw a NoSuchElementException.
   */
   // change the return type to generic type T
   public T peek() {
   if (this.top==-1) {
   throw new NoSuchElementException("Empty stack!");
   }
   else {
   return this.stack[this.top];
   }
  
   }
  
   /* Return the object at the top of the stack, AND ALSO remove it.
   * If there are no elements to pop, throw a NoSuchElementException.
   */
   // change the return type to generic type T
   public T pop() {
       if (this.top==-1) {
       throw new NoSuchElementException("Empty stack!");
       }
       else {
       return this.stack[this.top--];
       }
   }
  
   /* Add a new object to the top of the stack.
   * If there is no room in the stack, throw a IllegalStateException.
   */
   // input argument will be of generic type T
   public void push(T s) {
          
       if (this.top>=this.size-1) {
       throw new IllegalStateException("Stack is full!");
       }
      
       this.stack[++this.top]= s;
   }
  
   /* Return the position of an object on the stack. The position of an object
   * is just its distance from the top of the stack. So, the topmost item is
   * distance 0, the one below the topmost item is at distance 1, etc.
   */
   public int search(String s) {
       int dist = 0;
       int top = this.top;
      
       while(top>=0) {
           if(this.stack[top]==s) {
               return dist;
           }
           dist++;
           top--;
       }
       return -1;
   }  
  
   public static void main(String[] args) {
      
      
       // If any of these lines cause a compilation error, your stack hasn't
       // been properly made generic.
       GenericStack<Integer> intStack = new GenericStack<>();
       GenericStack<String> stringStack = new GenericStack<>();
       GenericStack<ArrayList<String>> listStack = new GenericStack<>();
   }
}

// end of GenericStack.java

// Calculator.java

package src;

import java.util.*;
import java.io.*;
import java.math.*;

public class Calculator{
          
   public static void main(String[] args) throws FileNotFoundException, IOException {  
  
       String numbers = "56 3 7 2.0 8.4";
       char[] moreNumbers = "1.0 2 3 4 5 0.324".toCharArray();

       GenericStack<Number> stack1 = makeStack(new StringReader(numbers));
       System.out.println(evaluate(stack1));

       GenericStack<Float> stack2 = new GenericStack<>();
       for (String token : numbers.split(" ")) {
       stack2.push(Float.parseFloat(token));
       }
       System.out.println(evaluate(stack2));

       // Uncomment the below lines so that it works for the file
       /*
       GenericStack<Number> stack3 = makeStack(new FileReader("numbers.txt"));
       System.out.println(evaluate(stack3));
       */

       GenericStack<Number> stack4 = makeStack(new CharArrayReader(moreNumbers));
       System.out.println(evaluate(stack4));      
   }
  
   /* This function is meant to take in a Reader called "reader" and return a
   * stack of Numbers.
   *
   * Remember: don't change anything that's already there. Just add your new
   * code where the comment is to fix the function's signature.
   */
   public static GenericStack<Number> makeStack(Reader reader) throws IOException {
       GenericStack<Number> stack = new GenericStack<>(64);
       char[] data = new char[64];
       reader.read(data);
       String tokens = new String(data);
      
       for (String token : tokens.split(" ")) {
           stack.push(parse(token));
       }
       return stack;
   }
  
   /* This function is meant to take in a stack of ANY KIND of Number
   * called "stack", and return the double you get if you add all of the
   * numbers together.
   * The function must be able to accept a stack of ANY KIND of Number!
   *
   * Hint: use wildcard generics!
   */
   // all the subclasses of Number can be used as the parameter of GenericStack
   public static double evaluate(GenericStack<? extends Number> stack) {
      
       double sum = 0; // set sum to 0
      
       // loop over the stack, adding the numbers together
       while(!stack.empty())
       {
           sum += ((Number)stack.pop()).doubleValue(); // remove and return the top element of the stack, convert it to double and add it to sum
       }
      
       return sum;
   }
  
   /* This function is missing a return type.
   * Examine it, and see if you can tell what type it should return.
   * (Spoiler: it's probably what you think it is.)
   */
   public static Number parse(String s) {
       try {
       return Integer.parseInt(s);
       } catch (NumberFormatException e) { }

       try {
       return Double.parseDouble(s);
       } catch (NumberFormatException e) { }

       return new BigDecimal(s);
   }
}

//end of Calculator.java

Output:


Related Solutions

To write a Generic Collection class for Stack<E>, using the generic Node<E> from Lab 5, and...
To write a Generic Collection class for Stack<E>, using the generic Node<E> from Lab 5, and test it using a stack of Car, Integer, and String Stack<E> For Programming Lab 6, you are to write your own Generic Collection for a Stack that will use your Node<E> from Lab 5 UML for Stack<E> Stack<E> - top : Node<E> - numElements : int + Stack( ) + push( element : E ) : void + pop( ) : E + size(...
For the first part of this lab, copy your working ArrayStringList code into the GenericArrayList class.(already...
For the first part of this lab, copy your working ArrayStringList code into the GenericArrayList class.(already in the code) Then, modify the class so that it can store any type someone asks for, instead of only Strings. You shouldn't have to change any of the actual logic in your class to accomplish this, only type declarations (i.e. the types of parameters, return types, etc.) Note: In doing so, you may end up needing to write something like this (where T...
Write the code for postfix expression in C++ using a linked stack that can take numbers...
Write the code for postfix expression in C++ using a linked stack that can take numbers bigger than 9 (any size the user gives) and pushes the final result onto the top of the stack
Using the first code of this lab (Figure 1), write a code that displays the status...
Using the first code of this lab (Figure 1), write a code that displays the status of a push button on the LCD, that is, when you press it you should see “Pushed” on the LCD and when you release it, you should see “Released” #include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { // set up the LCD's number of columns and rows: lcd.begin(16, 2);...
You are to use your code from part A of this assignment and add to it....
You are to use your code from part A of this assignment and add to it. In this part of the project, you are to do the following: 1. In the count_voters function you are to add code to: • Count the number of votes for Trump • Count the number of votes for Biden • Count the number of females • Count the number of males • Count the number of Democrats • Count the number of Republicans •...
C++ CODE Change your code from Part A to now present a menu to the user...
C++ CODE Change your code from Part A to now present a menu to the user asking them for an operation to perform on the text that was input. You must include the following functions in your code exactly as provided. Additionally, you must have function prototypes and place them above your main function, and the function definitions should be placed below the main function. Your program should gracefully exit if the user inputs the character q or sends the...
Lab 3.1 Create your objects in the stack (not on the heap). Add a friend function,...
Lab 3.1 Create your objects in the stack (not on the heap). Add a friend function, kilotopound, which will convert kilograms to pounds. Change your weight mutator to ask whether weight is input in kilograms or pounds. If it is kilograms, call the friend function kilotopound to convert it to pounds and return pounds. There are 2.2 pounds in one kilogram. Create an object on the stack with the following information:     uld – Container abbreviation - AYK uldid –...
Binary Search Tree (Part 1): Note: This is the first part of a 2-part lab. Only...
Binary Search Tree (Part 1): Note: This is the first part of a 2-part lab. Only this part is due on Oct 29. But please get it working or you will struggle with the second part. For the second part, the data type will be changing. For now, it is a string. Contents Explanation: 2 BST.cpp: 2 Code you must write: 2 bool insert(string s) (7): 2 TNode *find(string s) (4): 2 void printTreeIO(Tnode *n)(3): 2 void printTreePre(Tnode *n) (3):...
* Make sure you turn in your code (take a screen shot of your code in...
* Make sure you turn in your code (take a screen shot of your code in R)and answers. Conduct the hypothesis and solve questions by using R. 2) A random sample of 12 graduates of a secretarial school averaged 73.2 words per minute with a standard deviation of 7.9 words per minute on a typing test. What can we conclude, at the .05 level, regarding the claim that secretaries at this school average less than 75 words per minute on...
Write a Personal Ethics Statement includes the following: 1- The first part of your personal code...
Write a Personal Ethics Statement includes the following: 1- The first part of your personal code of ethics is where you will develop the philosophy (why) behind your code of ethics. The only requirement is that the purpose, as well as the code of ethics, be tailored to your needs. 2- The second part of your personal code of ethics is the “I will” section of your personal code of ethics. God, in the Bible, set up His “I will’s”...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT