concat std::vector and initializer list - c++

In c++11 you can do this wonderful syntax:
vector<int> numbers = {1, 2, 3};
Is there a way to concatenate a further initializer list onto an existing vector?
numbers.??? ({4, 5, 6});
or
std::??? (numbers, {4, 5, 6});

You can use std::vector::insert for that:
#include <vector>
vector<int> numbers = {1, 2, 3};
numbers.insert( numbers.end(), {4, 5, 6} );

Use std::vector::insert:
numbers.insert(numbers.end(), {4, 5, 6});

You can use std::vector::insert. Link to example code
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> a = {1,2,3};
a.insert(a.end(), {4,5,6});
for(int &i : a) {
cout << i << " ";
}
cout << endl;
return 0;
}

Related

Find unique element in sorted array using c++

I am trying to find unique element from the array these is question
Input : arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5}
Output : arr[] = {1, 2, 3, 4, 5}
They give me correct output but why they give 0 at the end in output:
these is my output:
{1,2,3,4,5,0}
Code:
#include<iostream>
using namespace std;
int main(){
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0;j<=n;j++){
if(arr[j]!=arr[j+1]){
cout<<arr[j];
}
}
}
Except for std::cout, you code is much more C than ++.
std::unique of the C++ Standard Library does exactly what you want. There is no need to re-implement this.
Next there is the erase-remove idiom to delete the superfluous elements.
For the output, you can use std::for_each() or at least a range-based for loop.
And also, you don't want using namespace std;
A more modern solution looks like this:
#include <iostream>
#include <algorithm>
#include <vector>
int main(){
std::vector<int> arr {1, 2, 2, 3, 4, 4, 4, 5, 5};
auto last = std::unique(arr.begin(), arr.end());
arr.erase(last, arr.end());
std::for_each(arr.begin(), arr.end(), [](int n){std::cout << n << std::endl;} );
}
Try it on Godbolt.
problem is in for loop becouse you use less or equal to n.
you need to use just less then n becouse array starts from zero that means you asking for sixth element that do not have alocalizated in memory
now it should be correct
#include<iostream>
using namespace std;
int main() {
int arr[] = {1, 2, 2, 3, 4, 4, 4, 5, 5};
int n=sizeof(arr)/sizeof(arr[0]);
int c=0;
for(int j=0; j<n; j++) {
if (arr[j]!=arr[j+1]) {
cout<<arr[j];
}
}
}

Iterate over columns in C++ matrix

I want to iterate over single row and column in std::vector<std::vector<int>> matrix and get their sum.
I know that I can do this in nested loop, but here is my question. Can I use
int val_sum = 0;
std::for_each(matrix_[row].begin(),matrix_[row].end(),[&](int x) { val_sum += x;});
for columns and how to do that?
The analogous way of your proposal is to iterate the matrix rows and accumulate the elements in the given column.
int val_sum = 0;
std::for_each(matrix.begin(),matrix.end(),[&](std::vector<int> &row) { val_sum += row[column];});
But I would still prefer to use the c++11 range-loop version
int val_sum = 0;
for ( const std::vector<int> &row : matrix )
val_sum += row[column];
You can use nested std::accumulate:
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<std::vector<int>> matrix = { {1, 2, 3}, {2, 3, 4}, {3, 4, 5} };
const int sum = std::accumulate(matrix.cbegin(), matrix.cend(), 0, [](const auto acc, const auto row) {
return acc + std::accumulate(row.cbegin(), row.cend(), 0);
});
std::cout << sum;
}
You could nest two for_each. You simply have to notice that every element of the outer for_each will be another vector<int>, a row. [Demo]
#include <algorithm> // for_each
#include <iostream> // cout
#include <vector>
int main()
{
std::vector<std::vector<int>> v{ {1, 2}, {3, 4}, {5, 6} };
std::for_each(std::cbegin(v), std::cend(v), [](auto& row) {
std::for_each(std::cbegin(row), std::cend(row), [](auto n) {
std::cout << n << " ";
});
std::cout << "\n";
});
}
If you want to sum all the elements of the matrix, you can use accumulate instead of the inner for_each loop. [Demo]
#include <algorithm> // for_each
#include <iostream> // cout
#include <numeric> // accumulate
#include <vector>
int main()
{
int result{};
std::vector<std::vector<int>> v{ {1, 2}, {3, 4}, {5, 6} };
std::for_each(std::cbegin(v), std::cend(v), [&result](auto& row) {
result += std::accumulate(std::cbegin(row), std::cend(row), 0);
});
std::cout << "sum = " << result << "\n";
}
Or even with two nested accumulate. [Demo]
#include <iostream> // cout
#include <numeric> // accumulate
#include <vector>
int main()
{
std::vector<std::vector<int>> v{ {1, 2}, {3, 4}, {5, 6} };
auto result = std::accumulate(std::cbegin(v), std::cend(v), 0, [](auto total, auto& row) {
return total + std::accumulate(std::cbegin(row), std::cend(row), 0);
});
std::cout << "sum = " << result << "\n";
}
If (after all, I misunderstood you from a beginning, and) you want to add all the elements of a given column. [Demo]
#include <iostream> // cout
#include <numeric> // accumulate
#include <vector>
int sum_column(const std::vector<std::vector<int>>& v, size_t column)
{
return std::accumulate(std::cbegin(v), std::cend(v), 0, [&column](auto total, auto& row) {
return total + row[column];
});
}
int main()
{
std::vector<std::vector<int>> v{ {1, 2}, {3, 4}, {5, 6} };
std::cout << "sum of column 1 = " << sum_column(v, 1) << "\n";
}

