In my cs2 class the assignment is to implement a sparse matrix with pointers without using a 2d array. Here is the exact text:

A sparse matrix can be represented using an array of pointers called "arrayOfPointer" and an array of integer called "matrixInfo". The size of "arrayOfPointer" will be equal to the number of rows in the matrix X. Each pointer arrayOfPointer will point to an array-of-objects, where each object stores the column index, and the value X[columnindex] for an element different from zero of the matrix X. The size of each array-of-objects will be equal to the number of elements different from zero of the corresponding row in the matrix X. We will store in "matrixInfo" the number of rows in the matrix, and for each row the size of the corresponding array-of-objects.

Here is the code I have done so far:

#include<iostream>
#include<cstdlib>

using namespace std;

//Class implimentations
class ObjectClass
{
    private:
        int collumnNumber;
        double value;
        
   public:
        int getColumnNumber() const;
        double getValue() const;
        void setColumnNumber();
        void setValue();
};
//******************************************************************************
class SparseMatrix
{
    private:
        int matrixInfo[11]; 
        ObjectClass ** arrayOfPointer;
           
    public:
        
                    //Main constructor
        SparseMatrix (matrixInfo)
        {//compiler says error on this line.
        // says "invalid member function decaration".
            for(int n=0; n<=matrixInfo[0] ; n++)
            {
                if( **arrayOfPointer[n]!=0)
                {
                    arrayOfPointer= new objectClass*[matrixInfo[n]];
                    arrayOfPointer.columnNumber[n]=(rand()%10);
                }
                 if(arrayOfPointer.collumnNumber! =0)
                    {
                        *arrayOfPointer=new objectClass []
                        arrayOfPointer.value[n]=(rand()%1000);
                    
                        //If the row is to have values different from zero
                        //constructor gives a random number for which collumn
                        //The non zero value will be in and then places a random
                        //number into that slot.
                    }
            }
        } 
    //*****OBJECT'S MEMBER FUNCTIONS PROTOTYPES*****
    void print() const;
    int getMatrixInfo() const;
    void setMatrixInfo();

};

Here is the main supplied to me in class:

int main()
{
    int tab[11];
    tab[0]=10;
    
    for(int i=1; i<11; i++)
    {
        tab[i]=1+rand()%5;
    }
    
    // The constructor uses one array of integers as parameter and will fill the
    // matrix with randomly selected values. The parameter contains the num
    // of rows, and for each row the number of elements different from zero  
    // in the matrix X.

    //SparseMatrix s(tab);
    
    cout << "The matrix s: " << endl;
   // s.print();
    cout << endl << endl;
    /*
    int tab1[11];
    tab1[0]=10;
    for(int i=1; i<11; i++)
    {
        tab1[i]=1+rand()%5;
    }
    
    SparseMatrix s1(tab1);
    s1.print;
    cout<< endl << endl;
    SparseMatrix s2=s+s1;
    s2.print();
    cout<< endl << endl;
    */
    return 0;
}

I omitted the member function implementation for the classes because currently they are empty and don't do anything and I also temporary disabled most of the main function for now.

I have been getting an error as marked in the code for the SparseMatrix class and cannot seem to understand what is wrong there, also I need to know if my SparseMatrix class is creating a sparse array according to the directions, and if not what I should do to fix it.

Thank you for your help.

Your constructor paramater is missing a type. I noticed that you chose the same name for your parameter as you chose for your array. You're aware that just by giving them the same name, you're not actually passing the array into the constructor, right?

Yes, this won't work because you are not specifying a type.

SparseMatrix (matrixInfo)

on line 29, you should to use something like this, depending on what you want the constructor to do:

// to specify x and y dimensions
SparseMatrix (size_t sizeX, size_t sizeY)
// to give some default data to fill the matrix up with
SparseMatrix (int **matrixInfo)

I have already coded a matrix class in C++ (header and code), feel free to look at it.

Edited 5 Years Ago by xfbs: n/a

Thank the both of you for the advice, I implemented the changes and its still giving me some error messages, that I'm working on solving.

Yes, you definitely had a few other issues in your code, but I saw no reason to point them out at the time. Let us know if you need more help.

OK, Ive worked on the code again and fixed all the simple errors like missing semicolons and misspelled words but I'm left with 4 errors that I can't seem to fix.

The only code I changed was that of the constructor so that is all ill post:

SparseMatrix (int matrixInfo[])
        {
            for(int n=0; n<=matrixInfo[0] ; n++)
            {
                if( arrayOfPointer[n]!=0)
                {
                    arrayOfPointer= new ObjectClass*[matrixInfo[n]];
                    arrayOfPointer[n].columnNumber=(rand()%10);
                }
                 if(arrayOfPointer[n].collumnNumber !=0)
                    {
                       *arrayOfPointer=new ObjectClass[arrayOfPointer[n].collumnNumber];
                        arrayOfPointer[n].value=(rand()%1000);
                    
                        //If the row is to have values different from zero
                        //constructor gives a random number for which collumn
                        //The non zero value will be in and then places a random
                        //number into that slot.
                    }
            }
        }

The four errors I get are:

request for member `columnNumber' in `*(((SparseMatrix*)this)->SparseMatrix::arrayOfPointer + (+(((unsigned int)n) * 4u)))', which is of non-class type `ObjectClass*'
on line 8.

