Iterator design pattern for 2d vector c++, OOP - c++

I'm beginner in C++. In my program I've created a matrix and wrote some func to operate with its cols and rows. Instead of i and j counters i want to implement iterator design pattern Didn't find proper info here. Can you pls help me with this task? Here is my code:
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
#define C 5
template <class T>
class myMatrix
{
private:
int col, row;
vector<vector<T>> matrix;
public:
myMatrix(int a, int b)
{
col = b;
row = a;
matrix.assign(a, vector<T>(b));
}
void copy_row(int numb);
void copy_col(int numb);
void input();
void output();
~myMatrix() { }
};
template <class T>
void myMatrix<T>::copy_row(int numb)
{
for (int i = 0; i < col; i++)
cout << matrix[numb][i] << " ";
}
template <class T>
void myMatrix<T>::copy_col(int numb)
{
for (int i = 0; i < row; i++)
cout << matrix[i][numb] << endl;
}
template <class T>
void myMatrix<T>::input()
{
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
T number;
cin >> matrix[i][j];
}
}
template <class T>
void myMatrix<T>::output()
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
cout << setw(10) << left << matrix[i][j];
cout << endl;
}
cout << endl;
}
int main()
{
int a, b;
myMatrix<int> matrix1(5, 5);
cout << "Put in the matrix 5x5: " << endl;
matrix1.input();
cout << endl;
matrix1.output();
cout << "Put the column number to copy: ";
cin >> a;
cout << endl;
matrix1.copy_col(a - 1);
cout << endl;
cout << "Put the row number to copy: ";
cin >> b;
cout << endl;
matrix1.copy_row(b - 1);
cout << endl;
return 0;
}

Related

array elements not printing when trying to print in the main function

I want to find the factors of a product by using arrays to check whether they equal it or not
the values do not print
here is the code
#include <iostream>
using namespace std;
int main() {
int arr[5] = { 1,3,5,7,2 };
int arr1[5] = { 0,6,5,4,9 };
int X;
cout << "Please enter X:"; cin >> X;
for (int i = 0, j = 0; i < 5 && j < 5; ++i, ++j) {
if (arr[i]*arr[j]==X) {
cout << arr[i] << " ";
cout << arr1[j] << " ";
}
}
}
Use this nested loops
for (int i = 0; i < 5 ;++i) {
for(int j=0 ;j<5;++j){
if (arr[i]*arr1[j]==X) {
cout << arr[i] << " ";
cout << arr1[j] << " ";
}
}
}

How do I use the dot operator on a 2D Vector of my class while accessing a function of that class?