How to replace the 2D vector corresponding to the values?

I am trying to replace the elements in a 2D vector (vector<vector<int>>). I want to change the elements not only by one value, but by a list, which means, for example, change 1,3,4,5,8,9 to 1,2,3,4,5,6 one-to-one correspondence. I have made a very slow code with double loops. Is there any way to speed up the process, with new function or sort the element? Because my 2D vector is very big, 3*300000 actually. My example code is below:
int myints[] = { 1,3,4,5,8,9 };
int myints2[] = { 1,2,3,4,5,6 };
std::vector<int> vals (myints, myints+6);
std::vector<int> vals2 (myints2, myints2+6);
vector<vector<int>> V0(3);
V0[0]={1,4,5};
V0[1]={3,1,8};
V0[2]={1,9,4};
for (size_t j = 0; j < V0.size(); j++)
{
for (int i = 0; i < vals.size(); i++)
replace(V0[j].begin(), V0[j].end(), vals[i], vals2[i]);
};
The ideal output V0 should be
1 3 4
2 1 5
1 6 3
You can use an unordered_map to replace each value directly, instead of searching through the whole vector for each replacement:
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
unordered_map<int, int> replacements{{1, 1}, {3, 2}, {4, 3}, {5, 4}, {8, 5}, {9, 6}};
vector<vector<int>> v0(3);
v0[0] = {1, 4, 5};
v0[1] = {3, 1, 8};
v0[2] = {1, 9, 4};
for_each(v0.begin(), v0.end(), [&](vector<int>& v)
{
transform(v.begin(), v.end(), v.begin(), [&](int val)
{
auto it = replacements.find(val);
return it != replacements.end() ? replacements[val] : val;
});
});
// Print
for (auto& v : v0)
{
cout << "[ ";
for (auto val : v)
{
cout << val << ", ";
}
cout << "]" << endl;
}
return 0;
}
Output:
[ 1, 3, 4, ]
[ 2, 1, 5, ]
[ 1, 6, 3, ]
In C++17, you may also choose a parallel execution policy in for_each and/or transform, since all the changes can be done in parallel.

Can't convert std::array to int?

