C++ RPN Matrix Calculator

This Matrix Calulator is a commandline based tool which can do some operations with matrixes. It is based on HP’s old but famous RPN (reverse polinish notation) which is based on a LIFO Stack. Ansi C++.

/***********************************************************************\
 * File:      MatricCalulator.cpp
 * Autor:     Marco Maniscalco
 * Copyrighted by Marco Maniscalco 2005. All Rights reserved.
 * Date:
 * 12.06.2004
 *
\***********************************************************************/

#include 
#include 
#include 
#include 

#define STACK_SIZE 10

const char *csMin1 = "Diese Operation benoetigt 1 Matrize\n";
const char *csMin2 = "Diese Operation benoetigt 2 Matrizen\n";


/******************************************************************************
    NAME: TCommand
*******************************************************************************/
typedef enum _TCommand
{
    cmdNone, cmdHelp, cmdClearStack, cmdDrop, cmdDuplicate, cmdSwap, cmdRead,
    cmdTrans, cmdAdd, cmdSub, cmdMult, cmdSkalar, cmdQuad, cmdExit
}TCommand;


/******************************************************************************
    NAME: TMatrixArray
*******************************************************************************/
typedef struct _TMatrixArray
{
	int** array_Matrix;
    int iRows;
    int iColumns;
} TMatrixArray;
typedef TMatrixArray* pMatrixArray;


/******************************************************************************
    NAME: TMatrix
*******************************************************************************/
class TMatrix
{
private:

    int ulRowCount;
    int ulColumnCount;
    TMatrixArray *pMatrixData;

public:

    TMatrix( int uRowCount, int uColumnCount );
    TMatrix( const TMatrix* AMatrix );
    ~TMatrix();
    int* Element( int i, int j );

    bool Add( TMatrix* AMatrix );
    bool Sub( TMatrix* AMatrix );

    TMatrix* Mult( TMatrix *AMatrix );
    void Mult( int s );
    TMatrix* Trans();

    int GetRowCount();
    int GetColumnCount();
};
typedef TMatrix*   p_Matrix;
typedef TMatrix** pp_Matrix;


/******************************************************************************
    NAME: TLIFO_Stack
*******************************************************************************/
class TLIFO_Stack
{
private:
    int iMaxItemCount;

    pp_Matrix pMatrixRoot;
    pp_Matrix pCurrentMatrix;

public:
    TLIFO_Stack( int iCount );
    ~TLIFO_Stack();
    int Count();
    void Clear();

    bool Push( TMatrix* AMatrix );
    TMatrix* Pop();

    bool Duplicate();
    bool Swap();

    void ReadFromKeyboard();
    void PrintInfo();
};


/******************************************************************************
    NAME: AllocateMatrix
*******************************************************************************/
pMatrixArray AllocateMatrix( int iRowCount, int iColumnCount )
{
    pMatrixArray pMatrixData = new TMatrixArray;

    pMatrixData->iRows = iRowCount;
    pMatrixData->iColumns = iColumnCount;

    pMatrixData->array_Matrix = new int*[iRowCount];

    for( int i=0; iarray_Matrix[i] = new int[iColumnCount];
        for( int c=0; carray_Matrix[i] = 0;
        }
    }

    return pMatrixData;
}


/******************************************************************************
    NAME: FreeMatrix
*******************************************************************************/
void FreeMatrix( pMatrixArray pMatrixData )
{
    for( int i = 0; iiRows; i++ )
        delete[] pMatrixData->array_Matrix[i];

    delete[] pMatrixData->array_Matrix;

    pMatrixData = NULL;
}


/******************************************************************************
    NAME: PrintHelp
*******************************************************************************/
void PrintHelp()
{
    printf( "\n" );
    printf( " >C<  'Clear': Clear the Stack.\n" );
    printf( " >D<  'Drop': Delete current StackMatrix s0\n" );
    printf( "              and  move down Matrix S1 to Sn-1.\n" );
    printf( " >d<  'Duplicate': copy s0 to sn-2 in s1 to sn-\n" );
    printf( " >s<  'Swap': Swap s0 and s1\n" );
    printf( " >r<  'read': Read Matrix from Keyboard, 'duplicate'\n" );
    printf( " >t<  transpose s0\n" );
    printf( " >+<  add s0 + s1\n" );
    printf( " >-<  subtract s0 - s1\n" );
    printf( " >*<  multiply s0 * s1\n" );
    printf( " >.<  read an calc scalar s * S&#91;0&#93;\n" );
    printf( " >q<  quad S&#91;0&#93;ý.\n" );
    printf( " >h<  This Screen.\n" );
    printf( " >E<  Exit.\n" );
}