I have trouble explaining what I'm trying to do--sorry if i botched the title: so, I made a 2D Vector. The 2D Vector is an object of my class which is named Matrix. I tried doing matrix.fill2dVector(numRows,numCols), and I would get these errors:
class "std::vector<std::vector<Matrix, std::allocator<Matrix>>, std::allocator<std::vector<Matrix, std::allocator<Matrix>>>>" has no member "fill2dVector"
'fill2dVector': is not a member of 'std::vector<std::vector<Matrix,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>'
I can see that it's trying to find fill2dVector inside the STL vector container; but, I don't want it to do that. Also, I'm stuck using the functions in the prototypes since this is an assignment for my class, but I am allowed to modify them.
#include <iostream>
#include <vector>
class Matrix
{
public:
Matrix();
double& operator()(const int rn, const int cn);
void operator()();
void fill2dVector(int &numRows, int &numCols);
void display2dVector(int &numRows, int &numCols) const;
private:
int numRows = 10, numCols = 10;
std::vector<std::vector <double>> data;
};
Matrix::Matrix()
{
data[10][10] = {};
}
double& Matrix::operator()(const int rn, const int cn)
{
return data[rn][cn];
}
void Matrix::operator()()
{
for (int r = 0; r < numRows; ++r)
{
for (int c = 0; c < numCols; ++c)
{
data[r][c] = 0;
}
}
}
void Matrix::display2dVector(int &numRows, int &numCols) const
{
for (int r = 0; r < numRows; ++r)
{
for (int c = 0; c < numCols; ++c)
{
std::cout << " " << data[r][c] << " ";
}
std::cout << std::endl;
}
}
void Matrix::fill2dVector(int &numRows, int &numCols)
{
for (int r = 0; r < numRows; ++r)
{
std::cout << "Enter " << numCols << " values for row #" << r << std::endl;
for (int c = 0; c < numCols; ++c)
{
std::cin >> data[r][c];
}
std::cout << std::endl;
}
}
int main()
{
std::cout << "Enter the size of the matrix:" << std::endl;
std::cout << " How many rows? ";
int numRows;
std::cin >> numRows;
std::cout << "How many columns? ";
int numCols;
std::cin >> numCols;
std::cout << std::endl;
std::cout << "*** numRows = " << numRows << ", " << "numCols = " << numCols << std::endl;
std::vector< std::vector <Matrix> > matrix;
std::cout << "Contents of the " << numRows << " x " << numCols << " vector:" << std::endl;
matrix.fill2dVector(numRows,numCols);
}
Instead of :
std::vector< std::vector <Matrix> > matrix;
Write :
Matrix matrix;
Also your matrix implementation is broken because you access vector elements without allocation and while filling doesn't check for vector size so you can get into an access out of bounds and why are you passing those ints by reference ?
I am not 100% sure if I understand your question so I think
I provide a code sample on accessing a 3d vector object I wrote
a while ago and my guess is, this will really help you solve your
Question. Just remove one layer for accessing a 2d vector.
With that Example code you should be able to solve your question.
There is also a <random> example referring to another question of yours.
#include <iostream> // cout
#include <vector> // vector
#include <random> //rand, srand
#include <algorithm> //shuffle
#include <string> //using strings
#include <limits> //cin
using my_engine = std::random_device; //most random
class deck
{
std::string comment;
public:
void output(std::string); //txt output
void display_card_deck();//display all cards
void mix_cards(); //delete and remix deck new game
size_t getCards(size_t playnum, size_t color, size_t number);
private:
size_t _inp_check(); //input player number + check
std::vector < std::vector < std::vector < size_t > > > _card_deck; //assign 3d vector
void _shuffle_cards(size_t players); //mix and shuffle cards randomly
};
void deck::output(std::string comment)
{
std::cout << comment << " cards are used for " << _card_deck.size() << std::endl;
}
int main()
{
deck play;
//round 1
play.mix_cards(); //mix cards randomly and input player number 2-8
play.output ("Welcome Player ... and Player ... "); //text, number of players
std::cout << play.getCards(0,2,2) << "test output" << std::endl; //pick one card
//round 2
play.mix_cards();
std::cout << play.getCards(0,2,2) << std::endl; //pick one card
play.output ("Welcome Player ... and Player ... "); //text, number of players
play.display_card_deck();
return 0;
}
//members of deck class
size_t deck :: _inp_check()
{
size_t input;
while (!(std::cin >> input) || input < 2 || input > 8)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Try again and enter a valid player number from 2 to 8: "<< "\n";
}
return input;
}
void deck :: mix_cards()
{
if (_card_deck.empty())
{
std::cout << "How many Players are playing today? (2-8):" << std::endl;
size_t players = _inp_check();
_shuffle_cards(players);
}
else
{
std::cout << "How many Players are playing today? (2-8):" << std::endl;
_card_deck.clear();
size_t players = _inp_check();
_shuffle_cards(players);
}
}
void deck :: _shuffle_cards(size_t players)
{
my_engine engn; //random_device
for(size_t playnum = 0; playnum < players; ++playnum)
{
std::vector < std::vector < size_t > > d1;
_card_deck.push_back( d1 );
for(size_t color = 0; color < 4; color++)
{
std::vector < size_t > d2;
_card_deck[playnum].push_back( d2 );
for(size_t k = 1; k < 11; k++)
{
_card_deck[playnum][color].push_back( k ); //1 2 3 4 5 6 7 8 9 10
}
shuffle(_card_deck[playnum][color].begin(), _card_deck[playnum][color].end(), engn);
}
}
}
void deck :: display_card_deck()
{
for (size_t i = 0; i < _card_deck.size(); i++)
{
for (size_t j = 0; j < _card_deck[i].size(); j++)
{
for (size_t k = 0; k < _card_deck[i][j].size(); k++)
{
std::cout << "_card_deck[" << i << "][" << j << "][" << k << "] = " << _card_deck[i][j][k] << std::endl;
}
}
}
}
size_t deck::getCards(size_t playnum, size_t color, size_t number)
{
return _card_deck[playnum][color][number];
}

