#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.
Related
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";
}
I want to compare the elements in array whether there is a similar element is present or not?
I am using two loops and it gives TLE can anyone help me in this?
code:-
int main() {
int arr=[1, 2, 3, 3, 4, 5, 6, 5, 6]
int max=0;
int k;
int c=0;
for (int i=0;i<n;i++) {
for (int j= i+1;j<n;j++) {
if (a[i]==a[j]) {
c++;
if (k>max) {
max= k;
}
}
}
}
}
how to optimize this?
The std::sort function time complexity is nlog(n) (According to Wikipedia, it's Intro Sort)
So one approach for your question is to:
Sort the array (It's better to use std::vector instead of C-Style array)
Compare every element with the next one (Which is going to be O(n))
If the two elements are equal, so show it or add it to a std::set to use it later
Here is my implementation for the algorithm that I mentioned before:
#include <vector>
#include <iostream>
#include <set>
#include <algorithm>
int main() {
std::vector<int> data{1, 2, 3, 4, 6, 2, 7, 1, 5, 4};
std::set<int> duplicatedValues;
std::sort(data.begin(), data.end());
for (int i{0}; i < data.size()-1; ++i)
if (data[i] == data[i+1])
duplicatedValues.insert(data[i]);
for (int value : duplicatedValues)
std::cout << value << " ";
std::cout << std::endl;
}
So time complexity for code above is going to be nlog(n)
Note: I should add that if you have n data and all of them are between range of 0 to n-1, We have O(n) for that, take a look at here.
Second Approach: (By using std::unordered_map)
(It takes a little shorter time than the previous approach, but roughly 2 times more memory!)
We can add every element in a dictionary and if we had that same data again in our array, increase its number in dictionary; and finally, show elements that have number more than 1.
#include <iostream>
#include <unordered_map>
#include <vector>
#include <stdlib.h>
int main() {
std::vector<int> data{1, 2, 8, 2, 5, 4, 1, 9, 2, 3, 8};
std::unordered_map<int, int> duplicatedData;
for (int i{0}; i < data.size(); ++i) {
if (duplicatedData.find(data[i]) == duplicatedData.end()) {
duplicatedData[data[i]] = 1;
}
else {
duplicatedData[data[i]] += 1;
}
}
for (auto x : duplicatedData) {
if (x.second > 1) {
std::cout << x.first << " ";
}
}
std::cout << std::endl;
}
EDIT: I recorded a video for this, with performance measurement in here
i will do it like
#include <algorithm>
#include <vector>
#include <execution>
#include <atomic>
#include <iostream>
int main()
{
int arr[] = {1,2,3,5,6};
std::atomic<bool> com_tr = false;
std::for_each(std::execution::par, &arr[0], (&arr[0] + sizeof(arr)/sizeof(int)),
[&](auto a)
{ com_tr = std::count(&arr[0], (&arr[0] + sizeof(arr)/sizeof(int)), a) == 1 ? (bool)com_tr : !false; });
if (com_tr) std::cout << "have one " << std::endl;
}
compiled with c++ -std=c++17 -O3 '/home/alex/etr/b.cpp' -o t -ltbb
but if it's really all you need to accomplish better would be std::any_of()
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.
How would I convert a vector of ints into a single int in c++?
vector<int>myints = {3, 55, 2, 7, 8}
Expected answer: 355278
Here's a quick and dirty way:
using namespace std;
vector<int> myints = {3, 55, 2, 7, 8};
stringstream stream;
for(const auto &i : myints)
{
stream << i;
}
int value = stoi(stream.str());
And here's a way to do it without strings:
using namespace std;
vector<int> myints = {3, 55, 2, 7, 8};
int value = 0;
for(auto i : myints)
{
int number = i;
do
{
value *= 10;
i /= 10;
}while(i != 0);
value += number;
}
cout << value << endl;
The i /= 10 is the key bit here as it scales the number up based on the number of digits in the current number, i
Using the <string> library and the += operator you can iterate over the vector of ints, cast each number to a string and print out the result:
#include <vector>
#include <iostream>
#include <string>
using namespace std;
int main() {
vector <int> myints = {3, 55, 2, -1, 7, 8};
string s = "";
for(int i : myints){
s += to_string(i);
}
cout << s; //prints 3552-178
}
This should do the job. Please care that an int may not be enough to handle the number of digits.
#include <vector>
#include <sstream>
int vectorToSingleInt(const std::vector<int> &myints)
{
std::stringstream stringStream;
for (int &i : myints)
stringStream << i;
int output = 0;
stringStream >> output;
return output;
}
The trick is that you need to figure out how many digits each number contains. You can use log10 from <cmath> to do this. You can move the total by pow(10, x), where x is the number of digits you are adding:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
vector<int>myints = {3, 55, 2, 7, 8};
int total = 0;
for (auto it = myints.begin(); it != myints.end(); ++it) {
int x = int(log10(*it)) + 1;
total = total * pow(10, x) + *it;
}
cout << total << endl;
return 0;
}
The output is 355278, as expected.
Here is an IDEOne link.
There is a upper_bound(), returns an iterator to the first element that is greater than val.
There is a lower_bound(), returns an iterator to the first element that is not less than val.
Is there an algorithm that returns an iterator to the first element that is not greater than val, or I have to reinvent the wheel?
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<int> data = { 1, 1, 2, 3, 3, 3, 3, 5, 5, 6 };
auto lower = std::lower_bound(data.begin(), data.end(), 4, [](int x, int y) {return x > y;});
cout << *lower ;
}
Output: 1, expexted 3
Note that another predicate like std::greater<> doesn't work.
Just use the predicate as in your code, but traverse it in reverse order with rbegin and rend
My two bits, you forgot to sort in descending order.
int main()
{
vector<int> data = { 1, 1, 2, 3, 3, 3, 3, 5, 5, 6 };
int wanted {4};
sort(begin(data), end(data), greater<int>());
auto bound = upper_bound(begin(data), end(data), wanted, greater<int>());
cout << "val with upper_bound: " << *bound << endl;
}
result: val with upper_bound: 3
or one step below with partition_point:
template <typename T>
struct greater_than {
T x;
bool operator()(const T& y) { return y > x; }
};
int main()
{
...
auto p_point = partition_point(begin(data), end(data),
greater_than<int>{wanted});
cout << "val with partition_point: " << *p_point << endl;
// val with partition_point: 3