I need copy a matrix that I have set up as M into a new matrix M2 and output that matrix.
How can this be done?
Here's what I tried so far:
#include <iostream>
using namespace std;
#define N 24
void copy(int M[][N], int M2[][N], int ROWS, int COLS)
{
int r, c;
M2[r][c]= M[r][c];
cout<< M2[r][c];
}
void print(int M[][N], int ROWS, int COLS)
{
int r, c, row, col;
row= 1;
col= 1;
M[row][col] = 2;
for(r=0; r< ROWS; r++)
{
for(c=0; c < COLS; c++)
{
if(M[r][c]==0)
{
cout<<" ";
}
else if (M[r][c]==1)
{
cout<< "T";
}
else if (M[r][c]==2)
{
cout<< "*";
}
else
{
cout << M[r][c];
}
}
cout <<endl;
}
}
void fill(int M[][N], int ROWS, int COLS, int row, int col)
{
int r, c;
for(r=0; r< ROWS; r++)
{
for(c=0; c < COLS; c++)
{
if (r == 0 || r == ROWS - 1) {
M[r][c]=0;
}
else if(c == 0 || c == COLS -1) {
M[r][c]=0;
}
else {
M[r][c]= 1;
}
}
}
}
int main()
{
int M[N/2][N];
int M2[N/2][N];
int ROWS, COLS;
int r, c;
ROWS = sizeof(M) / sizeof(M[0]);
COLS = sizeof(M[0]) / sizeof(M[0][0]);
fill(M, ROWS, COLS, 1, 1);
print(M, ROWS, COLS);
copy(M, M2, ROWS, COLS);
return 0;
}
Here is a problem:
int r, c;
M2[r][c]= M[r][c];
You never assigned r and c, they contain some unknown value, which might well be outside the range 0..ROWS-1 and 0..COLS-1.
Don't use uninitialized values, especially in pointer arithmetic.
To copy the entire matrix, you will probably need some loops like you have in the print function.
Since you are using two dimensional arrays to store the matrices, the copy of one into the other should be as simple as one call to memcpy. The contents of any array (regardless of dimension) are stored contiguously in memory.
In your copy function, just place the following line of code inside:
memcpy(M2, M1, r * c * sizeof(int));
Before the memcpy, make sure you have the appropriate values assigned to r and c (obviously this should be the correct number of rows and correct number of columns).
Related
I'm trying to split a matrix given into 4, but I'm getting some errors and I can't figure out why. I'm kind of new to the language. Does anybody knows what am I doing wrong?
void split_tl(T **matrice, unsigned int dim){
if(dim == 1){
return;
}
T **tl = new T*[dim/4];
for(unsigned int i = 0; i<dim/4;++i){
tl[i] = new T[dim/4];
}
for(unsigned int i=0; i<dim;++i){
for(unsigned int j=0; j<dim;j++){
if((i<dim/2) && (j<dim/2)){
tl[i][j] = matrice[i][j];
} else{
std::cout << "no ";
}
}
std::cout << std::endl;
}
}
In this function I'm trying to obtain the top left corner of the matrix.
int **matrice = new int*[2];
for(unsigned int i = 0; i<2;++i){
matrice[i] = new int[2];
}
for(unsigned int i = 0; i<2;++i){
for(unsigned int j = 0; j<2;++j){
matrice[i][j] = i+j;
}
}
This is the matrix I'm sending. It is a 2x2 matrix, just for testing purposes.
These are the errors from Valgrind:
==133== Invalid read of size 8
==133== Invalid write of size 4
==133== Process terminating with default action of signal 11 (SIGSEGV)
==133== Access not within mapped region at address 0x0
If dim is the side of a matrix, allocating to a quarter matrix should be dim/2.
Below in the code you are using :
if((i<dim/2) && (j<dim/2)){
tl[i][j] = matrice[i][j];
}
here tl may exceed the allocation
What you're doing wrong? You're allocating memory and passing pointers around.
Build a proper matrix class, e.g. (very simplified version):
template <typename T, unsigned Rows, unsigned Cols>
struct generic_matrix {
using datatype = T;
static constexpr unsigned rows = Rows;
static constexpr unsigned cols = Cols;
datatype data[rows][cols];
constexpr datatype& operator()(unsigned row, unsigned col) noexcept
{ return data[row][col]; }
constexpr const datatype& operator()(unsigned row, unsigned col) const noexcept
{ return data[row][col]; }
};
Submatrix:
/* Returns a submatrix of the matrix m,
* by deleting the row r and the column c.*/
template <typename M>
auto submatrix(const M& m, unsigned r, unsigned c) noexcept
{
generic_matrix<typename M::datatype, M::rows-1, M::cols-1> res;
for (unsigned row = 0, i = 0; row < M::rows; ++row) {
if (row == r) continue; //this row we do not want
for (unsigned col = 0, j = 0; col < M::cols; ++col) {
if (col == c) continue; //this col we do not want
res(i,j) = m(row,col);
++j;
}
++i;
}
return res;
}
Print:
template <typename M>
void printmatrix(const M& m) noexcept
{
for (unsigned r=0; r < M::rows; ++r) {
for (unsigned c=0; c < M::cols; ++c) {
std::cout << m(r,c) << ' ';
}
std::cout << '\n';
}
}
Test:
int main()
{
int n=0;
generic_matrix<int, 3, 3> m;
for (int r = 0; r < 3; ++r)
for (int c = 0; c < 3; ++c)
m(r,c) = ++n;
printmatrix(m);
std::cout << '\n';
printmatrix(submatrix(m, 0, 0));
std::cout << '\n';
printmatrix(submatrix(m, 1, 1));
std::cout << '\n';
printmatrix(submatrix(m, 2, 2));
return 0;
}
Note: It is just a hint. As you can see, no allocation nor casting is needed.
Does accessing the same array's different elements create a data race?
I have a "Matrix" wrapper class for an array with matrix interface, and i wrote a parallel multiplication by a scalar function for it.
I use CTPL library for thread pools.
I know that writing from a thread into an array cell passed by reference is not a data race (please correct me if i'm wrong) so i decided to pass a cell from the array to the function so i can write multiplication result into the cell itself, not by passing the reference to an array and the index, so i can avoid a data race.
I ran the function 10k times and the results did not differ even once, but a sanitizer i use ("-fsanitize=thread -fPIE -pie -g" in Cmake flags) still alerts me of a data race on the line where i create the thread pool.
Is the sanitizer mistaken or am i really experiencing a data race somewhere?
Here are the pieces of code, relevant to the prolem:
Wrapper:
class Matrix {
protected:
int width;
int height;
double* matrix;
public:
Matrix(int m, int n);
Matrix(int m, int n, const std::vector<double>& values);
int get_width() {
return width;
}
int get_height() {
return height;
}
double get_element(int row_num, int col_num);
void set_element(int row_num, int col_num, double el);
double* get_cell_ref(int row_num, int col_num);
};
Method implementations:
Matrix::Matrix(int m, int n) {
assert(m > 0 && n > 0);
matrix = new double[m * n]{0};
width = n;
height = m;
}
Matrix::Matrix(int m, int n, const std::vector<double>& values) {
assert(m > 0 && n > 0 && values.size() == m * n);
matrix = new double[m * n];
width = n;
height = m;
for (int i = 0; i < m * n; ++i) {
matrix[i] = values[i];
}
}
double Matrix::get_element(int row_num, int col_num) {
assert(check_valid(row_num, col_num, get_width(), get_height()));
return matrix[col_num + get_width() * row_num];
}
void Matrix::set_element(int row_num, int col_num, double el) {
assert(check_valid(row_num, col_num, get_width(), get_height()));
matrix[col_num + row_num * get_width()] = el;
}
double* Matrix::get_cell_ref(int row_num, int col_num) {
int idx = col_num + get_width() * row_num;
return &matrix[idx];
}
The function that supposedly has a data race:
Matrix* scalar_multiply_parallel(Matrix* a, double mul, int threadN) {
auto* b = new Matrix(a->get_height(), a->get_width());
ctpl::thread_pool thr_pool(threadN);
std::vector<std::future<void>> futures(a->get_height() * a->get_width());
for (int i =0; i < a->get_height(); i++) {
for (int j =0; j < a->get_width(); j++) {
int idx = j + a->get_width() * i;
auto util = [&a, &b, i, j, mul](int) {
//b->set_element(i, j, a->get_element(i, j) * mul);
double *cell;
cell = b->get_cell_ref(i, j);
*cell = a->get_element(i, j) * mul;
};
futures[idx] = thr_pool.push(util);
}
}
for (auto& f: futures) {
f.get();
}
return b;
}
Hi I have started solving C++ questions. One among them is rotating a N x N matrix to a 90 degree clockwise.
below is the code link, that i'm referring to. I had never solved matrix problems in C++/any.
http://www.geeksforgeeks.org/turn-an-image-by-90-degree/
#include <stdio.h>
#include <stdlib.h>
void displayMatrix(unsigned int const *p, unsigned int row, unsigned int col);
void rotate(unsigned int *pS, unsigned int *pD, unsigned int row, unsigned int col);
int main()
{
// declarations
unsigned int image[][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
unsigned int *pSource;
unsigned int *pDestination;
unsigned int m, n;
// setting initial values and memory allocation
m = 3, n = 4, pSource = (unsigned int *)image;
pDestination = (unsigned int *)malloc(sizeof(int)*m*n);
// process each buffer
displayMatrix(pSource, m, n);
rotate(pSource, pDestination, m, n);
displayMatrix(pDestination, n, m);
free(pDestination);
getchar();
return 0;
}
void displayMatrix(unsigned int const *p, unsigned int r, unsigned int c)
{
unsigned int row, col;
printf("\n\n");
for(row = 0; row < r; row++)
{
for(col = 0; col < c; col++)
{
printf("%d\t", *(p + row * c + col)); // what is this??? couldnt understand this logic?
}
printf("\n");
}
printf("\n\n");
}
void rotate(unsigned int *pS, unsigned int *pD, unsigned int row, unsigned int col)
{
unsigned int r, c;
for(r = 0; r < row; r++)
{
for(c = 0; c < col; c++)
{
*(pD + c * row + (row - r - 1)) = *(pS + r * col + c); // not understanding this logic as well.
}
}
}
could any one please explain more about this logic. I'm not able to resolve few places in the above problems that i have mentioned in the code itself.
Also please let me know the time and space complexity detailed..Thanks in advance.
The code relies on a two-dimensional array being contiguously stored and treats it as one-dimensional.
The line
*(pD + c * row + (row - r - 1)) = *(pS + r * col + c);
is equivalent to
pD[c][row-r-1] = pS[r][c];
This question already has answers here:
String not outputting the characters i type in
(3 answers)
Closed 9 years ago.
this program is supposed to output to the console a string of letters i type in, for example if i type in "im hungry" then its supposed to output im hungry to the console in a matrix for, if something i type in is too long then it carries over to the next line of the matrix
heres the code i have so far:
#include <iostream>
#include <string>
using namespace std;
#define N 6
//
// fill:
//
void fill(string s, int M[][N], int ROWS, int COLS)
{
int i, r, c;
s= "x";
for (i=0, r=0; r < ROWS; r++)
{
for (c=0; c < COLS; c++)
{
M[r][c] = s[i]; // store ith character into matrix:
i++; // next character:
if (i == s.length()) // start-over if that was last char:
i = 0;
}
}
}
void print(int M[][N], int ROWS, int COLS)
{
string s;
s= "x";
int r, c;
for(r=0; r< ROWS; r++)
{
for(c=0; c < COLS; c++)
{
cout<<(char)M[r][c];
}
cout <<endl;
}
}
//
// main:
//
int main()
{
string s;
getline(cin,s);
int M[N][N];
int M2[N][N];
int row, col, ROWS, COLS;
fill(s, M, 1, 1);
print(M, ROWS, COLS);
return 0;
}
instead of outputting what I type in, it keeps outputting a matrix of random characters (same no matter what I type in) any suggestions on how I can fix this?
If you don't really need of the matrix you can simply:
void print(string s, int limit, char endl = '\n') {
if (limit == 0) return;
if (s.length > limit) {
for (int i = 0; i < s.length; i++) {
std::cout << s[i];
if (i % limit == 0)
std::cout << endl;
} else {
std::cout << s;
}
}
which will take the string and print it, in case it below the limit, or split it into different lines with the endl char.
I'm writing a 2d array program and i'm having issues getting it to print out, I'm not sure if i'm doing my 2d array passing correct now as its crashing instead of running at all. Any advice would be helpful
void initialize(int* one, int** two);
void replace(int* arr,int rows, int cols,int value);
void fill(int* arr, int rows, int cols);
void print(int** arr, int rows, int cols);
ofstream outfile;
ifstream infile;
int arrayOne[100][100];
int arrayTwo[100][100];
int main(){
int rows,cols=0;
cout << "Please input how many rows you would like in the array: ";
cin >> rows;
cout << "Please input how many columns you would like in the array: ";
cin >> cols;
fill(arrayOne[100][100],rows,cols);
//print(arrayOne[100][100],rows,cols);
system("pause");
return 0;
}
void initialize(int* one, int* two){
for(int i=0;i<100;i++){
for(int j=0;j<100;j++){
arrayOne[i][j]=0;
arrayTwo[i][j]=0;
}
}
}
void replace(int* arr,int rows,int cols,int value){
arr[rows][cols]=value;
}
void fill(int* arr, int rows, int cols){
int i=0;
for(int r=0; r < rows; r++){
for(int c=0; c < cols; c++){
replace(arr,r,c,i++);
}
}
}
void print(int** arr, int r, int c){
for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
cout << arr[i][j] << " ";
}
cout << endl;
}
}
If you read the error message, it plainly states your problem. That being said, it does not plainly state how to fix it. You're going down a rough path with fixed arrays...
/* arrayOne[100][100] This is an 'int' at the 101st row and 101st column.
* It isn't an address to anywhere in the array, in fact it is just beyond
* the end of your array.
*
* Regardless, even if it were a pointer, it would point to a location in memory
* that is not yours. We count starting with 0 in C/C++. So if you'd like to
* reference the 'whole' array just pass it bare:
*/
fill (arrayOne, rows, cols);
/* Of course this means that you need to fix the definition of 'fill'
* and 'replace'.
*/
void replace(int arr[100][100],int rows,int cols,int value){
arr[rows][cols]=value;
}
/* As you can see this isn't going to be friendly */
void fill(int arr[100][100], int rows, int cols){
int i=0;
for(int r=0; r < rows; r++){
for(int c=0; c < cols; c++){
replace(arr,r,c,i++);
}
}
}
You have other issues, but those can be asked in other questions when you run into them.
Change all int* arr and int** arr to int arr[100][] or to arr[][100]. I don't remember which one. but, it's one of them for sure.