I have the vector of vectors a, and I want to print out the contents of the first vector.
a = [ 1 5 3 ; 11 17 14 ]
knowing it's size/dimension, I could do that using the following:
for ( int k = 0; k <= a[0].size(); k++)
cout << a[0][k] << endl;
and the output, as I wanted it, is:
1 5 3
However, in another example where the vector changes its size during execution, I tried to use the following:
for ( auto k : a[0])
cout << a[0][k] << endl;
but the output is as the following:
5 0
How can I get the elements of the first vector using the auto keyword without knowing the dimensions of the vector?
When you use the auto keyword, k is being assigned to the value of each element in the vector, not the index of the element. Therefore, if you wanted to print out the contents of the array, print out just k:
for ( auto k : a[0] )
cout << k << endl;
EDIT: For clarity, the reason it works in the first for loop is because you are setting k to be every integer from 0 to the number of elements in a[0], and therefore the index of each element, rather than the value.
Related
so the purpose of the code is to shuffle a vector, then print a random number from the vector, and then delete that same number so it won't repeat.
what I did is:
there is an initialized vector called songs, first I used random_device to make a random func.
I initialized an iterator to the back of the vector.
I shuffled the vector
Print
remove the last element that I printed (after shuffling).
The problem is when I do songs.pop_back(); it removes the last element from the original vector and not from the shuffled one, so it makes numbers coming back that way.
and I get an error.
code:
int getSong(int n, vector<int> songs, vector<int>::iterator iter) {
random_device random;
shuffle(songs.begin(), songs.end(), random);
for (int j = 0; j < n; j++) {
cout << songs[j] << " ";
}
iter = songs.end() -1 ;
int song = *iter;
iter--;
return song;
}
int main() {
vector<int> songs = { 1,2,3,4,5,6,7,8,9 };
int n = songs.size();
vector<int>::iterator iter;
for (int i = 0; i < n; n--) {
int l = getSong(n, songs, iter);
cout << "The song number is:" << l << "\n" << endl;
songs.pop_back();
}
return 0;
}
the output is:
Thank you!
I would write something like this instead. It is sort of wasteful but I wanted to keep your original program structure.
First, you need to pass a reference to the vector with std::vector<int>& if you want to modify its contents in the function. If your intent was to keep the original vector then yes, you just pass by value. But as you need to remove the last value in the main function, I figured this was the only way.
Second the iterator is not necessary. You can just remove that.
Last, you dont need to pass the size as the vector itself contains the size.
The use of random_device is somewhat awkward as random_shuffle would be cleaner - but again I tried to change your code minimally.
int getSong( vector<int>& songs ) {
random_device random;
shuffle(songs.begin(), songs.end(), random);
for ( int song : songs ) {
cout << song << " ";
}
cout << endl;
return *songs.rbegin();
}
In regards to the main loop, checking for empty() is cleaner than a loop through the size - it's more immune to edge cases.
int main() {
vector<int> songs = { 1,2,3,4,5,6,7,8,9 };
while( !songs.empty() ) {
int l = getSong(songs);
cout << "The song number is:" << l << "\n" << endl;
songs.pop_back();
}
return 0;
}
https://godbolt.org/z/oWbxvMjE3
Produces:
Program stdout
5 3 6 8 1 9 7 4 2
The song number is:2
7 3 5 8 6 9 1 4
The song number is:4
6 1 9 8 3 5 7
The song number is:7
3 6 1 5 8 9
The song number is:9
6 8 5 3 1
The song number is:1
8 5 3 6
The song number is:6
3 5 8
The song number is:8
3 5
The song number is:5
3
The song number is:3
I am learning C++ and I am working on a project where I have a two dimensional vector[5][1]
vector[0][0] = 1
vector[1][0] = 2
vector[2][0] = 3
vector[3][0] = 4
vector[4][0] = 5
I then add a count to the second dimension
example:
vector[0][1] = 17
vector[1][1] = 24
vector[2][1] = 91
vector[3][1] = 2
vector[4][1] = 50
I want to cout the first dimension the second dimension number of times
So if I would cout vector[0][0] 17 times vector[1][0] 24 times etc.
I just started learning 3 weeks ago and the prof is incredibly unresponsive, so I would appreciate any and all feedback!
I have a two dimensional vector[5][1]
I assume your declaration is int vector[5][1] (but you should clarify in your question).
This means the valid index for the first dimension is from 0 to 4 inclusive. And for the second dimension the only valid index is 0.
You go out of bounds when you do vector[0][1] etc and as such you have Undefined Behavior. If you wish to store two elements in the second dimension then you need to have int vector[5][2].
Going back to your question. Assuming you fixed the declaration.
I want to cout the first dimension the second dimension number of times
Think how you would do that for a row
cout the first dimension
ok, so
std::cout << vector[row_idx][0];
... the second dimension number of times
So we repeat the above vector[row_idx][1] times. Easy peasy:
for (int repeat = 0; repeat < vector[row_idx][1]; ++repeat)
{
std::cout << vector[row_idx][0];
}
And now do this for each row:
std::size_t num_rows = 5;
for (std::size_t row_idx = 0; row_idx < num_rows; ++row_idx)
{
for (int repeat = 0; repeat < vector[row_idx][1]; ++repeat)
{
std::cout << vector[row_idx][0];
}
std::cout << endl;
}
I am passing a small sparse matrix(for testing) to a C++ function from R. The matrix belongs to the class dgCMatrix as shown below:
5 x 5 sparse Matrix of class "dgCMatrix"
[1,] . . . . .
[2,] 1 1 . . .
[3,] . . . . .
[4,] . . 1 . .
[5,] . 1 . . .
I am iterating this matrix as mentioned in the documentation here.
My function prints out the value of the iterator and the row index, column index.
The c++ function is defined below:
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::MappedSparseMatrix;
using Eigen::SparseMatrix;
using Eigen::VectorXi;
using Eigen::Map;
using namespace Rcpp;
using namespace std;
// [[Rcpp::export]]
void createRec(RObject sparse_mat, IntegerVector sparse_vec) {
const MappedSparseMatrix<int> spmat(as<MappedSparseMatrix<int> >(sparse_mat));
long int nrow = spmat.rows();
long int ncol = spmat.cols();
NumericVector sim(nrow);
for(int k=0;k<spmat.outerSize();k++){
for(SparseMatrix<int,Eigen::ColMajor>::InnerIterator it(spmat,k);it;++it){
cout<<"k="<<k<<endl;
cout<<"value="<<it.value()<<endl;
cout<<"it.row="<<it.row()<<endl;
cout<<"it.col="<<it.col()<<endl;
cout<<"index="<<it.index()<<endl;
}
}
}
For the matrix given above the following results are printed:
k=0
value=156148016
it.row=66211520
it.col=0
index=66211520
k=1
value=0
it.row=0
it.col=1
index=0
k=1
value=1
it.row=4
it.col=1
index=4
k=2
value=1
it.row=3
it.col=2
index=3
1.) Any explanation for the values corresponding to k=0? Could these be due to passing the matrix in a wrong manner?
2.) k is iterating over outerSize, which is equal to 5, why is it not iterating for k=3,4? Considering it is a sparseMatrix, this behaviour was expected from the iterator.
Whenever you see very large numbers like 156148016 or 66211520, chances are you either have an undefined behavior (UB) or a value was not appropriately initialized. In this case, it is the later. Specifically, the dgCMatrix class' underlying type is that of a double not an int.
The dgCMatrix class is a class of sparse numeric matrices in the compressed, sparse, column-oriented format. In this implementation the non-zero elements in the columns are sorted into increasing row order. dgCMatrix is the "standard" class for sparse numeric matrices in the Matrix package.
Thus, when you are trying to create a map to the memory location of the underlying RObject there is an additional step required to recreate the object anew in the requested different type. After adding the const term, I'm willing to bet the entries are then as expected since the compiler likely keeps in memory the intermediary object.
So, the changing following:
MappedSparseMatrix<int> spmat(as<MappedSparseMatrix<int> >(sparse_mat));
to:
MappedSparseMatrix<double> spmat(as<MappedSparseMatrix<double> >(sparse_mat));
should be sufficient.
The linked example uses a SparseMatrix matrix, here you are using a MappedSparseMatrix but do not setup an appropriate MappedSparseMatrix::InnerIterator for the second loop.
Thus, we have:
for(SparseMatrix<int,Eigen::ColMajor>::InnerIterator it(spmat,k);it;++it){
Going to:
for(MappedSparseMatrix<double>::InnerIterator it(spmat,k);it;++it){
Also, note that the use of Eigen::ColMajor within the SparseMatrix<int, Eigen::ColMajor>::InnerIterator is not needed as that is the default initialization. So, I've removed this statement.
Regarding your second question, on the iteration of k.
k does iterate over both k=3,4 but there are no elements within those columns. Therefore, the inner loop where k is output does not get called.
This is easy to see if we put two k declarative output statements in the outer and inner loops.
e.g.
for(int k = 0; k < spmat.outerSize(); ++k) {
Rcpp::Rcout << "Overall k = " << k << std::endl << std::endl;
for(MappedSparseMatrix<double>::InnerIterator it(spmat,k); it; ++it) {
Rcpp::Rcout << "Inner k = " << k << std::endl;
}
}
Avoid using namespace std;
Adding in namespace sometimes has unintended consequences, especially one as large as std.
Taking the points from above and slightly simplifying your example, we have the following bare bones working example:
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::MappedSparseMatrix;
using Eigen::SparseMatrix;
using Eigen::VectorXi;
using Eigen::Map;
// [[Rcpp::export]]
void createRec(Rcpp::RObject sparse_mat) {
MappedSparseMatrix<double> spmat(Rcpp::as<MappedSparseMatrix<double> >(sparse_mat));
long int nrow = spmat.rows();
Rcpp::NumericVector sim(nrow);
for(int k = 0; k < spmat.outerSize(); ++k) {
Rcpp::Rcout << "Overall k = " << k << std::endl << std::endl;
for(MappedSparseMatrix<double>::InnerIterator it(spmat,k); it; ++it) {
Rcpp::Rcout << "Inner k = " << k << std::endl
<< "value = " << it.value() << std::endl
<< "it.row = " << it.row() << std::endl
<< "it.col = " << it.col() << std::endl
<< "index = " << it.index() << std::endl;
}
}
}
/***R
# Setup values
id_row = c(2, 2, 4, 5)
id_col = c(1, 2, 3, 2)
vals = rep(1,4)
# Make the matrix
x = sparseMatrix(id_row, id_col, x = vals, dims = c(5, 5))
# Test the function
createRec(x)
*/
Output:
Overall k = 0
Inner k = 0
value = 1
it.row = 1
it.col = 0
index = 1
Overall k = 1
Inner k = 1
value = 1
it.row = 1
it.col = 1
index = 1
Inner k = 1
value = 1
it.row = 4
it.col = 1
index = 4
Overall k = 2
Inner k = 2
value = 1
it.row = 3
it.col = 2
index = 3
Overall k = 3
Overall k = 4
For more details on sparse matrices in Eigen and Rcpp, you may wish to read the Rcpp Gallery: Using iterators for sparse vectors and matrices by Soren Hojsgaard and Doug Bates.
I'm new to C++ and is trying to solve the beginner's problem of finding all prime numbers between 0 - nth number. I saw this code online and it works perfectly.
However, my question is what is the use of '+ 1' within the statement 'bool prime[n + 1];'? I have deleted it from the code and everything seems to work just fine. Is it necessary or is it redundant?
void SieveOfEratosthenes(int n) {
bool prime[n + 1];
memset(prime, true, sizeof (prime));
for (int p = 2; p * p <= n; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * 2; i <= n; i += p)
prime[i] = false;
}
}
// Print all prime numbers
for (int p = 2; p <= n; p++)
if (prime[p])
cout << p << endl;
}
int main() {
int n = 1000;
cout << "Following are the prime numbers smaller "
<< " than or equal to " << n << endl;
SieveOfEratosthenes(n);
return 0;
}
In C++ an array of size N have index start from 0 to N-1. so for your problem, for N index assign N+1 size array. so that define the primality to N number.
In C++ (and many other languages) an array of size n has an index for 0 to (n - 1). In this case, you will need to check each number, up to and including n. You therefore need a spot in the array for n, at index prime[n]. This index will only exist if you oversize the array by 1. Otherwise, the array will stop at prime[n - 1].
The reason this works even if you take out the - 1 is that C++ is not fussy about array bounds - once you have an array you can legally read or write at any index, whether or not that index is safe. Notice I said legally, not safely - this is potentially very dangerous behaviour.
As part of a program I'm trying to print the contents of an array in reverse order. It is working fine except for one value and I can't figure out why.
I haven't gotten onto functions yet so I haven't used them in my code here is the snippet
case 7:
for (int i = 11; i != -1; i--)// The variable i is initialised to 11. While i is not equal to -1 decrement i by 1.
{
infile >> list[i];//Read in values for array from data.dat
cout << list[i] << " ";// Outputting the array in reverse order.
outfile << "The array in reverse order is: " << list[i] << " " << endl;// Outputting the array in reverse order to file.
}
cout << endl;
break;
The array is filled with the following numbers
8 16 12 6 16 4 8 10 2 16 12 6
The expected output is:
6 12 16 2 10 8 4 16 6 12 16 8
The output I'm getting is:
6 12 16 2 10 8 4 16 6 12 6 8
Any help appreciated
The right way to reverse an iterator is to shift it down by one.
Forward:
T a[N];
for (std::size_t i = 0; i != N; ++i)
{
consume(a[i]);
}
Backward:
T a[N];
for (std::size_t i = 0; i != N; ++i)
{
std::size_t const ri = N - i - 1;
// ^^^
consume(a[ri]);
}
You can write a loop where you actually decrement the loop variable directly, but it's awkward since you either have to use signed integers or otherwise do an additional - 1 when using the index, and it's altogether unnatural, hard to read and easy to get wrong. I'd much rather recommend always using the forward-moving loop as shown here and compute the reverse iterator separately.
Incidentally, this logic is already encapsulated in the iterator wrapper std::reverse_iterator, which is build from a normal, bidirectional moving iterator but decrements by one when being dereferenced. You can either reverse a sequence yourself by using make_reverse_iterator, or by using the free rbegin/rend functions:
#include <iterator>
T a[N];
for (auto rit = std::crbegin(a); rit != std::crend(a); ++rit)
{
consume(*rit);
}