Pre-lab 9: Working with stacks and queues

The goal of this lab is to write several small programs that make use of stacks and/or queues.

You will be using a version of the stack classes we looked at in class and Java's Queue interface and LinkedList class. (LinkedList implements Queue).

1. Grouping consistency

You have probably noticed that a text editor like Xemacs highlights text between grouping symbols-- () {} [] or < >-- if they match and are properly nested. In the first exercise, you will write a program which takes a string from the command line and determines whether or not it is properly nested with respect to these four grouping symbol pairs.

For example, the line "( a ( {b & 6 } [ 1 t ^] ~ ) )" is properly nested; "( a ( {b & 6 ) [ 1 t ^] ~ ) }" is not.

This can be done with a simple algorithm that makes one pass through the string and uses a stack.

2. Conversion from infix to RPN

Polish mathematician Jan Lukasiewicz invented a notation for arithmetic where the operator comes before the operands, for example + 5 3 instead of 5 + 3. The advantage of this is that the order of operation is always unambiguous without the need for parentheses (or even precedence rules). For example, 5 * 3 - 9 is written - * 5 3 9, whereas 5 * (3 - 9) is written * 5 - 3 9. In honor of its inventor (or his nationality, at any rate), this is referred to as Polish notation. (It is also called prefix notation, in contrast to normal arithmetic notation which is thus infix.)

Reverse Polish notation is similar except that the operator is put after the operands (so it is also postfix notation). The advantage is that all the operands are then known before the operator is read, if we read the string from left to right. This notation is particularly interesting for our purposes, because a stack can be used to evaluate expressions in RPN. (Your task in Project 6 will be to write a calculator that evaluates expressions entered in RPN.)

In the second exercise you will write a program which takes a string (of numbers, parentheses, and arithmetic operators--no other characters, even spaces) from the command line assumed to be in infix form and, using a stack, converts it to RPN. For example,

java InfixToRPN "((5*27)/(2+(3-8)))"

should print out

5 27 * 2 3 8 - + /

3. Computing capital gains

When a person buys stock in a company and later sells it for a profit, that person must pay taxes on that profit. For example, suppose a person bought 1000 shares of a company for $8 per share and later sold them for $9 per share. The person paid $8000 originally (an amount called the basis) and received $9000 (the proceeds). The proceeds minus the basis---in this case, $1000---is the capital gains of that sale. Capital gains are considered taxable income. (A capital loss can be deducted from other income, which means investors can sometimes strategically sell stocks at a loss to reduce their taxes.)

Things get tricky, when a person purchases and sells shares of a stock over several transactions. The capital gain depends on the interpretation of the sales: which shares, exactly, were bought and sold when. For example, suppose a person had the following transactions for stock of a certain company:

The total profit is (2437.50 + 10321.50) - (3000 + 3750 + 3200) = 5509. However, if a year ended after the third transaction (the first sale), then capital gains tax needed to be paid on the gain so far. But where did the 750 shares come from-- the original 1000 or the later 1500? It would affect the capital gains on that sale and thus would affect the person's reported income and taxes.

The standard way to compute capital gains is "first-in-first-out": you always sell the oldest shares first. Hence the 750 shares comes out of the original 1000 shares, and their original price (their basis) is 2250, and so the capital gain was 187.5. If this person then sold another 750 shares the next year without buying any more, then 250 of those shares would be the remaining shares from the original purchase, and the other 500 would come from the 1500 bought in the second purchase. If sold at $3.50 per share, this would be a capital gain of (750 * 3.50) - (250 * 3 + 500 * 2.5) = 2625 - 2000 = 625.

In this exercise, you will be given the class Transaction. Transaction is a simple value class--it even has public final instance variables instead of getters. It represents a transaction: a number of shares and a price per share.

You will write a class that keeps track of an investor's holdings in single company's stock by processing transactions as represented by Transaction objects. The class you will write will have a method processTransaction() that takes an instance of Transaction and updates its record of the investor's holding. In particular, the class will need to store or be able to compute the current total number of shares, the total basis for the shares currently held, and the capital gains on all the sales so far.

public class StockTracker {
    /**
     * Process a given transaction
     * @param trans The transaction to process
     */
    public void processTransaction(Transaction trans)

    /**
     * Get the number of shares currently held (all lots)
     * @return The total number of shares held
     */
      public int numShares()

     /**
     * Get the total cost basis of all shares currently held,
     * that is, how much the currently held shares cost when 
     * purchased.
     * @return The total cost basis of all shares currently held.
     */
    public int totalBasis()

    /**
     * Get the capital gains of all shares sold so far.
     * @return The current capital gains on sales of this stock
     */
    public int capitalGains()
}
I, , read the pre-lab

Thomas VanDrunen
Last modified: Thu Mar 15 09:11:17 CDT 2012