passing 2D array to another class C++ - c++

I am trying to calculate the perimeter of a rectangle. first I will prompt the user 4 times for the X and Y cords and store it into a 2D array and pass this 2D array to another class which is method class to proceed with the calculation of the perimeter. But the problem is, I don't know how to pass the 2d array to method class.
I am not asking how to calculate the perimeter, I only need to know how to pass the 2D array from main to method class and get the 2D array at method class.
Please advise.
main.cpp
Method method;
int main() {
int storeXandY[4][2];
for(int i=1;i<5;i++)
{
cout << "Please enter x-ordinate" << i<< endl;
cin>>storeXandY[i][0];
cout << "Please enter y-ordinate" << i << endl;
cin>>storeXandY[i][1];
}
//how to pass the 2D array to method class to do some calculations?
// I was thinking something like passing the 2d array to a consturctor but don't know whether it can be done
method.constructor(storeXandY);
}
method.h
//not sure of what to do
public:
constructor() {
}
method.cpp
//how to get the cords from 2d array from main
Please advise. Thanks

You can do it as :
class Method{
...
public int calcPerimeter(int vals[4][2])
{
// do your calculation here using vals array
}
...
}
From main(), you can simply do :
Method m = new Method();
int perimeter;
m.calcPerimeter(<your_array_name>);

Since you are writing C++, you should try to avoid using C-style arrays. I would do this
Method method;
int main() {
vector<vector<int> > storeXandY(4);
for(int i=0; i!=4; ++i) storeXandY[i].resize(2);
for(int i=1;i<5;i++)
{
cout << "Please enter x-ordinate" << i<< endl;
cin>>storeXandY[i-1][0]; /* you need i-1 here, not i */
cout << "Please enter y-ordinate" << i << endl;
cin>>storeXandY[i-1][1];
}
method.calcPerimeter(storeXandY);
}
where method::calcPerimeter is declared as follows
your_return_type method::calcPerimeter(const vector<vector<int> >& rectangle);
The advantage of using vectors is that you can get the number of elements they hold by invoking their size member function, so that in the above code storeXandY.size() is equal to 4 and storeXandY[0].size() is equal to 2.

Related

Working with vectors and loops