/******************************************************************************
    NAME: TranslateCommand
*******************************************************************************/
TCommand TranslateCommand( char cCmd )
{
    TCommand cmdResult = cmdNone;

    switch( cCmd )
    {
        case 'h': cmdResult = cmdHelp; break;
        case 'C': cmdResult = cmdClearStack; break;
        case 'D': cmdResult = cmdDrop; break;
        case 'd': cmdResult = cmdDuplicate; break;
        case 's': cmdResult = cmdSwap; break;
        case 'r': cmdResult = cmdRead; break;
        case 't': cmdResult = cmdTrans; break;
        case '+': cmdResult = cmdAdd; break;
        case '-': cmdResult = cmdSub; break;
        case '*': cmdResult = cmdMult; break;
        case '.': cmdResult = cmdSkalar; break;
        case 'q': cmdResult = cmdQuad; break;
        case 'E': cmdResult = cmdExit; break;
        default : cmdResult = cmdNone;
    }
    return cmdResult;
}


/******************************************************************************
    NAME: ReadSkalarFromKeyboard
*******************************************************************************/
int ReadSkalarFromKeyboard()
{
    int iSkalar = 1;

    printf ( "Skalar: " );
    scanf ( "%d", &amp;iSkalar );

    return iSkalar;
}


/******************************************************************************
    NAME: HandleCommand
*******************************************************************************/
bool HandleCommand( TLIFO_Stack&amp; pLifoStack, TCommand Command )
{
    TMatrix* pMatrixA,
           * pMatrixB,
           * pMatrixC;

    pMatrixA = pMatrixB = pMatrixC = NULL;

    if( Command == cmdHelp )
    {
        PrintHelp();
    }
    else if( Command == cmdClearStack )
    {
        pLifoStack.Clear();
    }
    else if( Command == cmdDrop )
    {
        pMatrixA = pLifoStack.Pop();
        if ( pMatrixA != NULL )
        {
            delete pMatrixA;
        }
    }
    else if( Command == cmdDuplicate )
    {
        pLifoStack.Duplicate();
    }
    else if( Command == cmdSwap )
    {
        if ( pLifoStack.Count() >= 2 )
        {
            pLifoStack.Swap();
        }
        else
        {
            printf( csMin2 );
        }
    }
    else if( Command == cmdRead )
    {
        pLifoStack.ReadFromKeyboard();
    }
    else if( Command == cmdTrans )
    {
        if ( pLifoStack.Count() != 0 )
        {
            pMatrixA = pLifoStack.Pop();
            pMatrixB = pMatrixA->Trans();
            delete pMatrixA;

            pLifoStack.Push( pMatrixB );
        }
        else
        {
            printf( csMin1 );
        }
    }
    else if( Command == cmdAdd )
    {
        if ( pLifoStack.Count() >= 2 )
        {
            pMatrixA = pLifoStack.Pop();
            pMatrixB = pLifoStack.Pop();

            if( pMatrixA->Add( pMatrixB ) )
            {
                pLifoStack.Push( pMatrixA );
            }
        }
        else
        {
            printf( csMin2 );
        }
    }
    else if( Command == cmdSub )
    {
        if ( pLifoStack.Count() >= 2 )
        {
            pMatrixA = pLifoStack.Pop();
            pMatrixB = pLifoStack.Pop();

            if( pMatrixA->Sub( pMatrixB ) )
            {
                pLifoStack.Push( pMatrixA );
            }
        }
        else
        {
            printf( csMin2 );
        }
    }
    else if( Command == cmdMult )
    {
        if ( pLifoStack.Count() >= 2 )
        {
            pMatrixA = pLifoStack.Pop();
            pMatrixB = pLifoStack.Pop();
            if( (pMatrixC = pMatrixA->Mult( pMatrixB )) != NULL )
            {
                pLifoStack.Push( pMatrixC );
            }

            delete pMatrixB;
            delete pMatrixA;
        }
        else
        {
            printf( csMin2 );
        }
    }
    else if( Command == cmdSkalar )
    {
        if ( pLifoStack.Count() != 0 )
        {
            int iSkalar;
            iSkalar = ReadSkalarFromKeyboard();

            pMatrixA = pLifoStack.Pop();
            pMatrixA->Mult( iSkalar );

            pLifoStack.Push( pMatrixA );
        }
        else
        {
            printf( csMin1 );
        }
    }
    else if( Command == cmdQuad )
    {
        pMatrixA = pLifoStack.Pop();
        if( (pMatrixB = pMatrixA->Mult( pMatrixA )) != NULL )
        {
            pLifoStack.Push( pMatrixB );
        }
        delete pMatrixA;
    }
    else if( Command ==  cmdExit )
    {
        return false;
    }
    else if( Command ==  cmdNone )
    {
        printf( "Unbekanntes Kommando. 'h' fuer Hilfe\n" );
    }

    pLifoStack.PrintInfo();

    return true;
}