request for member `collumnNumber' in `*(((SparseMatrix*)this)->SparseMatrix::arrayOfPointer + (+(((unsigned int)n) * 4u)))', which is of non-class type `ObjectClass*'
On line 10.

request for member `collumnNumber' in `*(((SparseMatrix*)this)->SparseMatrix::arrayOfPointer + (+(((unsigned int)n) * 4u)))', which is of non-class type `ObjectClass*'
on line 12.

request for member `value' in `*(((SparseMatrix*)this)->SparseMatrix::arrayOfPointer + (+(((unsigned int)n) * 4u)))', which is of non-class type `ObjectClass*'
On line 13.


I noticed that the error messages mentioned the this pointer, I don't understand why.

Thanks

Your problem is, you're trying to perform binary operations with one parameter of type int, and the other of type ObjectClass. Can't do that. You need to either overload the operators, or use a set() function instead of a native assignment (recommended).

I tried impelementing the set function approach and still got errors.

The code now looks like this:

//Class implimentations
class ObjectClass
{
    private:
        int collumnNumber;
        double value;
        
   public:
        int getColumnNumber() const;
        double getValue() const;
        int setColumnNumber(ObjectClass);
        double setValue(ObjectClass *arrayOfPointer);
};
//******************************************************************************
class SparseMatrix
{
    private:
        int matrixInfo[11]; 
        ObjectClass ** arrayOfPointer;
           
    public:
        
                    //Main constructor
        SparseMatrix (int matrixInfo[0])
        {//compiler says error on this line.
        // says "invalid member function decaration".
            for(int n=0; n<=matrixInfo[0] ; n++)
            {
                if( **arrayOfPointer[n]!=0)
                {
                    arrayOfPointer= new ObjectClass*[matrixInfo[n]];
                    arrayOfPointer.setColumnNumber(arrayOfPointer)=(rand()%10);
                }
                 if(arrayOfPointer.getCollumnNumber() !=0)
                    {
                        *arrayOfPointer=new ObjectClass [arrayOfPointer[n].collumnNumber];
                        arrayOfPointer.setValue()=(rand()%1000);
                    
                        //If the row is to have values different from zero
                        //constructor gives a random number for which collumn
                        //The non zero value will be in and then places a random
                        //number into that slot.
                    }
            }
        } 
    //*****OBJECT'S MEMBER FUNCTIONS PROTOTYPES*****
    void print() const;
    int getMatrixInfo() const;
    void setMatrixInfo();

};

With the following function impimentations:

int ObjectClass::getColumnNumber() const
{
    return (*this).ColumnNumber;
}
//******************************************************************************
double ObjectClass::getValue() const
{
    return (*this).value;
}
//******************************************************************************
int ObjectClass::setColumnNumber(ObjectClass arrayOfPointer)
{
    return (*this).collumnNumber;
}
//******************************************************************************
double ObjectClass::setValue(ObjectClass *arrayOfPointer)
{
    return (*this).value;
}

No, that didn't help. It seems any time I try to fix any thing it either doesn't do anything or introduces new errors. This is the hardest problem I've ever worked on!

There are a few more bugs in your code:

/* line 29
 * you are checking if arrayOfPointer[n] is NULL. However,
 * since you don't initialize it (aka set it to soemthing), 
 * it will be random garbage (depending on the OS you are 
 * using, some OS do initialize new memory). 
 */
if( **arrayOfPointer[n]!=0)

/* line 32
 * arrayOfPointer is of type ObjectClass**, not of type 
 * ObjectClass. Thus you can't call functions on it, if you want
 * to call a function on it you would need to do it like this:
 * arrayOfPointers[0][0].someFunction(). 
 * Also, you are doing a call like this: 
 * arrayOfPointer.someFunction()=rand()%10 - that last part won't
 * do anything because the variable returned is a doulbe, if you 
 * want to be able to change it you need to make someFunction
 * (in this the function is called setCollumnNumber()) return double&.
 */
arrayOfPointer.setColumnNumber(arrayOfPointer)=(rand()%10);

/* line 34
 * same thing here. need to use arrayOfPointer[x][y].someFunction();
 */
arrayOfPointer.getCollumnNumber()

/* line 36
 * I don't know what this call should do, but it's currently a little weird.
 * Currently you dereference the first item of the array of arrays,
 * meaning that when originally arrayOfPointers is of type ObectClass**,
 * *arrayOfPointers is of type ObjectClass*. Maybe you want to do
 * arrayOfPointers[n] = new ObectClass[....]; ?
 */
*arrayOfPointer=new ObjectClass [arrayOfPointer[n].collumnNumber];

/* line 37
 * again, this is an invalid call - ObjectClass::setValue() takes one
 * argument of type ObjectClass*. Since it returns a double and not a
 * double&, doing arrayOfPointer[x][y].setValue()=anything won't change
 * it.
 */
arrayOfPointer.setValue()=(rand()%1000);

Are you saying that my suggestion didn't fix the error you indicate for line 24? I find that surprising, but if true, give that parameter a different name. It's possible your compiler is getting confused between that argument, and your member variable of the same name.

Well I got some more of the program figured out but I had to turn it in for a grade before I completely grasped everything but, thank you to every one who helped me with it, even if I never completely 100% understood it.

This article has been dead for over six months. Start a new discussion instead.