Equivalence Relation

I am stuck on what to do next... The program is suppose to check to see if entered Zero-One Matrix is an Equivalence relation (transitive, symmetric, and reflexive) or not. I am still new to C++ (started this semester). I know how to create the matrix using vector but not on how to check if it is equivalence relation or not..
I assume I need to use boolean function but I'm stuck on what I need to put in as an argument or if this is correct. My original thought was... so for symmetric it will look like (which I know this goes after #include and beofre int main(). Any help would be awesome.
bool isSymmetric(vector<int> &vect, int Value)
{
for (int i = 0; i < Value; i++)
for (int j = 0; j < Value; j++)
if (vect[i][j] != vect[j][i])
return false;
return true;
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector< vector<int> > vec;
cout << "NxN matrix N: ";
int Value;
cin >> Value;
cout << Value << "x" << Value << " matrix\n";
for (int i = 0; i < Value; i++) {
vector<int> row;
for (int j = 0; j < Value; j++) {
cout << "Enter a number (0 or 1): ";
int User_num;
cin >> User_num;
while (User_num != 0 && User_num != 1) {
cout << "Invalid Entry! Enter 0 or 1!\n";
cout << "Enter a number (0 or 1): ";
cin >> User_num;
}
row.push_back(User_num);
}
vec.push_back(row);
}
cout << endl;
for (int i = 0; i < Value; i++) {
for (int j = 0; j < Value; j++) {
cout << vec[i][j] << " ";
}
cout << endl;
}
cout << endl;
system("pause");
return 0;
}

Passing 2D array to a Function in c++

