⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcalc.java

📁 用java实现浮点数加减乘除四则混合运算
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
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 )
				  {
						//保持一个数的float性质
						if ( elem.length == 1 )
						{
							myStack.pop();
									
				    	myStack.push( elem[0] );
						}
						else
						{
							Matrix temp = new Matrix( elem );

							myStack.pop();
										
							myStack.push( temp );
						}
				  }

					else 
					{
					  //报错,因为有非double型的对象。
					  System.out.println( 
							"Error: Elements don't match.Unable to make the matrix." );

						//将栈顶到"["为止的元素全部弹出。
						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;

          //判断是否全为行向量,若有数字或非行向量,则无法形成矩阵。
					//弹出全部直到"["为止。
					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 )
					{
						//判断向量是否可以组成一个矩阵。
						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 )
					{
						//对于元素为一的矩阵数组保留原样。即[ [ 5 6 ] ]为[ 5 6 ];
						if ( elem.length == 1 )
						{
							myStack.pop();
							myStack.push( elem[0] );
						}
						else
						{
							Matrix temp = 
								new Matrix( elem.length, elem[0].column(),elem );
							myStack.pop();   //弹出"[".												
							myStack.push( temp );
						}
					}
					else
					{
						//报错,无法形成正确的矩阵:由于有数字或矩阵不匹配。
						System.out.println(
							"Error: Elements don't match.Unable to make the matrix." );

						//将栈顶到"["为止的元素全部弹出。
						index = myStack.search( "[" );
						for ( int i = 0; i <= index; i++ )
						{
							myStack.pop();
						}
					}
				}				
		  }
			else
			{
				//报错 无匹配的"["				
				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
				{
					//因为非正整数,报错
					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
						{
							//矩阵与数字无法运算。
							//保持原来的状态。
              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
						{
							//矩阵与数字无法运算。
							myStack.push( number2 );
							myStack.push( number1 );

							System.out.println(
								"Error: Matrix and number can't do the addition!" );
						}
					}				
				}
				else
				{
					//运算数字个数不足。
					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();
						if ( number2.getClass() == Double.class )
						{
							double num2 = ((Double)number2).doubleValue();
							myStack.push( Matrix.minus( num2,num1)); 
						}
						else
						{
							//矩阵与数字无法运算。
							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
						{
							//矩阵与数字无法运算。
							myStack.push( number2 );
							myStack.push( number1 );

							System.out.println(
								"Error: Matrix and number can't do the subtraction!" );
						}
					}				
				}
				else
				{
					//运算数字个数不足。
					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
						{
							//除零错误。
							System.out.println( "Error: Can't divide by 0!" );
						}
								
					}
					else
					{
						//矩阵与数字无法运算。
						myStack.push( number2 );
						myStack.push( number1 );

						System.out.println(
								"Error: The two operands don't match. Can't do the division." );
					}				
				}
				else
				{
					//运算数字个数不足。
					System.out.println( 
						"Error: There aren't enough operands for division!" );				
				}
			}
			else
			{
				System.out.println( 
					"Error: Unable to do the division inside the matrix!" );				
			}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -