C++ Insert result of permutations into a vector - c++

I am encountering the issue that the first result of the permutation is being entered into the vector, but on the next for_each loop iteration the size of the vector resets itself to {size = 0}, instead of increasing its size and inserting the second permutation, and so on. How do I get around this? I've tried using a while loop but I couldn't work out what the condition for it should be.
I also wanted to ask, as later on I will need to compare the values in this vector to a vector containing a dictionary, would the current code (when working correctly) allow me to do so.
This is my code so far:
for_each(permutations.begin(), permutations.end(), [](string stringPermutations)
{
vector<string> permutations;
permutations.push_back(stringPermutations);
cout << stringPermutations << endl;
});
So apparently it looks like the lambda always creates a new, local, vector each time it's called. If I place vector<string> permutations; outside of the lambda I get an error with permutations.push_back(stringPermutations);. So how do I go about retrieving the stringPermutations out of the lambda and into a public accessible vector?
Thanks for the help and feedback.

Declare the vector outside the lambda and use lambda capture to capture this vector:
vector<string> permutation_v;
for_each(permutations.begin(), permutations.end(), [&](string stringPermutations)
// ^
{
permutation_v.push_back(stringPermutations);
cout << stringPermutations << endl;
});
But if I were you, I would directly construct this vector as
vector<string> permutation_v{permutations.begin(), permutations.end()};

It is unclear what you want to achieve with your code, but it just seems you want to print the contents of permutations.
Then just look at the elements in the vector.
for (auto &permutation : permutations) std::cout << permutation << '\n';
The question is: why do you use an std::unordered_set<std::string> and not a std::vector<std::string> in the first place? then you do not need to copy the elements into a new vector.

Related

Cpp: cout produces different output for each try without changing the code

In my cpp code I'm iterating over four geotiff images and want to extract their geotiepoints (coordinates) in a pair with the image number as first and the geotiepoints as second.
Next, I want to push them into a global vector of type pair for later use. That's my current code:
//Global Variable
std::vector <std::pair<short, double*>> GeoTPWithNr;
//for each file in directory
void GetGeoTiePoints(TIFF* tif)
{
unsigned short count;
double* Geotiepoints;
std::pair<short, double*>TiepointsWithNumber;
TiepointsWithNumber.first = filenumber;
TIFFGetField(tif, TIFFTAG_GEOTIEPOINTS, &count, &Geotiepoints)
TiepointsWithNumber.second = Geotiepoints;
GeoTPWithNr.push_back(TiepointsWithNumber);
std::cout << GeoTPWithNr[0].second[3] << std::endl;
std::cout << GeoTPWithNr[0].second[4] << std::endl;
}
To test the code I want to print the tiepoints of the vector at position 0. What I expect are four times the tiepoint values. When I ran the code first time it worked and I got the following result:
However, every time I run my code I get different result, eventhough I didn't change anything in my code.
When I print the values of my pair, before I push it into the vector, I always get the correct results. Thus, it seems there is a problem when trying to push the pair into the vector or retrieving the values from the vector.
Where is the problem? I guess it has something to do with how the results are written into the vector. Does anyone have an idea on how to solve this issue?
Thanks and best wishes
If I understood the problem correctly, my code doesn't write the actual values into the declared pair, but only to pointer to the values. When the compiler finishes the function it removes the values, thus at the next iteration of the loop the pointer somewhere else.
since I couldn't find a way to write an actuall array into a pair I replaced the pair by:
std::vector <std::array <double, 7>> GeoTPWithNr;
At position 7 I'm writing the value I wanted to write at the pair.first. Now that I write values into my global variable instead of a pointer, my output is stable and correct.

How to store a list of strings

I want store a list of strings that I will generate. I don't know the amount of strings and I also don't want to store them if there is an identical string in the list. I then want to be able to count the amount of strings in the list.
Thanks!
Use std::set for a container that automatically keeps the elements sorted and only allows distinct elements (no duplicates), e.g.:
std::set<std::string> s;
s.emplace("Arthur");
s.emplace("Barry");
s.emplace("Barry");
s.emplace("Barry");
s.emplace("Charlie");
std::cout << std::size(s) << std::endl; // Outputs '3'.
If you need fast access and seldomly update the container you might as well use std::vector and simply remove any duplicates after every insertion.
std::vector<std::string> v;
v.emplace_back("Arthur");
v.emplace_back("Barry");
v.emplace_back("Barry");
v.emplace_back("Barry");
v.emplace_back("Charlie");
std::sort(std::begin(v), std::end(v)); // Sort needed for 'std::unique' to always work.
v.erase(std::unique(std::begin(v), std::end(v)), std::end(v)); // Remove duplicates.
std::cout << std::size(v) << std::endl; // Outputs '3'.
std::vector does not keep the elements sorted though.

C++ Reverse sequence of elements in a vector