I am just learning c++ and am attempting to understand arrays.. So forgive my ignorance on what's wrong here.
#include <iostream>
#include <string>
#include <array>
using namespace std;
void readArray(int *readfile, int ArraySize){
int Interator;
for(Interator = 1; Interator < ArraySize; Interator++){
cout << " " << readfile[Interator];
}
}
int main(){
std::array<int, 5> array2={{1, 2, 3, 4, 5}};
readArray(array2, array2.end());
}
Error: Can't Convert 'std::array' to 'int*' for arg '1'to void 'readArray'
How would I fix this?
You cannot convert std::array to int* as compiler says. For such conversion you can use plain old array:
void readArray(int *readfile, int ArraySize)
{
int Interator;
for(Interator = 0; Interator < ArraySize; Interator++)
{
cout << " " << readfile[Interator];
}
}
int main()
{
//std::array<int, 5> array2={{1, 2, 3, 4, 5}};
int array2[] = {1, 2, 3, 4, 5};
readArray(array2, 5);
}
Also, Interator is changed to start from zero. If you need std::array then use std::array::begin() and std::array::begin():
void readArray2(const std::array<int, 5>& a)
{
for (auto elem : a)
cout << " " << elem;
}
int main()
{
std::array<int, 5> array2={{1, 2, 3, 4, 5}};
//int array2[] = {1, 2, 3, 4, 5};
readArray2(array2);
}
Just browse some reference to discover that std::array has a T* data() and a constexpr size_type size() which can and should be used for that purpose.
But this is a poor solution. The best solution would be to use iterators directly, eg:
template <typename T> void readArray(const T& data) {
for (const auto& element : data)
cout << element;
}
std::array<int, 5> data1 = { 1, 2, 3, 4, 5};
readArray(data1);
std::vector<int> data2 = {1, 2, 3, 4, 5};
readArray(data2);
std::list<int> data3 = {1, 2, 3, 4, 5};
readArray(data3);
Which would expect T to be a type that has proper begin and end() overloads.
It makes no sense to tag questions with C++11 if you try to use C solutions,

How to replace specific values in a vector in C++?

I have a vector with some values (3, 3, 6, 4, 9, 6, 1, 4, 6, 6, 7, 3), and I want to replace each 3 with a 54 or each 6 with a 1, for example and so on.
So I need to go through the vector first, get the [i] value, search and replace each 3 with a 54, but still keep relevant positions.std::set
is vector::swap a good way? I am not even sure how to begin this :(
I can't use push_back as that would not keep the correct order of values as that is important.
Please keep it simple; I am just a beginner :)
The tool for the job is std::replace:
std::vector<int> vec { 3, 3, 6, /* ... */ };
std::replace(vec.begin(), vec.end(), 3, 54); // replaces in-place
See it in action.
You can use the replace or replace_if algorithm.
Online Sample:
#include<vector>
#include<algorithm>
#include<iostream>
#include<iterator>
using namespace std;
class ReplaceFunc
{
int mNumComp;
public:
ReplaceFunc(int i):mNumComp(i){}
bool operator()(int i)
{
return i==mNumComp;
}
};
int main()
{
int arr[] = {3, 3, 6, 4, 9, 6, 1, 4, 6, 6, 7, 3};
std::vector<int> vec(arr,arr + sizeof(arr)/sizeof(arr[0]));
cout << "Before\n";
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, "\n"));
std::replace_if(vec.begin(), vec.end(), ReplaceFunc(3), 54);
cout << "After\n";
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, "\n"));
return 0;
}
You could loop through each element of the list.
std::vector<int> vec{3, 3, 6, 4, 9, 6, 1, 4, 6, 6, 7, 3};
for(int n=0;n<vec.size();n++)
if(vec[n]==3)
vec[n]=54;
Use the STL algorithm for_each. It is not required to loop, and you can do it in one shot with a function object as shown below.
http://en.cppreference.com/w/cpp/algorithm/for_each
Example:
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
void myfunction(int & i)
{
if (i==3)
i=54;
if (i==6)
i=1;
}
int main()
{
vector<int> v;
v.push_back(3);
v.push_back(3);
v.push_back(33);
v.push_back(6);
v.push_back(6);
v.push_back(66);
v.push_back(77);
ostream_iterator<int> printit(cout, " ");
cout << "Before replacing" << endl;
copy(v.begin(), v.end(), printit);
for_each(v.begin(), v.end(), myfunction)
;
cout << endl;
cout << "After replacing" << endl;
copy(v.begin(), v.end(), printit);
cout << endl;
}
Output:
Before replacing
3 3 33 6 6 66 77
After replacing
54 54 33 1 1 66 77