I am making some testing of vectors arrays and I don't know how to print it.
Here is my code:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include "vector"
#include <windows.h>
using namespace std;
vector<vector<int>> generateArrays(){
vector<vector<int>> cisla;
for(unsigned int i=1; i < 11; i++){
vector<int> pole;
vector<int> pole2;
for(unsigned int j=0; j < i*5; j++){
int a = rand();
pole.push_back(a);
pole2.push_back(a);
}
cisla.push_back(pole);
cisla.push_back(pole2);
}
return cisla;
}
vector<vector<int>> arrays = generateArrays();
void Print (const vector<int>& arrays){
// function for prinitng arrays
}
int main(){
Print(arrays);
system("pause");
}
What I need is some function to write down all numbers in vector arrays. I tried to Google it but none of the code work for me.
// requires #include <algorithm> for std::copy
// requires #include <iterator> for std::ostream_iterator
void Print(const vector<vector<int>>& arrays, std::ostream& out = std::cout)
{
for(const auto& array:arrays) {
std::copy(array.begin(), array.end(), std::ostream_iterator<int>(out, " "));
out << std::endl;
}
}
You can use vector::iterator, for instance:
vector<vector<int>>::iterator i = arrays.begin();
vector<int>::iterator j = *i.begin();
for(;i != arrays.end(); ++i) {
for(;j != *i.end(); ++j) {
std::cout << *j << " ";
}
std::cout << "\n";
}
void Print (const vector<int>& arrays){
for (std::vector<int>::iterator it = arrays.begin() ;
it != arrays.end();
++it)
std::cout << ' ' << *it;
}
#include <algorithm>
vector<vector<int>>::iterator it = arrays.begin();
while ( !(it == arrays.end()) {
std::copy( (*it).begin(), (*it).end(),
std::ostream_iterator<int>( std::cout, ","));
++it;
}
As you have std::vector<std::vector<int>> then the function could look as
void Print( const std::vector<std::vector<int>> &arrays )
{
for ( const std::vector<int> &v : arrays )
{
for ( int x : v ) std::cout << x << ' '; // you can include std::setw here
std::cout << std::endl;
}
}
Or if you need to output only std::vector<int> then it will look as
void Print( const std::vector<int> &arrays )
{
for ( int x : arrays ) std::cout << x << ' '; // you can include std::setw here
}
If your compiler does not support the range based for statement then you can use for example standard algorithm std::copy.
void Print( const std::vector<int> &arrays )
{
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, " " ) );
}
Or you can use an ordinary loop
void Print( const std::vector<int> &arrays )
{
for ( std::vector<int>::size_type i = 0; i < arrays.size(); i++ )
{
std::cout << arrays[i] << ' '; // you can include std::setw here
}
}
Or with iterators
void Print( const std::vector<int> &arrays )
{
for ( auto it = arrays.begin(); it != arrays.end(); ++it )
{
std::cout << *it << ' '; // you can include std::setw here
}
}
What about this?
Create a stream output operator for vector of T like this:
template <typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> const & array)
bool seenFirst = false;
os << "[ ";
for (auto const & i : array)
{
if (!seenFirst)
{
seenFirst = true;
os << i;
}
else
{
os << ", " << i;
}
}
os << "]";
return os;
}
At the end you might use it for std::vector<int> as well as for std::vector< std::vector <int> > like this:
std::cout << arrays;
If you have Print prototype as shown
then,
void Print (const vector<int>& arrays){
for(auto x:arrays)
std::cout << x <<" ";
}
int main(){
for(const auto& array:arrays)
Print(array);
system("pause");
}
Otherwise you can combine both in one function like
void Print (const vector<vector<int>>& arrays){
for(const auto& array:arrays)
for(auto x:array)
std::cout << x <<" ";
}
In C++11``
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Related
I essentially want to group the elements of the multimap by key, and obtain the new data structure as a map.
the multimap:
std::multimap<std::string,std::vector<int>> multiMap;
VecA VecB
ABC 10 30
ABC 10 30
DEF 20 20
the output required:
std::map<std::string,std::vector<int>> map;
VecA VecB
ABC 20 60
DEF 20 20
The following code works for a std::multimap<std::string,int>
std::vector<std::string> a = {ABC,ABC,DEF,GHI};
std::vector<int> b = {10,20,30,40};
std::multimap<std::string,int> multiMap;
for (int i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,int >(a[i], b[i]));
}
std::map<std::string,int> map;
std::for_each
(
multiMap.begin(),
multiMap.end(),
[&map] (auto const & i)
{
map[i.first] += i.second;
}
);
I am unable to change the code in line 19 of the above block (i.e. in the lambda function) to extend in the case of std::multimap<std::string,std::vector<int>> to std::map<std::string,std::vector<int>>
If you want use Arithmetic operators
Use valarray
Demo: https://wandbox.org/permlink/SAnHNKNZ0UufqZsN
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <valarray>
#include <numeric>
int main()
{
using key_type = std::valarray<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
std::for_each( multiMap.begin(), multiMap.end(), [&map] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) += i.second;
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}
If you want use std::vector
Define your sum function.
Demo: https://wandbox.org/permlink/FteFkLfwQh0P4wzp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <numeric>
int main()
{
using key_type = std::vector<int>;
key_type b = {10,20,30,40};
auto containerToStr = [](const auto& cont)
{
return std::accumulate(std::begin(cont), std::end(cont), std::string{}, [](const auto& str, const auto& val){
return str + " " + std::to_string(val);
});
};
std::multimap<std::string,key_type> multiMap;
std::vector<std::string> a = {"ABC","ABC","DEF","GHI"};
for (size_t i = 0; i < a.size(); i++)
{
multiMap.insert(std::pair<std::string,key_type >(a[i], b));
}
std::cout << "Before sum" << std::endl;
for (const auto& p : multiMap)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
std::cout << std::endl;
std::map<std::string,key_type> map;
// Warning : naive function, to rework
auto your_sum = [](const auto& cont1, const auto& cont2)
{
key_type result;
const auto smaller = std::min(cont1.size(), cont2.size());
for ( size_t i = 0 ; i < smaller; i++)
{
result.push_back(cont1[i]+cont2[i]);
}
return result;
};
std::for_each( multiMap.begin(), multiMap.end(), [&map,&your_sum] (auto const & i)
{
// map[i.first] += i.second; // caution map[i.first] create an empty key_type
if ( map.count(i.first) > 0)
{
map.at(i.first) = your_sum(i.second, map.at(i.first));
}
else
{
map.insert({i.first, i.second});
}
}
);
std::cout << "After sum" << std::endl;
for (const auto& p : map)
std::cout << p.first << " " << containerToStr(p.second) << std::endl;
}
I am the beginner of C++, and any help will be very appreciated.
here is the code i can run successfully:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
main(){
bool findIn=false;
RowVectorXd A(10);
A<<false,true,false,true,true,false,false,false,true,true;
std::cout << A << std::endl;
for (int i=0;i<A.size();i++){
if(A(i)==findIn){
std::cout << i << std::endl;
}
}
system("pause");
}
the result is {0,2,5,6,7}, and I want to design a function, the code is as follows:
int seq(bool findIn, VectorXd &resdX){
VectorXd A;
for(int i=0;i<resdX.size();i++){
if(resdX(i)==findIn){
A =A+i;
}
}
return(A);
}
I want this function to return result like that {0,2,5,6,7}.But I don`t know how to set up a array to save the result or is there a function just like 'which' in R software to produce sequence above.
Sounds like you want a vector of integers:
#include <vector>
std::vector<int> seq(bool findIn, VectorXd &resdX)
{
std::vector<int> v;
for(int i=0;i<resdX.size();i++) {
if (resdX(i) == findIn) {
v.push_back(i);
}
}
return v;
}
You can then print its contents by iterating through it:
std::vector<int> result = seq(false, A);
for (int i : result) std::cout << i << '\n';
I did not understand what are you looking for.
If you want just to print a sequence of integers indexing findIn values you might code:
void seq(bool findIn, VectorXd &resdX) { // not int
std::cout << "{ ";
for(int i=0;i<resdX.size();i++) // go inside the array
if(resdX(i)==findIn) // if you find that resdX(i) value equals findIn value
std::cout << i << " "; // print i index
std::cout << "}" << std::endl; // at the end prints a new line
}
EDIT1:
Try to adapt the following snippet:
#include <list>
...
std::list<int> seq(bool findIn, VectorXd& resdX) {
std::list<int> l;
for(int i=0; i<resdX.size(); i++) {
if (resdX(i) == findIn) {
l.push_back(i);
}
}
return l;
}
void print_seq(std::list<int> list_) {
std::cout << "{ ";
std::list<int>::iterator it = list_.begin();
for (; it != list_.end(); ++it) {
std::cout << i << " ";
}
std::cout << " }\n";
}
I am having trouble with my void print function to print out this vector. I'm not quite sure what it is talking about with "std::allocator. I get these errors:
st1.cpp: In function ‘void Print(std::vector<int, std::allocator<int> >)’:
st1.cpp:51: error: declaration of ‘std::vector<int, std::allocator<int> > v’ shadows a parameter
Here is the file:
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
void Initialize();
void Print();
int main()
{
stack<string> s1, s2;
s1.push("b");
s2.push("a");
if (s1.top() == s2.top())
{
cout << "s1 == s2" << endl;
}
else if (s1.top() < s2.top())
{
cout << "s1 < s2" << endl;
}
else if (s2.top() < s1.top())
{
cout << "s2 < s1" << endl;
}
else
{
return 0;
}
vector<int> v;
Initialize();
Print();
}
void Initialize(vector<int> v)
{
int input;
cout << "Enter your numbers to be evaluated: " << endl;
while(input != -1){
cin >> input;
v.push_back(input);
//write_vector(v);
}
}
void Print (vector<int> v){
vector<int> v;
for (int i=0; i<v.size();i++){
cout << v[i] << endl;
}
}
I just want to print v out to the screen. Any help?
Your function declaration and definition are not consistent, you want to generate vector from Initialize, you can do:
void Initialize(vector<int>& v);
To print vector:
void Print(const vector<int>& v);
Now you call:
vector<int> v;
Initialize(v);
Print(v);
Don't forget to change function definition of Initialize, Print to match the new signature I provided above.
Also you are redefining a local variable v which shadows function parameter, you just need to comment out that line, also pass vector by const ref:
void Print (const vector<int>& v){
//vector<int> v;
for (int i=0; i<v.size();i++){
cout << v[i] << endl;
}
}
You have to pass by const reference and remove the extraneous vector.
void Print(const std::vector<int>& v){
for(unsigned i = 0; i< v.size(); ++i) {
std::cout << v[i] << std::endl;
}
}
Another way to print it out would be to use iterators like so:
void Print(const std::vector<int>& v) {
std::vector<int>::iterator it;
for(it = v.begin(); it != v.end(); ++it) {
std::cout << (*it) << '\n';
}
}
Or in C++11 you can do it like so:
void Print(const std::vector<int>& v) {
for(auto& i : v)
std::cout << i << '\n';
}
I don't think your Initialize() function works like you expect it to. It seems to just make a copy and then discards it, not modifying any values of the existing vector.
Leveraging c++ std's 11 onwards, this could be acheived in one line as shown below.
std::for_each(v.begin(),v.end(),[](const int &i) { std::cout << i; });
This code runs a for loop using std::vector iterators from begin() to end(), serially feeding the lambda/[] function the required argument to be printed.
Is it possible to implement a C++ function which gives a string representation of every std::vector<T>, as long as the element of type T can be appended to an output stream like
T x;
...
std::cout << x << std::endl;
The string representation should look like
[x, y, z]
I've attempted the following, but what should ? be?
template <typename T> std::string vectorToString(std::vector<T>& vec) {
std::string s;
for (T element : vec) {
?
}
return s;
}
You'll want a stringstream to do the formatting:
std::ostringstream ss;
ss << '['
bool first = true;
for (T const & element : vec) {
if (!first) {
ss << ", ";
}
ss << element;
first = false;
}
ss << ']';
return ss.str();
Use a std::ostringstream instance for ? and return std::ostringstream::str():
std::ostringstream s;
s << "[";
for (auto i(vec.begin()); i != vec.end(); i++)
{
if (vec.begin() != i) s << ", ";
s << *i;
}
s << "]";
return s.str();
If you are working on C++11, you can use this simple version:
#include <sstream>
#include <algorithm>
using namespace std;
template<typename T>
string format(vector<T> const& v)
{
if (v.empty()) return "[]";
ostringstream ss;
ss << "[" << v[0];
for_each(begin(v) + 1, end(v), [&ss] (T const& s) { ss << ", " << s; });
ss << "]";
return ss.str();
}
If you want to make it generic for other types of collections (not just vector) or even for sub-ranges of a collection, you can generalize it this way:
#include <sstream>
#include <algorithm>
using namespace std;
template<typename It>
string format(It b, It e)
{
if (b == e) return "[]";
ostringstream ss;
ss << "[" << *b;
for_each(++b, e, [&ss] (decltype(*b)& s) { ss << ", " << s; });
ss << "]";
return ss.str();
}
template<typename C>
string format(C const& c)
{
return format(begin(c), end(c));
}
int main()
{
vector<int> v = { 4, 5, 5, 8 };
cout << format(v) << endl;
return 0;
}
Using algorithms, which usually simplify code (not sure if in this case, but added for the sake of completion):
template <typename T>
std::string toString( std::vector<T> const & v ) {
if (v.empty())
return "[]";
typename std::vector<T>::const_iterator last = std::prev(v.end());
std::ostringstream st;
st << "[ ";
std::copy( v.begin(), last, std::ostream_iterator<T>(st,", ") );
st << *last << " ]";
return st.str();
}
A little bit faster version
template <typename T> std::string vectorToString( const std::vector<T>& vec ) {
if ( vec.empty() ) {
return "[]";
}
std::ostringstream s;
s << "[" << vec.front();
for (auto i = vec.begin() + 1, e = vec.end(); i != e; i++)
{
s << ", " << *i;
}
s << "]";
return s.str();
}
Another moment: maybe it would be right to specialize this function for strings and quote them, because if a string in vector begins or ends with , it would be hard to understand how many strings was printed.
template <>
std::string vectorToString< std::string >( const std::vector<std::string>& vec ) {
if ( vec.empty() ) {
return "[]";
}
std::ostringstream s;
s << "[" << vec.front();
for (auto i = vec.begin() + 1, e = vec.end(); i != e; i++)
{
s << ", \"" << *i << "\"";
}
s << "]";
return s.str();
}
In my example there are three similar vectors which I would like to print.
Could you help me understand how to transfer a vector into a subprogram so that not to
repeat myself?
#include "stdafx.h";
#include <vector>;
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
struct SPoint
{
int X;
int Y;
};
vector<SPoint> points;
vector<SPoint> selected;
vector<SPoint> cleared;
void print_points()
{
cout << "Points: "<< endl;
for (int i = 0; i < points.size(); i++)
{
cout << '('<<points[i].X <<',' <<points[i].Y <<')'<< endl;
}
cout << endl;
}
void print_selected()
{
cout << "Selected: "<< endl;
for (int i = 0; i < selected.size(); i++)
{
cout << '('<<selected[i].X <<',' <<selected[i].Y <<')'<< endl;
}
cout << endl;
}
void print_cleared()
{
cout << "Cleared: "<< endl;
for (int i = 0; i < cleared.size(); i++)
{
cout << '('<<cleared[i].X <<',' <<cleared[i].Y <<')'<< endl;
}
cout << endl;
}
int main ()
{
SPoint temp = {0, 0};
for (int i = 0; i < 11;i++)
{
temp.X = i;
temp.Y = i;
points.push_back(temp);
}
for (int i = 5; i< 11;i++)
{
temp.X = i;
temp.Y = i;
points.push_back(temp);
}
print_points();
print_selected();
print_cleared();
system ("pause");
return 0;
}
You could do something like this:
void
print(const std::vector<SPoint>& vect, const std::string& message)
{
std::cout << message << ":" << std::endl;
for (int i = 0, size = vect.size(); i < size; ++i)
std::cout << vect[i].X << ":" << vector[i].Y << " ";
std::endl;
}
print(points, "Points");
print(points, "Selected");
print(points, "Cleared");
Good luck
To pass a vector as an argument to a function you do something like this:
void func(const vector<SPoint>& points) {
... do stuff
}
Then you call the function in you code like this:
...some stuff
vector<SPoint> a;
func(a);
Just use a const reference to a vector and pass it to the function:
void print(const vector<SPoint> &data) const {
}
...
print(points);
Here is a full C++ style approach:
struct SPoint
{
int X;
int Y;
};
std::ostream& operator <<( std::ostream& stream, SPoint const& point )
{
stream << '(' << point.X << ',' <<point.Y << ')';
return stream;
}
void print_vector( std::ostream& stream, std::vector< SPoint > const& vector )
{
std::copy(
points.begin(), points.end()
, std::ostream_iterator< SPoint >( std::cout, '\n' )
);
}
and then:
print_vector( std::cout, points );
print_vector( std::cout, selected );
print_vector( std::cout, cleared );