The purpose of this assignment is to provide some exercise in using multiply-linked data structures.
Your program will be a number grid. It will provide a grid with ten rows and six columns. A cell in the grid can hold and display either a number (a double) or a string. Operations will be provided which display the grid, assign values to the cells, do arithmetic on cells, do arithmetic on rows and columns, fill cells with values, insert, delete, and move rows and columns. The default value for all cells is a null String. The program will present a menu of operations to perform. When input is taken from the user for a cell value any input beginning with a double quote mark (") is treated as a string. The quote mark is not included in the string. Any other input is assumed to be a number and is accepted as a double. A sample run of the program may look like:
Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> dis col 0 col 1 col 2 col 3 col 4 col 5 row 0 row 1 row 2 row 3 row 4 row 5 row 6 row 7 row 8 row 9 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> n from row: 0 from column: 0 to row: 9 to column: 5 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> dis col 0 col 1 col 2 col 3 col 4 col 5 row 0 0 1 2 3 4 5 row 1 6 7 8 9 10 11 row 2 12 13 14 15 16 17 row 3 18 19 20 21 22 23 row 4 24 25 26 27 28 29 row 5 30 31 32 33 34 35 row 6 36 37 38 39 40 41 row 7 42 43 44 45 46 47 row 8 48 49 50 51 52 53 row 9 54 55 56 57 58 59 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> f from row: 3 from column: 2 to row: 6 to column: 4 with value: "whoopie Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> dis col 0 col 1 col 2 col 3 col 4 col 5 row 0 0 1 2 3 4 5 row 1 6 7 8 9 10 11 row 2 12 13 14 15 16 17 row 3 18 19 whoopie whoopie whoopie 23 row 4 24 25 whoopie whoopie whoopie 29 row 5 30 31 whoopie whoopie whoopie 35 row 6 36 37 whoopie whoopie whoopie 41 row 7 42 43 44 45 46 47 row 8 48 49 50 51 52 53 row 9 54 55 56 57 58 59 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> a first node row: 3 first node column: 1 second node row: 8 second node column: 3 destination node row: 0 destination node column: 0 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> dis col 0 col 1 col 2 col 3 col 4 col 5 row 0 70 1 2 3 4 5 row 1 6 7 8 9 10 11 row 2 12 13 14 15 16 17 row 3 18 19 whoopie whoopie whoopie 23 row 4 24 25 whoopie whoopie whoopie 29 row 5 30 31 whoopie whoopie whoopie 35 row 6 36 37 whoopie whoopie whoopie 41 row 7 42 43 44 45 46 47 row 8 48 49 50 51 52 53 row 9 54 55 56 57 58 59 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> dr First row: 8 Second row: 4 Target row: 1 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> dis col 0 col 1 col 2 col 3 col 4 col 5 row 0 70 1 2 3 4 5 row 1 2 1.96 8 9 10 1.82759 row 2 12 13 14 15 16 17 row 3 18 19 whoopie whoopie whoopie 23 row 4 24 25 whoopie whoopie whoopie 29 row 5 30 31 whoopie whoopie whoopie 35 row 6 36 37 whoopie whoopie whoopie 41 row 7 42 43 44 45 46 47 row 8 48 49 50 51 52 53 row 9 54 55 56 57 58 59 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> delc column number: 3 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> dis col 0 col 1 col 2 col 3 col 4 row 0 70 1 2 4 5 row 1 2 1.96 8 10 1.82759 row 2 12 13 14 16 17 row 3 18 19 whoopie whoopie 23 row 4 24 25 whoopie whoopie 29 row 5 30 31 whoopie whoopie 35 row 6 36 37 whoopie whoopie 41 row 7 42 43 44 46 47 row 8 48 49 50 52 53 row 9 54 55 56 58 59 Operations display dis assign cell as fill f number n add cells a subtract cells s multiply cells m divide cells d add rows ar subtract rows sr multiply rows mr divide rows dr add columns ac subtract columns sc multiply columns mc divide columns dc insert row ir insert column ic delete row delr delete column delc quit q -> q
Each cell in the grid will be represented by a Node (a class) with a Value field and two pointer (i.e. reference) fields, right and down. The right pointers will be used to link the nodes into rows and the down pointers will link the nodes into columns. Each row will be linked as a circle (the right field of the final node in each row will point to the first node in the row) as will each column (the down pointer of the bottom node pointing to the top node of the column).
A Value is represented as a class with three fields: a double field, dval, to hold numeric values, a String field, sval, for character strings, and a tag field which indicates whether the Value is currently a number or string (or is invalid). Arithmetic (+, -, *, and /) can be performed on Values.
The grid itself will be an instance of a Grid class. This class will have integer fields for the number of rows, number of columns, and the print width (for displaying a cell). Use the value 10 for print width. It will have a head field which points to the first node of the grid (at row 0, column 0). A constructor and a number of public member functions for the grid operations will be written.
After the (number of rows) × (number of columns) nodes have been created and linked together by the constructor for Grid all access to nodes will be done through pointer operations beginning at head.
The Value class represents the values that can be stored in the nodes. A value can be either a double or a string. A separate data field is provided for each so it is possible for a "Value" to contain both a double and a string. The tag field indicates which of these data fields holds the "real value" of the Value. A Value can also have an "INVALID" tag. This tag value is only used for (some) intermediate results in arithmetic and a Value with an INVALID tag is never stored in a node. Values are constructed with tag STRING, dval 0, and sval a null String.
Arithmetic can be done on Values with the operators plus, minus, star, and slash. Each of these will be implemented as a method of the Value class taking a Value as parameter. The operators will first check to see if the tags of both operands are DBL. If not no arithmetic is performed and the tag of the resulting Value is set to INVALID. Otherwise the sum, product, etc., is computed and the result stored in the dval field of the resulting Value. The tag is set to DBL.
You will write a toString method for Value. Notice that you do not know whether the input will be a double or a string until after it has been entered. To resolve this problem accept the input as a String and check the first character. If it is a double quote mark (") it is a string and copy it (after allocating memory) without the quote mark to the sval field. Otherwise the input is intended as a double. In this case convert it to a double with Double.parseDouble and store the result in the dval field.
The Grid class has member functions to print the grid, to do arithmetic on the cells, to insert and delete rows and columns, and to assign values to the cells.
The display member function will display the grid. Each cell will be displayed in a field of print_width characters. The row and column numbers will be displayed.
Arithmetic can be done on individual cells with addNodes, subNodes, mulNodes, and divNodes member functions. Other member functions perform arithmetic on entire rows (addRows, etc.) or columns (addCols, etc.) at a time. In all cases once you have located the nodes to be operated on you can just "add," etc., the Values and assign Values without accessing the Value's data fields or checking tags by simply using the arithmetic methods from Value.
Entire rows and columns can be inserted into the grid using insertRow and insertCol. Rows and columns can be deleted using deleteRow and deleteCol. These functions work through much fussing with pointers and require a certain amount of care to code.
Two member functions assign values to cells: number and fill. number requires the row and column numbers of two grid cells. These define a rectangular "subgrid" having these two grid cells as corners. number will assign the numbers 0, 1, 2, etc. (as doubles) to these cells. fill is similar but it puts the same Value (passed as a parameter) in the node representing each cell.
Notice that fill can be used to assign a value to a single cell.
For all methods the parameter values must be validated. Each row and column number must be in the correct range (between 0 and Grid.rows-1 and between 0 and Grid.cols-1 respectively). If two row/column pairs are used to define a subgrid (as with number and fill) the first pair cannot follow the second (but they can be the same). The delRow and delCol functions must not reduce the grid to an empty grid (there must always be at least one row and one column in the grid). Member functions which do division must check for zero divisors. If a zero divisor is found and error message is displayed and the division is not performed. Any other validations needed for the member functions to make sense must be done.
To run your grid you will write a program which will create a grid (using the default size of ten rows and six columns). The program will run in a loop which displays a menu offering all of the choices seen in the sample run shown above, accepts user input, and then performs the requested operation by calling the appropriate member function.
Test your work thoroughly and in small pieces as you proceed. A small problem in Value or the constructor for Grid, for example, which might not be apparent under overly simple testing can cause major, and difficult to trace, problems later on.
Note that much code is used repeatedly in this program. Simplify your program by factoring out this common code where appropriate. For example, adding a few private methods to class Grid to handle common operations in moving around the grid can clean up your code considerably.
As before, you will hand in a hard copy of your source file, a sample terminal session and a readme file listing any parts of the program which are not provided or are not working properly.