sorry to post a student question here. I'm not looking for a quick solution, I'm looking to understand. Comments in my code will explain the same, but here's a plain text version:
This is the beginning of a "LoShu Magic Square", I'm not to the addition of all parts of the matrix I'm making, I'm stuck at trying to verify that the same number has not been put into the rows before. My idea was to use one vector to "test" numbers that had been entered so far, so it does not need to be multi-dimensional (none of them are, but I don't care about the limit on the tester).
As-is the code will take the first number into the test vector, go to the check function, realize that number is there (which it should, haven't hashed out where to add the initial value), and after that initial check it will take ANY other value between 1-9, including repeats, which is bad. Help please? Why does it stop recognizing values inside the test vector after the initial round?
Separate link to code if it's maybe easier to read there: http://ideone.com/Dzh4mJ
#include<iostream> // This is the beginning of a "LoShu magic square" program for class, currently my
#include <vector> // goal is simply getting vectors to check whether or not a number has already been
using namespace std; // entered, and if so to go back and ask for another one. As-is it does not work
// through the first iteration. It recognizes the first number, says it's already in
bool theCheckening(vector<int>, int ); // and proceeds to take ANY numbers afterwards, repeats and all.
int main () {
int tester;
vector<int> loShu1; // Rows 1-3 of a "square"
vector<int> loShu2;
vector<int> loShu3;
vector<int> testCaseOut(1,0); // Test vector to iterate inside check function
do {
do{
cout << "Enter 1-9: "; // Working as intended, makes sure no number besides 1-9 is entered
cin >> tester;
} while (tester < 1 || tester > 9);
// Put initial value into test Vector
if (theCheckening(testCaseOut, tester)){ // If check function returns true, add value to row 1
loShu1.push_back(tester);
testCaseOut.push_back(tester);
cout << "It worked?!";
}
} while (loShu1.size() <= 2); // shooting for size of 3, working as intended
for (int var : loShu1) // Debug to see rows before maths and adding them (to come)
cout << var << " ";
cout << "\n";
for (int var : loShu2)
cout << var << " ";
cout << "\n";
for (int var : loShu3)
cout << var << " ";
return 0;
}
bool theCheckening(vector<int> testCaseInc, int testInt) {
int count;
vector<int> testCase(testCaseInc); // Initialize vector inside check function to current test numbers
for (int var : testCase)
cout << var << " ";
for (count = 0;count<=testCase.size();count++) { // for all the numbers inside the testing vector
if (testCase[count]!=testInt){ // if current position of test vector is ! in vector already,
cout << "ADDED!"; // add it to row back in main()
return true;
for (int var : testCase)
cout << var << " ";
}
cout << "ALREADY ENTERED!"; // Debug
cout << testCase.size();
return false; // otherwise, ignore and ask for another number
}
}
i think you have a logical error in your theCheckening function.
As far as i understand you want your function to return TRUE if the value is NOT in in the vector and FALSE if it IS in your vector.
Now to the problem:
Imagine someone has tipped in the following values to your code:
1 2 5 8
This values will be added to your vector and the vector will also contain:
1 2 5 8
Now let's say you tipp one more time the 2. Your Function will now start with value 1 of the vector and compare it to the 2. This is of course FALSE.
Look at your code:
if (testCase[count]!=testInt)
return true;
Your code says you can now return true. Which will cause your function to end and return true to the caller.
You didn't check the following values of the vector.
Your function theCheckening should look like this:
// user const vector<int> &, which will not cause to copy the
// vector
bool theCheckening(const vector<int> & testCase, int testInt) {
// use size_t which represents a integer datatype which
// is as big as arrays can be in the current bit setting
// 32 bit => size_t = unsigned int
// 64 bit => size_t = unsigned long long
for(size_t count = 0; count <= testCase.size(); count++) {
if(testCase[i] == testInt)
return false;
}
return true;
}
I hope this works and i understood this qestion correctly.

I can't create proper std::vector in c++

I have to create a list of objects, so to keep it as smooth as possible I wanted to use std::vector instead of regular array of objects. However I don't exactly know how to use them properly. Here is sample code from my class in which I try to add objects to vecor and in 2nd method to display them.
private:
vector <Student> stud;
public:
void Student::dodaj(){
stud.push_back(Student(getNaz(), getImie(), getLeg(), getRok()));
}
void Student::wypisz(){
cout << "Lista osob:\n";
for (int i = 0; i < 1; i++)
{
cout << endl;
cout << "Nazwisko: " << stud[i].nazwisko << endl;
cout << "Imie: " << stud[i].imie << endl;
cout << "Numer indeksu.: " << stud[i].legitymacja << endl;
cout << "Rok studiow: " << stud[i].rok << endl;
}
And my main:
Student st("Kowalski", "Jan", 123455, 2);
Student test1("Nowak", "Jan", 123, 2);
st.dodaj();
test1.dodaj();
test1.wypisz();
However the output result is only one object for wich I use wypisz(print/display) method, in this case test1, that is displayed instead of two of them - st and test1. Any ideas how to fix that?
It appears that stud is a member of Student, which means that each Student object contains its own vector. When you call dodaj on a particular student, it just adds its own details to the vector it contains.
st.dodaj(); // Adds details of st to st's own vector
test1.dodaj(); // Adds details of test1 to test1's own vector
// Now we have one vector inside st containing a single element
// and one vector inside test1 containing a single element
test1.wypisz(); // Prints elements from test1's vector
Instead, your vector should be outside of your Student class (or at least static). One option would be to do this:
Student st("Kowalski", "Jan", 123455, 2);
Student test1("Nowak", "Jan", 123, 2);
std::vector<Student> stud;
std.push_back(st);
std.push_back(test1);
You may want to have another class (maybe School?) which contains this vector.

How to add items to a 2-dimensional dynamic vector

I have so far been able to use 1-d vectors, adding or removing elements with push/pop back.
However, when trying to fill out a 2-d vector which is supposed to represent a matrix, I run into problems. I haven't been able to use these functionalities with my 2-d vector. When the code does compile and run I get the bits asking for dimension and then it asks for the first element [1,1], for any value entered IĀ get "Segmentation fault: core dumped". I have no idea what is going on and have been trying to modify bits of my code but to no great success, the internet has also been rather useless in giving an easy guide on how to fill out these damn things...
Thank you so much!
Here is my code
#include <iostream>
#include <vector>
using namespace std;
vector<vector<double> > readMatrix();
int main()
{
vector<vector<double> > matrix1 = readMatrix();
vector<vector<double> > matrix2 = readMatrix();
}
vector<vector<double> > readMatrix()
{
cout << "Entering a matrix" << endl;
cout << "Number of Lines : ";
int numberOfLines;
cin >> numberOfLines;
cout << "Number of Columns :";
int numberOfColumns;
cin >> numberOfColumns;
vector<vector<double> > matrix;
int i(0);
int j(0);
while(i<=numberOfLines && j<=numberOfColumns)
{
cout << "[" << i+1 << "," << j+1 << "] =" ;
int value;
cin >> value;
matrix[i].push_back(value);
cout << endl ;
j++;
if(j==numberOfColumns)
{
j=1;
i++;
}
}
return matrix;
}
Declare the matrix like this:
vector<vector<double> > matrix (y, vector<double> (x, 0));
Now you have an y*x matrix. If you want to use push_back you have to declare the x-vector when starting on a new row.
When you do vector<vector<double> > matrix; you initialize a vector of vectors, both of size 0 (that's the default), so when you do matrix[i].push_back(value) even when i==0 you access memory which you hasn't been allocated. it's better if you do pre-allocate memory like this:
vector<vector<double> > matrix(numberOfLines,vector<double>(numberOfColumns));
And then you don't need to push back or anything, you just do matrix[i][j]=whatever.
In C++ you can use the vector constructor to automatically define the size:
vector<vector<double> > matrix(numberOfLines, vector<double>(numberOfColumns, 0));
With vectors, for loops are better than while loops because the size is always known. I suggest you iterate over the vector rows and columns with these (and remove your push_back statements.)
you need to do something like:
matrix.resize( ... );
.
.
.
matrix[i].push_back( ... );
The problem here is that you don't have a two dimensional vector. You have a vector, of vectors, of doubles. You need to put some vectors in the first vector, calling resize() as above is one way. You could also pass an initial size to the constructor, you could push the vectors on one by one - though that could carry performance issues.

passing a returned pointer of a dynamical two-dimensional array to a sub-function and addressing the array

My issue is the following: I am making a pointer to a dynamic two dimensional array on the heap. This is done in a subfunction "Production" which fills in the elements of the table (array) and returns the pointer of the array to the main(). There I want to give the pointer as a parameter for another function "PrintTable"; which cout's the table. My issue is that the returned pointer is actually a one dimensional array (c++) and I don't know how to adress it to get the second row of the array..
Let me try to explain it to you:
So first I have a function which returns a pointer to a two-dimensional array.
int* Production(int num1, string name1[], int num2, string name2[])
{
int** productionTable=new int*[num1];
for (int i = 0; i < num1; i++)
{
productionTable[i] = new int[num2];
}
for (int i=0;i<num1;i++)
{
cout << "\nGive production " << name1[i]<<endl;
for (int j=0;j<num2;j++)
{
cout << "On " << name2[j] << " : ";
cin >> productionTable[i][j];
}
}
return* productionTable;
}
in the main () I let the returned pointer point to a pointer productiontable so it exists in the main.
int* productionTable=Production(num1, name1[], num2, name2[])
Then I call function printTable() witch has to output the 2dimensional array as a table. so I want to use this pointer as an argument for another function; to cout the elements from this array.
PrintTable(num1, name1[], num2, name2[], productionTable);
This function looks like this:
void printTable(int num1, string name1[], int num2, string name2[],int* productionTable)
{
cout << left <<setw(10)<< "";
for (int i=0;i<num2;i++)
{
cout << left <<setw(10)<< name2[i];
}
cout<<endl;
for (int i=0;i<num1;i++)
{
cout << setw(10)<<name1[i]<<"";
for (int j=0;j<num2;j++)
{
cout << left <<setw(10)<< productionTable[i+j];
}cout<<endl;
}
}
My problem is that I can't get the function to output the second row right. How should i adress the second parameter of the array. So far i've read i should make the table point to [COLindex * COL_size + ROWindex]. I've tried it but i dan't get him to print the second row. What should the COL_size paramter be?
This is your problem:
int** productionTable=new int*[num1];
...
return* productionTable;
Basically, by the return, you return only the first row (or a pointer to it) discarding the rest of the table. To make it work, you could declare Production and productionTable (at all places) as int**, return productionTable in Production and use productionTable[i][j] for element retrieval.
I haven't been able to wade through the creation of your table fully, so there may well be problems there. Just looking at the end bit though, it seems that you're trying to print a one-dimensional array in two dimensions, which is straightforward, you just need to keep track of how far into the array you are on each row.
For each row, you need to offset your column index by (number of columns * number of rows already printed).
It looks like num1 is the total number of rows and num2 is the total number of columns. i is the number of rows completed already. So i*num2 is the offset required to read the row you are trying to print.
for (int i=0;i<num1;i++)
{
cout << setw(10)<<name1[i]<<"";
for (int j=0;j<num2;j++)
{
cout << left <<setw(10)<< productionTable[i*num2+j];
}
cout<<endl;
}

Matrix multiplication with vectors - C++

I am working on making a program that can multiply matrices of user-defined size. I use vectors to store the values in the matrix.
void Multiply(vector<float> A,vector<float> B,int rA, int cA,int rB,int cB)
{
system(CLEARSCREEN);
vector<float> C; // The resulting matrix
int sizeA=rA*cA;
int sizeB=rB*cB;
int sizeC=rA*cB;
int lrA=sizeA-1;
int lrB=sizeB-1;
int writeHead=0;
A.resize(sizeA);
B.resize(sizeB);
C.resize(sizeC);
demoDisplay(rA,rB,cA,cB,lrA,lrB,sizeA,sizeB);
for(;writeHead<=lrA; writeHead++)
{
cout << "Please enter a value for \"" << alphabet[writeHead] << "\" in MATRIX A.\n";
cin >> A[writeHead];
}
cout << "\n";
writeHead=0;
for (;writeHead<=lrB; writeHead++)
{
cout << "Please enter a value for \"" << alphabet[writeHead] << "\" in MATRIX B.\n";
cin >> B[writeHead];
}
cout << "\n\n";
displayMatrices(A,B,rA,rB,cA,cB,lrA,lrB,sizeA,sizeB);
for (int colRead=0; colRead<=cA; colRead++) {
// somehow iterate through each element of the vector?
}
}
I'm relatively new to C++, and so I'm not quite sure how to do the actual multiplication of the two matrices. If anyone could help, it would be great.
Maybe you were mislead by the name of the vector container, that implies some mathematical use. The vector template doesn't provide any function to multiply matrices or even to multiply vectors. The vector in this case only provides you with a container to store a matrix. Obviously you store the matrices in some linearized way and that will make the multiplication more complicated later.
Be sure to read http://www.cplusplus.com/reference/stl/vector/
Furthermore you dont really want to iterate through the vectors, because if that was the case, you could have just used some other container. You want random access to do multiply the columns and rows by hand. For this you can use the []-operator] or the at() member function.
Then it is just a matter of doing the multiplication by hand, as for example shown here(which also includes some pseudo code).