Hello I'm still new to C++ and I am writing a program to reverse the elements in a vector. I don't get any errors running the program but when I run it and I enter the numbers my program prints " Printing ... end of print" then it just closes on its own. I sure it may be a simple mistake.
using namespace std;
vector<int> reverse_a(const vector<int>&veca)
{
vector<int> vecb;
//size_t as the index type
size_t i = veca.size();
while ( i > 0 )
vecb.push_back(veca[--i]);
return vecb;
}
void print(const vector<int> vec)
{
cout << "printing " << endl;
for (size_t i = 0; i < vec.size(); ++i)
cout << vec[i] << ",";
cout << "\n" << "\n end of print.\n";
}
int main(void)
{
vector<int>veca;
vector<int>vecb;
int input;
while(cin >> input)
veca.push_back(input);
reverse_a(veca);
print(vecb);
}
Sort of off topic, but can't be explained in a comment. Aderis's answer is correct and πάντα ῥεῖ brings up an alternative for OP.
As with most intro to programming problems, the standard Library has done all of the work already. There is no need for any function because it already exists, in a somewhat twisted form:
std::copy(veca.rbegin(), veca.rend(), std::back_inserter(vecb));
std::copy does just what it sounds like it does: it copies. You specify where to start, where to stop, and where to put the results.
In this case we want to copy from veca, but we want to copy backwards, so rather than calling begin like we normally would, we call rbegin to get one of those reverse iterator thingys πάντα ῥεῖ was talking about. To define the end, we use rend which, rather than tearing things limb from limb marks the end of the reverse range of veca. Typically this is one before the beginning, veca[-1], if such a thing existed.
std::back_inserter tells std::copy how to place the the data from veca in vecb, at the back.
One could be tempted to skip all of this reverse nonsense and
std::copy(veca.begin(), veca.end(), std::front_inserter(vecb));
but no. For one thing, it would be hilariously slow. Consider veca = {1,2,3,4,5}. You'd insert 1 at the beginning of vecb, then copy it to the second slot to make room for 2. Then move 2 and 1 over one slot each to fit in 3. You'd get the nice reverse ordering, but the shuffling would be be murderous. The second reason you can't do it is because vector does not implement the push_front function required to make this work, again because it would be brutally slow.
Caveat:
This approach is simple, but slow. The back_inserter may force resizing of the vector's internal array, but this can be mitigated by preallocating vecb's storage.
It's just a simple mistake. You are forgetting to set vecb to the result of the reverse_a function in main. Instead of reverse_a(veca);, you should have vecb = reverse_a(veca);. The way you currently have it, vecb never gets set and therefore has a length of zero and nothing prints.

Assigning values in a vector in non-sequential order

I want to implement a code similar to the below-mentioned one using vectors in the most efficient and easiest manner. How do I do it?
int a[1005];
for(int i=1;i<=1000;i+=5)
a[i]=i*i;
When I try doing the same using vectors,compiler throws assertion failed error..subscript out of range...
vector<int> a;
for(int i=1;i<=1000;i+=5)
a[i]=i*i;
So,I tried pushback function...However the index of vector could only be increased from 0 to number of calls to pushback and not in the way I want i.e 1,6,11,16
vector<int> a;
for(int i=1;i<=1000;i+=5)
a.pushback(i*i);
Declare the vector with the size you want as a constructor argument: vector<int> a(1000);
My answer is going to be a little different than the others so far.
If the goal is to store numbers in a container, and not care about sizing, or care about whether the data is stored contiguously, then the solution could be to use a std::map<int, int>.
Example:
#include <map>
#include <iostream>
using namespace std;
int main()
{
std::map<int, int> a;
for(int i=1;i<=1000;i+=5)
a[i]=i*i;
// output the results
auto it = a.begin();
while (it != a.end())
{
cout << it->first << " has a value of " << it->second << endl;
++it;
}
}
Live Example: http://ideone.com/sfgfmu
Note that there were no changes to your original code, except to change the declaration of vector to map.
Each entry in the map has a key/value pair of the i item as the key, and its square as the data. Then you can use the operator [] of the map similar to how you would use it for an array. However, there are differences, in that a map has to do a lookup, while an array is direct access, plus a map will fill in an entry if the item doesn't already exist.
As far as performance, the map has to store the items differently than an array for this to work. Thus you more than likely will get a small degradation in speed, but not a lot (since a map finds items in logarithmic time, not linear).
So it's up to you whether to stick with a vector and deal with the resizing issue, or go with a std::map and live with convenience with a possible degradation in speed (but may not be a lot if any degradation, depending on your usage).
You need to tell the vector how many elements to have.
#include <vector>
int main()
{
std::vector<int> a(1000); // 1000 elements
for(int i = 0; i < 1000; i += 5)
a[i] = i * i;
}
Also note arrays and vectors start from 0 not 1. So a 1000 element array or vector counts form 0 - 999 (not 1 - 1000).

Working with structure objects

I have a logic that looks like the below (Not the actual code):
StructureElement x;
For i in 1 to 1000
do
x.Elem1 = 20;
x.Elem2 = 30;
push(x into a std::vector)
end
My knowledge is that x be allocated memory only once and that the existing values will be overwritten for every iteration.
Also, the 'x' pushed into the vector will not be affected by subsequent iterations of pushing a modified 'x'.
Am I right in my observations?
Is the above optimal? I would want to keep memory consumption minimal and would not prefer using new. Am I missing anything by not using new?
Also, I pass this vector and recieve a reference to it it another method.
And, if I were to read the vector elements back, is this right?
Structure element xx = mYvector.begin()
print xx.Elem1
print xx.Elem2
Any optimizations or different ideas would be welcome.
Am I right in my observations?
Yes, if the vector is std::vector<StructureElement>, in which case it keeps its own copies if what is pushed in.
Is the above optimal?
It is sub-optimal because it results in many re-allocations of the vector's underlying data buffer, plus unnecessary assignments and copies. The compiler may optimize some of the assignments and copies away, but there is no reason, for example, to re-set the elements of x in the loop.
You can simplify it like this:
std:vector<StructureElement> v(1000, StructureElement{20, 30});
This creates a size-1000 vector containing copies of StructureElement with the desired values, which is what you seem to be trying in your pseudo-code.
To read the elements back, you have options. A range based for-loop if you want to iterate over all elements:
for (const auto& e: v):
std::cout << e.Elem1 << " " << e.Elem2 << std::endl;
Using iterators,
for (auto it = begin(v); it != end(v); ++it)
std::cout << it->Elem1 << it->Elem2 << std::endl;
Or, pass ranges in to algorithms
std::transform(begin(v), end(v), ....);