Why doesn't the range-based loop with auto display addresses?
The for loop:
for (int i = 0; i < s; i++) cout << &ar[i] << endl;
works normally, but range-based loop with auto doesn't:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int ar[] = { 12,-23,0,1,2 };
int s = sizeof(ar) / sizeof(int);
int * m = &ar[0];
sort(&ar[0], m+ s);
for (auto m : ar)
cout << m << endl;
cout << endl;
for (auto m : ar)
cout << &m << endl;
cout << endl;
for (int i = 0; i < s; i++)
cout << &ar[i] << endl;
system("pause");
}
With the auto m you are passing (array) elements by value / copy in your range based loop:
for (auto m : ar) { // pass by value
std::cout << &m << ' '; // prints addresses of copies, not the actual array elements
}
This means m becomes a copy of an array element in each iteration and has its own address in the memory.
If you passed by reference (auto& m) or a reference to const (const auto& m), you would observe the expected results:
for (auto& m : ar) { // pass by reference
std::cout << &m << ' '; // prints addresses of the actual array elements
}
Now m is an actual array element and &m represents the array element address as expected.
Related
how to loop only half of the elements in C++ vector data structure using auto keyword
vector<string> InputFIle;
void iterateHalf(){
/* iterate only from begin to half of the size */
for (auto w = InputFIle.begin(); w != InputFIle.end(); w++) {
cout << *w << " : found " << endl;
}
}
You need to compute begin and end of your loop, i.e. first and last_exclusive.
#include <vector>
#include <numeric>
#include <iostream>
int main(){
std::vector<int> vec(16);
std::iota(vec.begin(), vec.end(), 0);
size_t first = 3;
size_t last_exclusive = 7;
//loop using indices
for(size_t i = first; i < last_exclusive; i++){
const auto& w = vec[i];
std::cout << w << " ";
}
std::cout << "\n";
//loop using iterators
for(auto iterator = vec.begin() + first; iterator != vec.begin() + last_exclusive; ++iterator){
const auto& w = *iterator;
std::cout << w << " ";
}
std::cout << "\n";
}
template<typename s>
void vecprint2d(const s& vec){
cout<<"{"<<endl;
for(int x = 0; x < vec.size(); x++){
cout<<"{";
for(int y = 0; y < vec[x].size() - 1;y++){
cout << vec[x][y]<<", ";
}
cout<<vec[x][vec[x].size() - 1]<<"}"<<endl;
}
cout<<"}"<<endl;
}
int main(){
vector<vector<int>> vec = {{1,2,3},{},{4,5,6}};
vecprint2d(vec);
return 0;
}
in my attempt at a function for printing a vector of vectors,
why does cout inside the inner loop cause problems, or is the problem elsewhere?
the output right now looks like:
{
{
If the inner vector's size is 0, size() - 1 will overflow and it will loop forever and/or crash. Could that be what is happening on your raspberry pi?
To avoid this, handle 0-sized vectors as well.
For example like this:
template<typename s>
void vecprint2d(const s& vec) {
cout << "{" << endl;
for (auto const& row : vec) {
cout << "{";
int i = 0;
for (auto const& val : row) {
if (i++)
cout << ", ";
cout << val;
}
cout << "}" << endl;
}
cout << "}" << endl;
}
The size() function of an empty vector will return an (unsigned) value of zero and, in your inner loop, you test y against vec[x].size() - 1. This will give a value that has 'underflowed' and thus have the maximum value that a size_t variable can hold, so the y loop will run a very large number of times! However, it will likely fail on the first loop, because trying to access any element of an empty vector is undefined behaviour.
To fix this, enclose your inner loop in an "is it empty" if block (in fact, you should do this for both loops). Here's a possible solution:
template<typename s>
void vecprint2d(const s& vec)
{
cout << "{" << endl;;
if (!vec.empty()) for (size_t x = 0; x < vec.size(); x++) {
cout << "{";
if (!vec[x].empty()) {
for (size_t y = 0; y < vec[x].size() - 1; y++) {
cout << vec[x][y] << ", ";
}
cout << vec[x][vec[x].size() - 1];
}
cout << "}" << endl;
}
cout << "}" << endl;
}
Feel free to ask for further clarification and/or explanation.
I am trying to figure out how to bubble sort a 2D string array. I am currently stuck trying to figure out why my program isnt sorting the strings. I spsupect it could be possible that something is wrong with void swap. I feel somehting with the 2D array needs to be put in there. I am not very sure I just learned how to create bubble sorting algorithms.
#include
using namespace std;
const int SIZE = 2;
const int ROWS = 2;
void bubbleSort(string values[][SIZE]);
void swap(int &, int &);
int main ()
{
string values[ROWS][SIZE] = {{"A23", "A12"}, {"name1", "name2"}};
cout << "Unsorted Values: " << endl;
for(auto element : values)
cout << element << " ";
cout << endl;
cout << "Sorted Values" << endl;
bubbleSort(values);
for (auto element:values)
cout << element << " ";
return 0;
}
void bubbleSort(string values[][SIZE])
{
int maxElement;
int index;
for (maxElement = SIZE - 1; maxElement > 0; maxElement--)
{
for( index = 0; index < maxElement; index++)
{
if (values[0][index] > values[0][index + 1])
{
swap(values[0][index], values[0][index + 1]);
}
}
}
}
void swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
Your program prints out the adresses because your print loop iterate each entry of your string 2D array. Consequently, every entry is an array. So arr holds the pointer to the first element of the array.
You only need a nested loop to print out the values of the single elements:
for (auto row : values)
for (int i = 0; i < SIZE; i++)
std::cout << row[i] << " ";
Furthermore, there is no need to implement an own swap function. Just use std::swap(T&,T&)
But i assume that you want to achieve a multi array sort. Then you should use a simple struct to represent an entity instead of multiple arrays and implement a operator to compare two entities. I suggest to use a range based container too. Then you can take advantage of the standard sort functions.
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Entry
{
string id;
string name;
bool operator<(const Entry& comp)
{
return id < comp.id;
}
};
int main()
{
auto print = [](const vector<Entry>& vec)
{
for (auto& el : vec)
{
cout << el.id << "->" << el.name << "\t";
}
};
vector<Entry> values { {"A23","name1" }, {"A12", "name2"} };
cout << "Unsorted Values: " << endl;
print(values);
cout << endl;
std::sort(values.begin(), values.end());
cout << "Sorted Values" << endl;
print(values);
return 0;
}
Prints out:
Unsorted Values:
A23->name1 A12->name2
Sorted Values:
A12->name2 A23->name1
I have a vector array called nVectors.
vector<int>* nVectors[21];
for (int i = 1; i <= 20; i ++) {
nVectors[i] = generateVector(i);
}
I can print all the members of a single vector, but when it comes to the vector array, I still don't know how to print all the vectors in an array.
Maybe an iterator through all the member of a vector array and print using my predefined method pvector can solve this problem? But I don't know how to iterate in gdb.
std::array<std::vector<int>*, 21> nVectors;
for(std::array<std::vector<int>*>::iterator i = nVectors.begin();
i != nVectors.end();
++i)
{
for(std::vector<int>::iterator it = (*i)->begin();
it != (*i)->end();
++it)
{
std::cout << *it << " ";
}
}
std::cout << std::endl;
Or, in C++11:
std::vector<int>* nVectors[21];
for(auto &i : nVectors)
{
for(auto &it : i)
{
std::cout << *it << " ";
}
}
std::cout << std::endl;
I have this code, which reads in input from a file and stores it in a vector. So far, I've gotten it to give me the sum of the values within the vector and give the mean of the values using the sum.
What I'd like to do now is learn how to access the vector again and subtract a value from each element of the vector and then print it out again. For example, once the sum and mean are calculated, I'd like to be able to reprint each value in the terminal minus the mean. Any suggestions/examples?
#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
using namespace std;
int main()
{
fstream input;
input.open("input.txt");
double d;
vector<double> v;
cout << "The values in the file input.txt are: " << endl;
while (input >> d)
{
cout << d << endl;
v.push_back(d);
}
double total = 0.0;
double mean = 0.0;
double sub = 0.0;
for (int i = 0; i < v.size(); i++)
{
total += v[i];
mean = total / v.size();
sub = v[i] -= mean;
}
cout << "The sum of the values is: " << total << endl;
cout << "The mean value is: " << mean << endl;
cout << sub << endl;
}
You can simply access it like an array i.e. v[i] = v[i] - some_num;
Well, you could always run a transform over the vector:
std::transform(v.begin(), v.end(), v.begin(), [mean](int i) -> int { return i - mean; });
You could always also devise an iterator adapter that returns the result of an operation applied to the dereference of its component iterator when it's dereferenced. Then you could just copy the vector to the output stream:
std::copy(adapter(v.begin(), [mean](int i) -> { return i - mean; }), v.end(), std::ostream_iterator<int>(cout, "\n"));
Or, you could use a for loop...but that's kind of boring.
You can access the values in a vector just as you access any other array.
for (int i = 0; i < v.size(); i++)
{
v[i] -= 1;
}
Your code works fine. When I ran it I got the output:
The values in the file input.txt are:
1
2
3
4
5
6
7
8
9
10
The sum of the values is: 55
The mean value is: 5.5
But it could still be improved.
You are iterating over the vector using indexes. This is not the "STL Way" -- you should be using iterators, to wit:
typedef vector<double> doubles;
for( doubles::const_iterator it = v.begin(), it_end = v.end(); it != it_end; ++it )
{
total += *it;
mean = total / v.size();
}
This is better for a number of reasons discussed here and elsewhere, but here are two main reasons:
Every container provides the iterator concept. Not every container provides random-access (eg, indexed access).
You can generalize your iteration code.
Point number 2 brings up another way you can improve your code. Another thing about your code that isn't very STL-ish is the use of a hand-written loop. <algorithm>s were designed for this purpose, and the best code is the code you never write. You can use a loop to compute the total and mean of the vector, through the use of an accumulator:
#include <numeric>
#include <functional>
struct my_totals : public std::binary_function<my_totals, double, my_totals>
{
my_totals() : total_(0), count_(0) {};
my_totals operator+(double v) const
{
my_totals ret = *this;
ret.total_ += v;
++ret.count_;
return ret;
}
double mean() const { return total_/count_; }
double total_;
unsigned count_;
};
...and then:
my_totals ttls = std::accumulate(v.begin(), v.end(), my_totals());
cout << "The sum of the values is: " << ttls.total_ << endl;
cout << "The mean value is: " << ttls.mean() << endl;
EDIT:
If you have the benefit of a C++0x-compliant compiler, this can be made even simpler using std::for_each (within #include <algorithm>) and a lambda expression:
double total = 0;
for_each( v.begin(), v.end(), [&total](double v) { total += v; });
cout << "The sum of the values is: " << total << endl;
cout << "The mean value is: " << total/v.size() << endl;
Just use:
for (int i = 0; i < v.size(); i++)
{
v[i] -= valueToSubstract;
}
Or its equivalent (and more readable?):
for (int i = 0; i < v.size(); i++)
v[i] = v[i] - valueToSubstract;
You might want to consider using some algorithms instead:
// read in the data:
std::copy(std::istream_iterator<double>(input),
std::istream_iterator<double>(),
std::back_inserter(v));
sum = std::accumulate(v.begin(), v.end(), 0);
average = sum / v.size();
You can modify the values with std::transform, though until we get lambda expressions (C++0x) it may be more trouble than it's worth:
class difference {
double base;
public:
difference(double b) : base(b) {}
double operator()(double v) { return v-base; }
};
std::transform(v.begin(), v.end(), v.begin(), difference(average));
int main() {
using namespace std;
fstream input ("input.txt");
if (!input) return 1;
vector<double> v;
for (double d; input >> d;) {
v.push_back(d);
}
if (v.empty()) return 1;
double total = std::accumulate(v.begin(), v.end(), 0.0);
double mean = total / v.size();
cout << "The values in the file input.txt are:\n";
for (vector<double>::const_iterator x = v.begin(); x != v.end(); ++x) {
cout << *x << '\n';
}
cout << "The sum of the values is: " << total << '\n';
cout << "The mean value is: " << mean << '\n';
cout << "After subtracting the mean, The values are:\n";
for (vector<double>::const_iterator x = v.begin(); x != v.end(); ++x) {
cout << *x - mean << '\n'; // outputs without changing
*x -= mean; // changes the values in the vector
}
return 0;
}