I am Having Problem with Passing a 2D array to a c++ Function. The function is supposed to print the value of 2D array. But getting errors.
In function void showAttributeUsage(int)
Invalid types for int(int) for array subscript.
I know the problem is with the syntax in which I am passing the particular array to function but I don't know how to have this particular problem solved.
Code:
#include <iostream>
using namespace std;
void showAttributeUsage(int);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
int attVal[qN][aN];
cout << "\nEnter Attribute Usage Values" << endl;
for(int n = 0; n < qN; n++) { //for looping in queries
cout << "\n\n***************** COLUMN " << n + 1 << " *******************\n\n";
for(int i = 0; i < aN; i++) { //for looping in Attributes
LOOP1:
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if((attVal[n][i] > 1) || (attVal[n][i] < 0)) {
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
goto LOOP1; //if wrong input value
}
}
}
showAttributeUsage(attVal[qN][aN]);
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
getch();
return 0;
}
void showAttributeUsage(int att)
{
int n = 0, i = 0;
while(n != '\0') {
while(i != '\0') {
cout << att[n][i] << " ";
i++;
}
cout << endl;
n++;
}
}
I really suggest to use std::vector : live example
void showAttributeUsage(const std::vector<std::vector<int>>& att)
{
for (std::size_t n = 0; n != att.size(); ++n) {
for (std::size_t i = 0; i != att.size(); ++i) {
cout << att[n][i] << " ";
}
cout << endl;
}
}
And call it that way:
showAttributeUsage(attVal);
Looking at your code, I see no reason why you can't use std::vector.
First, your code uses a non-standard C++ extension, namely Variable Length Arrays (VLA). If your goal is to write standard C++ code, what you wrote is not valid standard C++.
Second, your initial attempt of passing an int is wrong, but if you were to use vector, your attempt at passing an int will look almost identical if you used vector.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
typedef std::vector<int> IntArray;
typedef std::vector<IntArray> IntArray2D;
using namespace std;
void showAttributeUsage(const IntArray2D&);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
IntArray2D attVal(qN, IntArray(aN));
//... Input left out ...
showAttributeUsage(attVal);
return 0;
}
void showAttributeUsage(const IntArray2D& att)
{
for_each(att.begin(), att.end(),
[](const IntArray& ia) {std::copy(ia.begin(), ia.end(), ostream_iterator<int>(cout, " ")); cout << endl;});
}
I left out the input part of the code. The vector uses [] just like a regular array, so no code has to be rewritten once you declare the vector. You can use the code given to you in the other answer by molbdnilo for inputing the data (without using the goto).
Second, just to throw it into the mix, the showAttributeUsage function uses the copy algorithm to output the information. The for_each goes throw each row of the vector, calling std::copy for the row of elements. If you are using a C++11 compliant compiler, the above should compile.
You should declare the function like this.
void array_function(int m, int n, float a[m][n])
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a[i][j] = 0.0;
}
where you pass in the dimensions of array.
This question has already been answered here. You need to use pointers or templates. Other solutions exists too.
In short do something like this:
template <size_t rows, size_t cols>
void showAttributeUsage(int (&array)[rows][cols])
{
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < cols; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
You're using a compiler extension that lets you declare arrays with a size determined at runtime.
There is no way to pass a 2D array with such dimensions to a function, since all but one dimension for an array as a function parameter must be known at compile time.
You can use fixed dimensions and use the values read as limits that you pass to the function:
const int max_queries = 100;
const int max_attributes = 100;
void showAttributeUsage(int array[max_queries][max_attributes], int queries, int attributes);
int main()
{
int attVal[max_queries][max_attributes];
int qN = 0;
int aN = 0;
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
cout << "\nEnter Attribute Usage Values" << endl;
for (int n = 0; n < qN; n++)
{
cout << "\n\n***************** COLUMN " << n + 1 <<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad_input = true;
while (bad_input)
{
bad_input = false; // Assume that input will be correct this time.
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad_input = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal, qN, aN);
getch();
return 0;
}
void showAttributeUsage(int att[max_queries][max_attributes], int queries, int attributes)
{
for (int i = 0; i < queries; i++)
{
for (int j = 0; j < attributes; j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
For comparison, the same program using std::vector, which is almost identical but with no size limitations:
void showAttributeUsage(vector<vector<int> > att);
int main()
{
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
vector<vector<int> > attVal(qN, vector<int>(aN));
cout << "\nEnter Attribute Usage Values"<<endl;
for (int n = 0; n < qN; n++)
{
cout<<"\n\n***************** COLUMN "<<n+1<<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad = true;
while (bad)
{
bad = false;
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal);
getch();
return 0;
}
void showAttributeUsage(vector<vector<int> > att);
{
for (int i = 0; i < att.size(); i++)
{
for (int j = 0; j < att[i].size(); j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
The Particular Logic worked for me. At last found it. :-)
int** create2dArray(int rows, int cols) {
int** array = new int*[rows];
for (int row=0; row<rows; row++) {
array[row] = new int[cols];
}
return array;
}
void delete2dArray(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
delete [] ar[row];
}
delete [] ar;
}
void loadDefault(int **ar, int rows, int cols) {
int a = 0;
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
ar[row][col] = a++;
}
}
}
void print(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
cout << " | " << ar[row][col];
}
cout << " | " << endl;
}
}
int main () {
int rows = 0;
int cols = 0;
cout<<"ENTER NUMBER OF ROWS:\t";cin>>rows;
cout<<"\nENTER NUMBER OF COLUMNS:\t";cin>>cols;
cout<<"\n\n";
int** a = create2dArray(rows, cols);
loadDefault(a, rows, cols);
print(a, rows, cols);
delete2dArray(a, rows, cols);
getch();
return 0;
}
if its c++ then you can use a templete that would work with any number of dimensions
template<typename T>
void func(T& v)
{
// code here
}
int main()
{
int arr[][7] = {
{1,2,3,4,5,6,7},
{1,2,3,4,5,6,7}
};
func(arr);
char triplestring[][2][5] = {
{
"str1",
"str2"
},
{
"str3",
"str4"
}
};
func(triplestring);
return 0;
}

Why isnt my simpleVector.cpp linking? (starting out with c++)

i got the .cpp and .h straight from the book, it seems as if nothing is missing, but im getting these linking errors....
#ifndef SIMPLEVECTOR_H
#define SIMPLEVECTOR_H
#include <iostream>
#include <new> // needed for bad__alloc exception
#include <cstdlib> // needed for the exit function
using namespace std;
template <class T>
class simplevector
{
private:
T *aptr;
int arraysize;
void memerror(); // handles mem aloc errors
void suberror(); // handles subscripts out of range
public:
simplevector() // default constructor
{ aptr = 0; arraysize = 0; }
simplevector(int); // constructor
simplevector(const simplevector &); // coppy constructor
~simplevector();
int size()
{ return arraysize; }
T &operator[](const int &); // overloaded [] operator
};
template <class T>
simplevector<T>::simplevector(int s)
{
arraysize = s;
// allocate memory for the array
try
{
aptr = new T [s];
}
catch (bad_alloc)
{
memerror();
}
// initialize the array.
for (int count = 0; count < arraysize; count++)
*(aptr + count) = 0;
}
template <class T>
simplevector<T>::simplevector(const simplevector &obj)
{
arraysize = obj.arraysize;
aptr = new T [arraysize];
if (aptr == 0)
memerror();
for(int count = 0; count < arraysize; count++)
*(aptr + count) = *(obj.aptr + count);
}
template <class T>
simplevector<T>::~simplevector()
{
if (arraysize > 0)
delete [] aptr;
}
template <class T>
void simplevector<T>::memerror()
{
cout << "ERROR: Cannot allocate memory.\n";
exit(0);
}
template <class T>
T &simplevector<T>::operator [](const int &sub)
{
if (sub < 0 || sub >= arraysize)
suberror();
return aptr[sub];
}
#endif
This program demonstrates the simplevector template:
#include <iostream>
#include "simplevector.h"
using namespace std;
int main()
{
simplevector<int> inttable(10);
simplevector<float> floattable(10);
int x;
//store values in the arrays.
for (x = 0; x < 10; x++)
{
inttable[x] = (x * 2);
floattable[x] = (x * 2.14);
}
//display the values in the arrays.
cout << "these values are in inttable:\n";
for (x = 0; x< 10; x++)
cout << inttable[x] << " ";
cout << endl;
cout << "these values are in floattable:\n";
for (x = 0; x< 10; x++)
cout << floattable[x] << " ";
cout << endl;
//use the standard + operator on array elements.
cout << "\nAdding 5 to each element of inttable"
<< " and floattable.\n";
for (x = 0; x< 10; x++)
{
inttable[x] = inttable[x] + 5;
floattable[x] = floattable[x] + 1.5;
}
//display the values in the array.
cout << "These values are in inttable:\n";
for (x = 0; x< 10; x++)
cout << inttable[x] << " ";
cout << endl;
cout << "These values are in floattable:\n";
for (x = 0; x< 10; x++)
cout << floattable[x] << " ";
cout << endl;
// use the standard ++ operator on array elements.
cout << "\nIncrementing each element of inttable and"
<< " floattable.\n";
for (x = 0; x< 10; x++)
{
inttable[x]++;
floattable[x]++;
}
//display the values in the array.
cout << "These values are in inttable:\n";
for (x = 0; x< 10; x++)
cout << inttable[x] << " ";
cout << endl;
cout << "These values are in floattable:\n";
for (x = 0; x< 10; x++)
cout << floattable[x] << " ";
cout << endl;
return 0;
}
It's right there in the errors you posted in the OP comments - you declared simplevector::suberror without ever defining it.
Where are the guts of suberror()? I don't see that in the class implementation.