/******************************************************************************
    NAME: main
*******************************************************************************/
int main( int argc, char* argv[] )
{
    char cCmd;
    TCommand cmdCommand;
    TLIFO_Stack *pLifoStack = new TLIFO_Stack( STACK_SIZE );

    printf( "Matrix Calculator\n\nEnter Command:" );

    do
    {
        printf( "\n$" );
        cin >> cCmd;
        cmdCommand = TranslateCommand( cCmd );
    }
    while ( HandleCommand( *pLifoStack, cmdCommand ) );

    delete pLifoStack;
    return 0;
}



/******************************************************************************

    TMatrix implementation

*******************************************************************************/



/******************************************************************************
    NAME: TMatrix( int uRowCount, int uColumnCount )
*******************************************************************************/
TMatrix::TMatrix( int uRowCount, int uColumnCount )
{
    ulRowCount = uRowCount;
    ulColumnCount = uColumnCount;

    pMatrixData = AllocateMatrix( ulRowCount, ulColumnCount );
}


/******************************************************************************
    NAME: TMatrix( int uRowCount, int uColumnCount )
*******************************************************************************/
TMatrix::TMatrix( const TMatrix* AMatrix )
{
    ulRowCount = AMatrix->ulRowCount;
    ulColumnCount = AMatrix->ulColumnCount;

    pMatrixData = AllocateMatrix( ulRowCount, ulColumnCount );

    memcpy( pMatrixData, 
            AMatrix->pMatrixData, 
           (ulRowCount * ulColumnCount * sizeof( int )) + (2*sizeof(int)) );
}


/******************************************************************************
    NAME: ~TMatrix
*******************************************************************************/
TMatrix::~TMatrix()
{
    FreeMatrix( pMatrixData );
}


/******************************************************************************
    NAME: Element
*******************************************************************************/
int* TMatrix::Element( int a, int b )
{
    if ( (a > ulRowCount) || (b > ulColumnCount) )
    {
        return NULL;
    }

    return &amp;pMatrixData->array_Matrix[a][b];
}


/******************************************************************************
    NAME: Add
*******************************************************************************/
bool TMatrix::Add( TMatrix* AMatrix )
{
    if ( (ulRowCount != AMatrix->ulRowCount) || 
          (ulColumnCount != AMatrix->ulColumnCount) )
    {
        return false;
    }

    for ( int i = 0; i < ulRowCount; ++i )
    {
        for ( int j = 0; j < ulColumnCount; ++j )
        {
            *Element( i, j ) += *( AMatrix->Element( i, j ) );
        }
    }
    return true;
}


/******************************************************************************
    NAME: Sub
*******************************************************************************/
bool TMatrix::Sub( TMatrix* AMatrix )
{
    if ( (ulRowCount != AMatrix->ulRowCount) || 
         (ulColumnCount != AMatrix->ulColumnCount) )
    {
        return false;
    }

    for ( int i = 0; i < ulRowCount; ++i )
    {
        for ( int j = 0; j < ulColumnCount; ++j )
        {

            *Element( i, j ) -= *( AMatrix->Element( i, j ) );
        }
    }
    return true;
}


/******************************************************************************
    NAME: Mul
*******************************************************************************/
TMatrix* TMatrix::Mult( TMatrix* AMatrix )
{
    if( !AMatrix )
    {
        return NULL;
    }
    if ( (ulColumnCount != AMatrix->ulRowCount) || 
         (ulRowCount != AMatrix->ulColumnCount) )
    {
        return NULL;
    }

    TMatrix* pNeu = new TMatrix( ulRowCount, AMatrix->ulColumnCount );

    for ( int i = 0; i < ulRowCount; ++i )
    {
        for ( int j = 0; j < AMatrix->ulColumnCount; ++j )
        {
            for ( int k = 0; k < ulColumnCount; ++k )
            {
                *pNeu->Element( i, j ) += ( *Element( i, k ) ) * 
                                          ( *AMatrix->Element( k, j ) );
            }
        }
    }

    return pNeu;
}


/******************************************************************************
    NAME: Mul (einfache multiplikation)
*******************************************************************************/
void TMatrix::Mult( int iSkalar )
{
    for ( int i = 0; i < ulRowCount; ++i )
    {
        for ( int j = 0; j < ulColumnCount; ++j )
        {
            *Element( i, j ) *= iSkalar;
        }
    }
}


/******************************************************************************
    NAME: Trans(pnoieren)
*******************************************************************************/
TMatrix* TMatrix::Trans()
{
    TMatrix* pNeu = new TMatrix( ulColumnCount, ulRowCount );

    for ( int y = 0; y < ulRowCount; y++ )
    {
        for ( int x = 0; x < ulColumnCount; x++ )
        {
            *pNeu->Element( x, y ) = * Element( y, x );
        }
    }

    return pNeu;

}


