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";
}
Related
Is there any STL/Boost function in C++ that allows me to find the indices of all unique elements in a vector?
I have seen many solutons to find unique elements, but I need their index.
vector<int> v = { 1,1,1, 2,2,2,2, 3, 3, ,4,5,5,5,5,5,5 };// already sorted
Either I need first index of unique elemnt
vector<int> unique_index={0,3,7,9,10};
or I need last index of unique elements
vector<int> unique_index={2,6,8,9,15};
A simple way (aside from just keeping track of what the last element was) is to use a std::set to test if the current element is unique in the elements of the vector -- seen so far, and populate your unique indexes as you go. This provides a single pass through to collect the indexes where the first unique element is seen, e.g.
#include <iostream>
#include <vector>
#include <set>
int main (void) {
std::vector<int> v = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5 },
uniqueidx{};
std::set<int> s{};
for (size_t i = 0; i < v.size(); i++)
if (s.insert(v[i]).second)
uniqueidx.push_back(i);
for (const auto i : uniqueidx)
std::cout << i << '\n';
}
Example Use/Output
$ ./bin/set_index_of_unique_in_vector
0
3
7
10
11
(note: the last two values are 10 and 11, not 9 and 10 -- you are missing a value in your vector initialization, e.g. 3, ,4)
If you just wanted a simple-old loop to do the same thing, you could use:
#include <iostream>
#include <vector>
int main (void) {
std::vector<int> v = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5 },
uniqueidx{};
for (size_t i = 0; i < v.size(); i++)
if (!i || v[i-1] != v[i])
uniqueidx.push_back(i);
for (const auto i : uniqueidx)
std::cout << i << '\n';
}
(same output)
The benefit of the approach with std::set is you leave the determination of uniqueness up to std::set, with the simple loop -- it's up to you....
Look things over and let me know if you have questions.
Similar to David's answer of using std::set, you could also use std::map with its member function try_emplace(key, value):
#include <iostream>
#include <vector>
#include <map>
int main (void) {
std::vector<int> v = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5 };
std::map<int, int> m;
for (size_t i = 0; i < v.size(); i++)
{
// `i` is only entered if the `m[v[i]]` isn't filled yet.
m.try_emplace(v[i], i);
}
for (auto [valueFromV, indexFromV] : m)
{
std::cout << indexFromV << '\n';
}
}
you can change this code and using int instead of a string.
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <iterator>
#include <algorithm>
std::map<std::string, int> get_unique_indices(const std::vector<std::string>& products) {
std::vector<std::string> tempProducts(products);
std::map<std::string, int> result;
std::sort(std::begin(tempProducts), std::end(tempProducts));
for (auto it1 = std::begin(tempProducts), it2 = it1; it1 != std::end(tempProducts); it1 = it2) {
int duplication = 0;
for (; it2 != std::end(tempProducts) && (*it2 == *it1); ++it2) {
duplication++;
}
if (duplication == 1) {
result.insert({ *it1, std::find(std::begin(products), std::end(products), *it1) - std::begin(products) });
}
}
return result;
}
int main()
{
using namespace std;
vector<string> products = { "apple", "orange", "lemon", "apple", "kivi", "orange", "kivi", "melon"};
auto result = get_unique_indices(products);
for (const auto& [key, value] : result) {
std::cout << key << " " << value << std::endl;
}
return 0;
}
At first, I create another vector to save the original data. (Cause the position of the item will change in the sort method).
then I use two iterators to find duplicate items and count them. the result will be saved in a map instance.
this code must compile with c++17 onwards.
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
vector<int> a = {1, 2, 3, 4, 5};
for (auto &x : a)
cout << x << endl;
}
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
vector<int> a = {1, 2, 3, 4, 5};
for (auto x : a)
cout << x << endl;
}
Two codes above prints same values (1, 2, 3, 4, 5).
But is there different thing between initializing &x and x?
Thanks for reading!
There is no difference in the output for the code you wrote. However, if you tried to change the value of x when in the loop, there would be a difference.
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
vector<int> a = {1, 2, 3, 4, 5};
for (auto x : a)
x = 0;
for (auto x : a)
cout << x << endl;
}
is very different to:
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
vector<int> a = {1, 2, 3, 4, 5};
for (auto & x : a)
x = 0;
for (auto x : a)
cout << x << endl;
}
In the second, the vector a will be all zeros at the end of the program. This is because auto by itself copies each element to a temporary value inside the loop, whereas auto & takes a reference to an element of the vector, which means that if you assign something to the reference it overwrites wherever the reference is pointing.
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.
Goal: Return all elements in vector A that appear N times and put results in vector B.
Expected Result:
--Begin With---
Vector A=(10,20,30,30,40,50,100,50,20,100,10,10,200,300)
Do some code to return the name of elements that appear in Vector A
when N=3
Result should be Vector B=(10) //because only 10 is in vector A N=3 times.
My Attempt:
I got the counts of all the elements placed into another vector but I don't have the part that can give back all of the elements that appear N times. I'm very flexible with how it can be done if it means a speed increase.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator> // std::back_inserter
#include <algorithm> // std::copy
int main()
{
std::vector<int> v{ 1, 2, 3, 4, 4, 3, 7, 8, 9, 10 };
std::vector<std::pair<int, int> > shows;
int target1;
int num_items1;
int size = static_cast<int>(v.size());
for(int x=0; x<size; x++)
{
target1 = v[x];
num_items1 = std::count(v.begin(), v.end(), target1);
shows.push_back(std::make_pair(target1, num_items1));
std::cout << "number: " << target1 << " count: " << num_items1 << '\n';
}
}
ACCEPTED SOLUTION TO QUESTION
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator> // std::back_inserter
#include <algorithm> // std::copy
#include <set>
#include <map>
using namespace std;
int main()
{
std::vector<int> v{ 1, 2, 3, 4, 4, 3, 7, 8, 9, 10 };
std::vector<int> shows;
std::map<int, int> freqOfv;
for(const auto& i: v)
{
freqOfv[i]++;
}
std::set<int> s(v.begin(), v.end());
int N = 2; //Can be read from stdin as well...
for ( auto it = s.begin(); it != s.end(); it++ )
{
if(freqOfv[*it] ==N)
{
shows.push_back(*it);
}
}
for (std::vector<int>::const_iterator i = shows.begin(); i != shows.end(); ++i)
{
std::cout << *i << ' ';
}
return 0;
}
As suggested in the comments, std::map will simplify the code:
int main()
{
std::vector<int> v{ 1, 2, 3, 4, 4, 3, 7, 8, 9, 10 };
std::map<int, int> freqOfv;
for(const auto& i: v)
freqOfv[i]++;
int N = 2; //Can be read from stdin as well...
for(const auto& i: freqOfv)
{
if(N == i.second)
std::cout << "The value " << i.first << " occurs " << N << " times." << std::endl;
}
}
This produces the following output:
The value 3 occurs 2 times.
The value 4 occurs 2 times.
Of course, you need #include <map> at the beginning to use maps in your code.
I have vectors and I would like to retrieve one vector that contains all entries which aren't duplicated anywhere in all input vectors.
#include <vector>
int main() {
std::vector<int> a = {2, 1, 3};
std::vector<int> b = {99, 1, 3, 5, 4};
std::vector<int> c = {5, 6, 7, 1};
// magic to retrieve {2, 99, 4, 6, 7} (order doesn't matter)
}
Is there a library function that can help performing this task efficiently?
I'm not tied to using vectors. The solution could include lists, sets, or whatever are most appropriate for the task.
Using unordered_map, O(N) space complexity and O(N) time complexity:
#include <vector>
#include <unordered_map>
#include <iostream>
std::vector<int>
get_unique_values(std::initializer_list<std::vector<int>> vectors)
{
std::unordered_map<int, size_t> tmp;
auto insert_value_in_tmp = [&tmp](int v) {
auto i = tmp.find(v);
if (i == tmp.end())
tmp[v] = 1;
else if (i->second != 2)
i->second = 2;
};
for ( auto& vec : vectors) {
for ( auto vec_value : vec ) {
insert_value_in_tmp(vec_value);
}
}
std::vector<int> result;
for (auto v : tmp) {
if (v.second == 1)
result.push_back(v.first);
}
return result;
};
int main() {
std::vector<int> a = {2, 1, 3};
std::vector<int> b = {99, 3, 5, 4};
std::vector<int> c = {5, 6, 7};
std::vector<int> result = get_unique_values({a,b,c});
for (auto v : result) {
std::cout << v << " ";
}
std::cout << '\n';
return 0;
}