I am relatively new to C++ programming and I wanted to learn more about language by programming matrices. I have this code that works, but I can't figure out how to create code that would work for any amount of columns and rows. I have trouble passing matrices to functions, which have rows and columns determined by user input.
This is what I have:
#include <iostream>
using namespace std;
template <int rows, int cols>
void display(int (&array)[rows][cols]) {
int i, j;
cout<<"\n";
for(i = 0; i<rows; i++) {
for(j = 0; j<cols; j++) {
cout<<" ";
cout<<array[i][j];
}
cout<<"\n";
}
}
int main() {
int M1[3][3];
cout<<"Enter your matrix elements: \n";
int i, j;
for(i = 0; i<3; i++) {
for(j = 0; j<3; j++) {
cout<<"a["<<i<<"]["<<j<<"]: ";
cin>>M1[i][j];
}
}
display(M1);
return 0;
}
Is performing such task possible without complicating the code too much?
Many remarks and comments are okay, but I think that the best strategy is to use a single vector for storage and a vector for the shape. Learn on pythons numpy to understand the concept or search for ndarray, which is how many different platforms name this concept (n dimensional array). A class bundling the data vector, the shape vector and convenient operators and member functions is then the way to go.
The classical answer would have required you to perform dynamic memory allocations for you array. This is a bit overwhelming especially if you are a newbie. (And to the best of my knowledge this is still way to do it in C)
However the recommend way to do something like that in modern C++ is to use the Standard Template Library.
/*
... Stuff where you get input from the user, specifically the num of rows and cols
... Say these vals were stored in 2 ints num_rows and num_cols
*/
std::vector<std::vector<int> > mat(num_rows);
for (int i = 0; i < num_rows; i++) {
mat[i].resize(num_cols); // this will allow you to now just use [][] to access stuff
}
Please see the first comment below, it has a nice way to avoid the loop to set up the vector and takes care of it at initialization time
Related
I'm new to programming and was finding transpose of a matrix.
However, I want the input of the matrix from the user and by writing the following code, the complier doesn't take any input values and immediately stops.
I looked into previous questions posted here about the same but found non useful.
#include<iostream>
using namespace std;
int main()
{
int rows,val;
int num[rows][rows];
cin>> rows;
for(int i=1; i<= rows; i++)
{
for(int j = 1; j <= rows; j++)
{
cin>> val;
arr[i][j]= val;
}
cout<<endl;
}
You can't use variables in array length if they aren't defined as one of the comments mentioned.
arr[i][j] inside your nested for loop isn't declared so that would also give an error, I guess you wanted to use num array which you declared.
The rest is all looking good
In C++ , I Made A Code That has A 2D Vector in it and Users are Required to give The inputs In 2D vector . I find It difficult To find The no. of rows in 2 vector with the help of size function.
#include <bits/stdc++.h>
#include <vector>
using namespace std;
int diagonalDifference(vector<vector<int>> arr)
{
int d = arr[0].size();
cout << d;
return 0;
}
int main()
{
int size;
cin >> size;
vector<vector<int>> d;
for (int i = 0; i < size; i++)
{
d[i].resize(size);
for (int j = 0; j < size; j++)
{
cin >> d[i][j];
}
}
cout << diagonalDifference(d);
}
The Output Should BE No. Rows , But it is coming NULL
Here
vector<vector<int>> d;
for (int i = 0; i < size; i++)
{
d[i].resize(size);
//...
d is a vector of size 0 and accessing d[i] is out of bounds. You seem to be aware that you first have to resize the inner vectors, but you missed to do the same for the outer one. I dont really understand how your code can run as far as printing anything for arr[0].size(); without segfaulting. Anyhow, the problem is that there is no element at arr[0].
But first, Look at your function argument -> is a copy of your vector ,use (vector<> & my vec) to avoid the copying mechanism of vector class (copy constructor for instance) cause if you put there your vector as a parameter and u will make some changes inside the function brackets you will not see any results ( if you dont wanna change your primary vector from function main, keep it without changes).
Secondly, look at code snippet pasted below.
std::vector<std::vector<typename>> my_vector{};
my_vector.resize(width);
for (size_t i = 0; i < my_vector.size(); ++i)
{
my_vector[i].resize(height);
}
It gives you two dimensional vector
Operator[] for vector is overloaded and you have to use my_vector[0].size() just
my_vector[1].size() and so on ! I recommend for that displaying the size by kind of loops given in c++ standards
Regards!
iam trying to write a function that shifts rows in c++
for example
1 2 3
4 5 6
7 8 9
i want to shift it by one so the result is
7 8 9
1 2 3
4 5 6
the parameters is
void Matrix:: rowShift(const int shiftSize){}
here is the class
class Matrix {
private:
std::string type;
int row, col;
double **array;
void rowShift(const int shiftSize);
here is the constructor
Matrix::Matrix(int rows, int cols, std::string matType) {
type = matType;
row = rows;
col = cols;
array= new double*[row];
for (int i = 0; i < row; ++i)
array[i] = new double[col];
for (int i = 0; i < rows; i++)
for (int j = 0; j<cols; j++)
array[i][j] = 0;
}
any ideas iam new to see and i have a problem iam not used to the syntax either
I am new to C++ and I am not used to the syntax either
First things first, if you are new to the language you should take some time to read up on the basics before you just start writing code. There are many great books to get you started. I would recommend something like this introduction to programming in C++ written by the creator of the language.
Programming: Principles and Practice Using C++ (Bjarne Stroustrup)
I am trying to write a function that shifts rows in C++
So you have a two dimensional array (matrix) that you want to shift all rows down, and the old bottom row becomes the new top row. This seems like it might be your homework assignment loay. Is it your homework? If it is, please tag it as such in the future to be honest with yourself and others. I want you to stop reading my answer to your question now, go get that book and read it cover to cover. Once do that come back and check my answer.
Now that you're familiar with C++ I'll also assume you are familiar with the the standard template library and container objects such as std::vector.
here is the constructor
Now that you're familiar with C++, you know that you can use member initializer lists for your constructor arguments. This means you don't have to initialize them in the body of the constructor! I'm going to leave out your std::string matType variable because it's not used anywhere in the code you provided. I recommend using a nested std::vector to hold your matrix data as opposed to a C style array. The std::vector class will do all your memory management for you (new double[col] will not be necessary). Here we have defined the class private member variable mMatrix to be a std::vector of rows and columns std::vector< std::vector<double> > mMatrix;
Matrix( const size_t rows,
const size_t cols ) :
mRows(rows),
mCols(cols),
mMatrix(rows, std::vector<double>(cols)) {
init();
}
The Matrix::init() function will populate your matrix with default values incrementing from 1 to n. We do this using the concepts you read up on like std::iterator.
void init()
{
std::vector< std::vector<double> >::iterator row;
std::vector<double>::iterator col;
double seedVal(1.0);
for (row = mMatrix.begin(); row != mMatrix.end(); ++row)
{
for (col = row->begin(); col != row->end(); ++col)
{
*col = seedVal;
seedVal++;
}
}
}
Now I'm going to assume that you'll want to print the values of your matrix to verify that the shift down operation has worked. You can print the matrix using nested for loops very similar to the way we initialized the values earlier. This time we can use ::const_iterator since when we print, we are making a guarantee that we are not modifying the contents. We also use formatting flags from #include <iomanip> like std::setfill(' ') and std::setw(6) to get the spacing and formatting to look nice.
void print()
{
std::vector< std::vector<double> >::const_iterator row;
std::vector<double>::const_iterator col;
for (row = mMatrix.begin(); row != mMatrix.end(); ++row)
{
for (col = row->begin(); col != row->end(); ++col)
{
std::cout << std::setfill(' ') << std::setw(6) << *col;
}
std::cout << std::endl;
}
}
Now let's talk about the real reason you're here. The method to down shift the entire matrix (which I think should be a public method of the Matrix class so that it can be accessed by anyone). First, whenever you shift the contents of an array (vector) you must loop in the opposite direction of the shifting. In our case, we should invert the direction of our outer loop over each row. We also do NOT want to overwrite the contents of our rows without saving what was there before. We can accomplish this with a temporary variable that will, you guessed it, temporarily hold the old value while we shift the new one. Here is the method that will down shift all elements of the matrix, as long as we have at least one row to work with.
void shiftDown()
{
if (mRows > 0)
{
for (size_t i = mRows - 1; i-- > 0; )
{
for (size_t j = 0; j < mCols; ++j)
{
double temp = mMatrix[i+1][j];
mMatrix[i+1][j] = mMatrix[i][j];
mMatrix[i][j] = temp;
}
}
}
}
There now you have a self contained Matrix class with a method that will shift each row down and wrap around the top row. For bonus points, you can play with variations of this nested loop to implement methods like shiftUp(), shiftLeft(), and shiftRight().
I have a struct:
struct xyz{
int x,y,z;
};
and I initialize a struct xyz type vector:
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
for (int k = 0; k < N; k++)
{
v.x=i;
v.y=j;
v.z=k;
vect.push_back(v);
}
}
}
then I want to transform that vector to array because array is 2 time faster than vector to manipulate, so I do
xyz arr[vect.size()];
std::copy(vect.begin(), vect.end(), arr);
when I run this program it shows me segmentation fault which I think is because vect.size() is too large.
So I am wondering is there any way to convert that large size vector to array without that problem.
I appreciate for any help
My overly pedantic comment got too big, so instead I'll try to make this a somewhat roundabout answer. The short answer is probably just to stick with vector but make sure to use reserve; oh, and benchmark.
You didn't say what compiler or C++ version you're using, so I'll just go with my current gcc.godbolt.org default of gcc 4.9.2, C++14. I'm also assuming that you really want this as a 1-dimension array, rather than the more natural (for your example) 3.
If you know N at compile time, you could do something like this (assuming I got the array offset calculation correct):
#include <array>
...
std::array<xyz, N*N*N> xyzs;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
xyzs[i*N*N+j*N+k] = {i, j, k};
}
}
}
The biggest downsides, IMO:
error-prone offset calculation
depending on N, where the code is run, etc, this can blow the stack
On the compilers I tried this on, the optimizers seem to understand that we're moving through the array in contiguous order, and the generated machine code is more sensible, but it could also be written like so, if you prefer:
#include <array>
...
std::array<xyz, N*N*N> xyzs;
auto p = xyzs.data();
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
for (int k = 0; k < N; ++k) {
(*p++) = {i, j, k};
}
}
}
Of course, if you actually know N at compile time, and it won't blow the stack, you might consider a 3-dimensional array xyz xyzs[N][N][N]; since this might be more natural for the way these things are being ultimately being used.
As pointed out in comments, variable length arrays aren't legal C++, but they are legal in C99; if you don't know N at compile time you should be allocating off the heap.
A vector and an array will wind up being identical in terms memory layout; they differ in that vector allocates memory from the heap, and the array (as you are writing it) would be on the stack. The only recommendation I'd make is to call reserve before entering your loop:
vect.reserve(N*N*N);
This means you'll only be doing a single memory allocation up front, rather than grow-and-copy mechanism that you'll get from a default constructed vector.
Assuming xyz is as simple as you declare here, you could also do something like the second example above:
std::vector<xyz> xyzs{N*N*N};
auto p = xyzs.data();
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
for (int k = 0; k < N; ++k) {
(*p++) = {i, j, k};
}
}
}
You lose the safety of push_back, and it is less efficient if xyz default constructor needs to do anything (like if xyz members were changed to have default values).
Having said all that, you really should benchmark. But then, you should probably be benchmarking the code that ultimately uses this array, rather than the code to construct it; I'd have other concerns if construction was dominating usage.
I have following code to accomplish prefix sum task:
#include <iostream>
#include<math.h>
using namespace std;
int Log(int n){
int count=1;
while (n!=0){
n>>=1;
count++;
}
return count;
}
int main(){
int x[16]={39,21,20,50,13,18,2,33,49,39,47,15,30,47,24,1};
int n=sizeof(x)/sizeof(int );
for (int i=0;i<=(Log(n)-1);i++){
for (int j=0;j<=n-1;j++){
if (j>=(std::powf(2,i))){
int t=powf(2,i);
x[j]=x[j]+x[j-t];
}
}
}
for (int i=0;i<n;i++)
cout<<x[i]<< " ";
return 0;
}
From this wikipedia page
but i have got wrong result what is wrong? please help
I’m not sure what your code is supposed to do but implementing a prefix sum is actually pretty easy. For example, this calculates the (exclusive) prefix sum of an iterator range using an arbitrary operation:
template <typename It, typename F, typename T>
inline void prescan(It front, It back, F op, T const& id) {
if (front == back) return;
typename iterator_traits<It>::value_type accu = *front;
*front++ = id;
for (; front != back; ++front) {
swap(*front, accu);
accu = op(accu, *front);
}
}
This follows the interface style of the C++ standard library algorithms.
To use it from your code, you could write the following:
prescan(x, x + n, std::plus<int>());
Are you trying to implement a parallel prefix sum? This only makes sense when you actually parallelize your code. As it stands, your code is executed sequentially and doesn’t gain anything from the more complex divide and conquer logic that you seem to employ.
Furthermore, there are indeed errors in your code. The most important one:
for(int i=0;i<=(Log(n)-1);i++)
Here, you’re iterating until floor(log(n)) - 1. But the pseudo-code states that you in fact need to iterate until ceil(log(n)) - 1.
Furthermore, consider this:
for (int j=0;j<=n-1;j++)
This isn’t very usual. Normally, you’d write such code as follows:
for (int j = 0; j < n; ++j)
Notice that I used < instead of <= and adjusted the bounds from j - 1 to j. The same would hold for the outer loop, so you’d get:
for (int i = 0; i < std::log(n); ++i)
Finally, instead of std::powf, you can use the fact that pow(2, x) is the same as 1 << x (i.e. taking advantage of the fact that operations base 2 are efficiently implemented as bit operations). This means that you can simply write:
if (j >= 1 << i)
x[j] += x[j - (1 << i)];
I think that std::partial_sum does what you want
http://www.sgi.com/tech/stl/partial_sum.html
The quickest way to get your algorithm working: Drop the outer for(i...) loop, instead setting i to 0, and use only the inner for (j...) loop.
int main(){
...
int i=0;
for (int j=0;j<=n-1;j++){
if (j>=(powf(2,i))){
int t=powf(2,i);
x[j]=x[j]+x[j-t];
}
}
...
}
Or equivalently:
for (int j=0; j<=n-1; j++) {
if (j>=1)
x[j] = x[j] + x[j-1];
}
...which is the intuitive way to do a prefix sum, and also probably the fastest non-parallel algorithm.
Wikipedia's algorithm is designed to be run in parallel, such that all of the additions are completely independent of each other. It reads all the values in, adds to them, then writes them back into the array, all in parallel. In your version, when you execute x[j]=x[j]+x[j-t], you're using the x[j-t] that you just added to, t iterations ago.
If you really want to reproduce Wikipedia's algorithm, here's one way, but be warned it will be much slower than the intuitive way above, unless you are using a parallelizing compiler and a computer with a whole bunch of processors.
int main() {
int x[16]={39,21,20,50,13,18,2,33,49,39,47,15,30,47,24,1};
int y[16];
int n=sizeof(x)/sizeof(int);
for (int i=0;i<=(Log(n)-1);i++){
for (int j=0;j<=n-1;j++){
y[j] = x[j];
if (j>=(powf(2,i))){
int t=powf(2,i);
y[j] += x[j-t];
}
}
for (int j=0;j<=n-1;j++){
x[j] = y[j];
}
}
for (int i=0;i<n;i++)
cout<<x[i]<< " ";
cout<<endl;
}
Side notes: You can use 1<<i instead of powf(2,i), for speed. And as ergosys mentioned, your Log() function needs work; the values it returns are too high, which won't affect the partial sum's result in this case, but will make it take longer.