/******************************************************************************
    NAME: GetRowCount
*******************************************************************************/
int TMatrix::GetRowCount()
{
    return ulRowCount;
}


/******************************************************************************
    NAME: GetColumnCount
*******************************************************************************/
int TMatrix::GetColumnCount()
{
    return ulColumnCount;
}



/******************************************************************************

    TLIFO_Stack implementation

*******************************************************************************/



/******************************************************************************
    NAME: TLIFO_Stack
*******************************************************************************/
TLIFO_Stack::TLIFO_Stack( int iCount )
{
    iMaxItemCount = iCount;
    pMatrixRoot = (pp_Matrix)malloc( iMaxItemCount*sizeof( p_Matrix ) );
    pCurrentMatrix = pMatrixRoot - 1;
}


/******************************************************************************
    NAME: ~TLIFO_Stack
*******************************************************************************/
TLIFO_Stack::~TLIFO_Stack()
{
    TLIFO_Stack::Clear();
    free( pMatrixRoot );

    pCurrentMatrix = NULL;
    pMatrixRoot = NULL;
}


/******************************************************************************
    NAME: Count
*******************************************************************************/
int TLIFO_Stack::Count()
{
    return pCurrentMatrix - pMatrixRoot + 1;
}


/******************************************************************************
    NAME: Pop
*******************************************************************************/
TMatrix* TLIFO_Stack::Pop()
{
    TMatrix* pS0Matrix = NULL;

    if ( pCurrentMatrix < pMatrixRoot )
    {
        pS0Matrix = NULL;
    }
    else
    {
        pS0Matrix = *pCurrentMatrix;
        pCurrentMatrix--;
    }

    return pS0Matrix;
}


/******************************************************************************
    NAME: Push
*******************************************************************************/
bool TLIFO_Stack::Push( TMatrix* AMatrix )
{
    pCurrentMatrix++;
    *pCurrentMatrix = AMatrix;
    return true;
}


/******************************************************************************
    NAME: Clear
*******************************************************************************/
void TLIFO_Stack::Clear()
{
    pp_Matrix pMatrix;

    for ( pMatrix=pMatrixRoot; pMatrix<=pCurrentMatrix; pMatrix++ )
    {
        if( *pMatrix != NULL )
        {
            delete *pMatrix;
        }
        *pMatrix = NULL;
    }

    pCurrentMatrix = pMatrixRoot - 1;
}


/******************************************************************************
    NAME: Swap
*******************************************************************************/
bool TLIFO_Stack::Swap()
{
    bool bResult = false;

    if ( TLIFO_Stack::Count() >= 2 )
    {
        p_Matrix pS0Matrix = *pCurrentMatrix;

        *pCurrentMatrix = *( pCurrentMatrix - 1 );
        *( pCurrentMatrix - 1 ) = pS0Matrix;
    }

    return bResult;
}


/******************************************************************************
    NAME: Duplicate (oder: Push S[0] erneut)
*******************************************************************************/
bool TLIFO_Stack::Duplicate()
{
    bool bResult = false;

    if ( TLIFO_Stack::Count() != 0 )
    {
        p_Matrix pS0MatrixTmp = new TMatrix( *pCurrentMatrix );
        bResult = Push( pS0MatrixTmp );
    }

    return bResult;
}


/******************************************************************************
    NAME: PrintInfo()
*******************************************************************************/
void TLIFO_Stack::PrintInfo()
{
    int iMatrixCount = TLIFO_Stack::Count();

    printf( "\nÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n" );
    printf(  "º %i Matrizen                    º\n", iMatrixCount );
    printf(  "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n" );

    for ( int i = iMatrixCount - 1; i >= 0; i-- )
    {
        int iRowCount, iColumnCount;

        iRowCount = ( *( pCurrentMatrix - i ) )->GetRowCount();
        iColumnCount = ( *( pCurrentMatrix - i ) )->GetColumnCount();

        printf( "\n S[%i] (%ix%i)\n\n", i, iRowCount, iColumnCount );

        for ( int a = 0; a < iRowCount; a++ )
        {
            for ( int b = 0; b < iColumnCount; b++ )
            {
                printf( " %d\t", * ( *( pCurrentMatrix - i ) )->Element( a, b ) );
            }
            printf( "\n" );
        }

    }

}

/******************************************************************************
    NAME: ReadFromKeyboard
*******************************************************************************/
void TLIFO_Stack::ReadFromKeyboard()
{
    int iM_Width, iM_Height, iInput;

    printf( "\n" );

    printf( "Matrix Breite: " );
    scanf( "%i", &amp;iM_Width );

    printf( "Matrix Hoehe: " );
    scanf( "%i", &amp;iM_Height );

    TMatrix* pNeu = new TMatrix( iM_Height, iM_Width );

    for( int i=0; iElement( i, j ) = iInput;
        }
    }

    Push( pNeu );
}

Schreibe einen Kommentar