?? mcalc.java
字號(hào):
import java.io.*;
import java.util.*;
/**
* This is the main class of the calculator program. <p>
* The calculator program can perform matrix arithmetic including addition,
* subtraction, multiplication, division as well as transposition and
* inversion. <p>
* It can also perform floating-number arithmetic. <p>
* This class reads the commands from the user, solves
* the problem, and returns the answer.
*
* @author Rachel Chen 0122070
* @version 1.0 2003/3/22
* @see java.io.StreamTokenizer
* @see java.util.Hashtable
* @see java.util.StringTokenizer
*/
public class Mcalc
{
/** Class MyStack is used as the stack for this program.*/
private MyStack myStack;
/** Class Hashtable is used to store the variables' value. */
private Hashtable hashtable;
/**
* This is the constructor for class Mcalc.
* It initializes the stack and the hashtable.
*/
public Mcalc()
{
myStack = new MyStack();
hashtable = new Hashtable();
}
/*
* +------------+------------+---------------+-----------------+
* | represent | Command | data | variable |
* +------------+------------+---------------+-----------------+
* | number | 0 | double type | String type |
* | | | number | or NULL |
* +------------+------------+---------------+-----------------+
* | [ | 1 | 0.0 | "[" |
* +------------+------------+---------------+-----------------+
* | ] | 2 | 0.0 | "]" |
* +------------+------------+---------------+-----------------+
* | id N | 3 | N | "id " + N |
* +------------+------------+---------------+-----------------+
* | = | 4 | 0.0 | "=" |
* +------------+------------+---------------+-----------------+
* | + | 5 | 0.0 | "+" |
* +------------+------------+---------------+-----------------+
* | - | 6 | 0.0 | "-" |
* +------------+------------+---------------+-----------------+
* | / | 7 | 0.0 | "/" |
* +------------+------------+---------------+-----------------+
* | * | 8 | 0.0 | "*" |
* +------------+------------+---------------+-----------------+
* | _ | 9 | 0.0 | "_" |
* +------------+------------+---------------+-----------------+
* | t | 10 | 0.0 | "t" |
* +------------+------------+---------------+-----------------+
* | inv | 11 | 0.0 | "inv" |
* +------------+------------+---------------+-----------------+
* | =: V | 12 | 0.0 | V |
* +------------+------------+---------------+-----------------+
* | := V | 13 | 0.0 | V |
* +------------+------------+---------------+-----------------+
* | dup / d | 14 | 0.0 | "dup" |
* +------------+------------+---------------+-----------------+
* | exch / x | 15 | 0.0 | "exch" |
* +------------+------------+---------------+-----------------+
* | pop | 16 | 0.0 | "pop" |
* +------------+------------+---------------+-----------------+
* | quit / q | 17 | 0.0 | "quit" |
* +------------+------------+---------------+-----------------+
* | help / ? | 18 | 0.0 | "help" |
* +------------+------------+---------------+-----------------+
*/
/**
* This mathod reads commands from the user and does the thing it orders.
* If the operator doesn't perform correctly,e.g [ 6 7 ] [ 7 8 ] / <p>
* Then this operation would be ignored,and [ 6 7 ] [ 7 8 ] remains in <p>
* the stack.<p>
* It can distinguish different commands, check the validity and returns
* the right answer. <p>
*
* Explanations for each command:<p>
* NO.0 number: Just push the data into the stack. <p>
* NO.1 [: Just push "[" into the stack. <p>
* NO.2 ]: First search for the "[" in the stack. When it is found,pop all the
* objects from the stack until "[" is reached. Then organise the objects,
* change them into a matrix object and push back to the stack. Otherwise,
* give the error information. <p>
* NO.3 id N: if data equals 1 ,just push 1.0f, else if data is positive call
* Matrix.identityMatrix() to make the Identity matrix and push it, otherwise
* give the error information. <p>
* NO.4 =: Pop and print the data on top of the stack when it is not empty, otherwise
* give the error information. <p>
* No.5 +/ NO.6 -/ NO.7 / /NO.8 * /NO.9 _/ NO.10 t/ NO.11 inv:
* Search for "[" in the stack. When finds one gives the error information
* because it is not allowed to do the operation inside the matrix.
* Then count the operands in the stack. If it is lower than the required number,
* give the error information. Then check whether the operands' types matches.
* At last, call the static method in the class Matrix to do the operation
* and push the result into the stack.<p>
* NO.12 =: V :First check the validity of the variable's name. If is invalid,
* give the error information.Then pop the value from the stack and store it in
* the hashtable together with the variable. If the stack is empty,give the
* error information; <p>
* NO.13 := V : Get the value from the hashtable by the variable. If there
* is no one matching the variable,give the error information. <p>
* NO.14 dup/d: Check the number of data in the stack. If it is non-zero,peek
* the top value and push it to the stack.Otherwise,give the error information. <P>
* NO.15 exch/x :Check the data number in the stack. If it not lower than two,
* pop the two value and push them back after exchanging the value. <p>
* Otherwise give the error information.<p>
* NO.16 pop: Pop the data in the stack. Give the error information when the
* stack is empty. <p>
* NO.17 quit/q : Quit the program. <p>
* NO.18 help/? : Show the help information. <p>
*
* @param command Use the value of this parameter to choose the right
* case for the command.
* @param data The data for the command.
* @param variable The variable for the command.
*/
public void readCommand( int command, double data, String variable )
throws java.io.IOException
{
switch ( command )
{
case 0:
myStack.push( new Double( data ));
break;
case 1:
myStack.push( "[" );
break;
case 2:
int index = myStack.search( "[" );
if ( index != -1 )
{
if ( myStack.peek().getClass() == Double.class )
{
boolean isValid = true;
Double[] elem = new Double[ index ];
for ( int i = index - 1; i >= 0; i-- )
{
Object tem = myStack.pop();
if ( tem.getClass() != Double.class )
{
isValid = false;
break;
}
elem[i] = ( Double )tem;
}
if ( isValid )
{
//保持一個(gè)數(shù)的float性質(zhì)
if ( elem.length == 1 )
{
myStack.pop();
myStack.push( elem[0] );
}
else
{
Matrix temp = new Matrix( elem );
myStack.pop();
myStack.push( temp );
}
}
else
{
//報(bào)錯(cuò),因?yàn)橛蟹莇ouble型的對(duì)象。
System.out.println(
"Error: Elements don't match.Unable to make the matrix." );
//將棧頂?shù)?quot;["為止的元素全部彈出。
index = myStack.search( "[" );
for ( int i = 0; i <= index; i++ )
{
myStack.pop();
}
}
}
else if ( myStack.peek().getClass() == Matrix.class )
{
Matrix[] elem = new Matrix[index];
boolean isValid = true;
//判斷是否全為行向量,若有數(shù)字或非行向量,則無(wú)法形成矩陣。
//彈出全部直到"["為止。
for ( int i = index - 1; i >= 0; i-- )
{
Object tem = myStack.pop();
if ( tem.getClass() != Matrix.class || ((Matrix)tem).row() != 1 )
{
isValid = false;
break;
}
elem[i] = (Matrix)tem;
}
if ( isValid )
{
//判斷向量是否可以組成一個(gè)矩陣。
loop:
{
for ( int i = 0; i < elem.length - 1; i++ )
{
if ( elem[i].column() != elem[i + 1].column())
{
isValid = false;
break loop;
}
if ( elem[i].column() == 1 )
{
isValid = false;
break loop;
}
}
}
}
if ( isValid )
{
//對(duì)于元素為一的矩陣數(shù)組保留原樣。即[ [ 5 6 ] ]為[ 5 6 ];
if ( elem.length == 1 )
{
myStack.pop();
myStack.push( elem[0] );
}
else
{
Matrix temp =
myStack.pop(); //彈出"[".
myStack.push( temp );
}
}
else
{
//報(bào)錯(cuò),無(wú)法形成正確的矩陣:由于有數(shù)字或矩陣不匹配。
System.out.println(
"Error: Elements don't match.Unable to make the matrix." );
//將棧頂?shù)?quot;["為止的元素全部彈出。
index = myStack.search( "[" );
for ( int i = 0; i <= index; i++ )
{
myStack.pop();
}
}
}
}
else
{
//報(bào)錯(cuò) 無(wú)匹配的"["
System.out.println(
"Error: No \"[\" matches this \"]\".Unable to make the matrix." );
}
break;
case 3:
int matchIden = myStack.search( "[" );
if ( matchIden == -1 )
{
if ( data == 1 )
{
myStack.push( new Double( 1 ) );
}
else if ( data > 1 )
{
myStack.push( Matrix.identityMatrix((int)data ) );
}
else
{
//因?yàn)榉钦麛?shù),報(bào)錯(cuò)
System.out.println( "Error: N can't be negative!" );
}
}
else
{
System.out.println(
"Error: Unable to do the operation inside the matrix!" );
}
break;
case 4:
if ( myStack.size() == 0 )
{
System.out.println( "Error: Stack is empty!" );
}
else
{
Object result = myStack.pop();
if ( result.getClass() == Double.class )
{
System.out.println( result );
}
else if ( result.getClass() == Matrix.class )
{
System.out.println( Matrix.toString((Matrix)result ) );
}
}
break;
case 5:
int matchAdd = myStack.search( "[" );
if ( matchAdd == -1 )
{
if ( myStack.size() >=2 )
{
Object number1 = myStack.pop();
Object number2 = myStack.pop();
if ( number1.getClass() == Double.class )
{
double num1 = ((Double)number1).doubleValue();
if ( number2.getClass() == Double.class )
{
double num2 = ((Double)number2).doubleValue();
myStack.push( Matrix.add( num2,num1));
}
else
{
//矩陣與數(shù)字無(wú)法運(yùn)算。
//保持原來(lái)的狀態(tài)。
myStack.push( number2 );
myStack.push( number1 );
System.out.println(
"Error: Matrix and number can't do the addition!" );
}
}
else
{
Matrix num1 = ( Matrix )number1;
if ( number2.getClass() != Double.class )
{
Matrix num2 = ( Matrix )number2;
Matrix result = Matrix.add( num2,num1 );
if ( result != null )
{
myStack.push( result );
}
}
else
{
//矩陣與數(shù)字無(wú)法運(yùn)算。
myStack.push( number2 );
myStack.push( number1 );
System.out.println(
"Error: Matrix and number can't do the addition!" );
}
}
}
else
{
//運(yùn)算數(shù)字個(gè)數(shù)不足。
System.out.println(
"Error: There aren't enough operands for addition!" );
}
}
else
{
System.out.println(
"Error: Unable to do the addition inside the matrix!" );
}
break;
case 6:
int matchMinus = myStack.search( "[" );
if ( matchMinus == -1 )
{
if ( myStack.size() >=2 )
{
Object number1 = myStack.pop();
Object number2 = myStack.pop();
if ( number1.getClass() == Double.class )
{
double num1 = ((Double)number1).doubleValue();
{
double num2 = ((Double)number2).doubleValue();
myStack.push( Matrix.minus( num2,num1));
}
else
{
//矩陣與數(shù)字無(wú)法運(yùn)算。
myStack.push( number2 );
myStack.push( number1 );
System.out.println(
"Error: Matrix and number can't do the subtraction!" );
}
}
else
{
Matrix num1 = ( Matrix )number1;
if ( number2.getClass() == Matrix.class )
{
Matrix num2 = ( Matrix )number2;
Matrix result = Matrix.minus( num2,num1 );
if ( result != null )
{
myStack.push( result );
}
}
else
{
//矩陣與數(shù)字無(wú)法運(yùn)算。
myStack.push( number2 );
myStack.push( number1 );
System.out.println(
"Error: Matrix and number can't do the subtraction!" );
}
}
}
else
{
//運(yùn)算數(shù)字個(gè)數(shù)不足。
System.out.println(
"Error: There aren't enough operands for subtraction!" );
}
}
else
{
System.out.println(
"Error: Unable to do the subtraction inside the matrix!" );
}
break;
case 7:
int matchDiv = myStack.search( "[" );
if ( matchDiv == -1 )
{
if ( myStack.size() >=2 )
{
Object number1 = myStack.pop();
Object number2 = myStack.pop();
if ( number1.getClass() == Double.class )
{
double num1 = ((Double)number1).doubleValue();
if ( num1 != 0 )
{
if ( number2.getClass() == Double.class )
{
double num2 = ((Double)number2).doubleValue();
myStack.push( Matrix.divide( num2,num1));
}
else if( number2.getClass() == Matrix.class )
{
Matrix num2 = ( Matrix )number2;
myStack.push( Matrix.divide( num2,num1 ));
}
}
else
{
//除零錯(cuò)誤。
System.out.println( "Error: Can't divide by 0!" );
}
}
else
{
//矩陣與數(shù)字無(wú)法運(yùn)算。
myStack.push( number2 );
myStack.push( number1 );
System.out.println(
"Error: The two operands don't match. Can't do the division." );
}
}
else
{
//運(yùn)算數(shù)字個(gè)數(shù)不足。
System.out.println(
"Error: There aren't enough operands for division!" );
}
}
else
{
System.out.println(
"Error: Unable to do the division inside the matrix!" );
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -