This question already has answers here:
How to sum up elements of a C++ vector?
(13 answers)
Closed 2 years ago.
say I have an array that is an integer and stores five numbers, I want to add these numbers together and put them into a certain variable, how do I do this. if you have the answer to this then it would be greatly appreciated if you could respond. thanks.
Here is a simple code to sum integers:
Try it online!
#include <vector>
#include <iostream>
int main() {
std::vector<int> a = {1, 2, 3, 4, 5};
int res = 0;
for (auto x: a)
res += x;
std::cout << res << std::endl;
return 0;
}
Output:
15
Alternative way is to use std::accumulate:
Try it online!
#include <vector>
#include <iostream>
#include <numeric>
int main() {
std::vector<int> a = {1, 2, 3, 4, 5};
auto res = std::accumulate(a.begin(), a.end(), 0);
std::cout << res << std::endl;
return 0;
}
Related
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()
I want to achieve more less the equivalent to this Python code in C++ (but more memory efficient):
a = [1, 5, 3]
additional = 6
for elem in [additional] + a:
print(elem) # prints: 6 1 5 3
# alternative without creating the additional vector:
import itertools
for elem in itertools.chain([additional], a):
print(elem)
The only way that I know to do this in C++ is:
#include <iostream>
#include <vector>
int main() {
std::vector<int> a = {1, 5, 3};
int additional = 6;
for (int i = 0; i < a.size() + 1; ++i) {
int cur_elem;
if (i == 0) {
cur_elem = additional;
} else {
cur_elem = a[i-1];
}
std::cout << cur_elem << std::endl;
}
}
Is there a way to do this with a range based for loop? I found the Boost join operator but it seems to use only iterables, so I need to create an extra vector (like in the Python example).
Ideally, the iteration would be without creating the joined object in the memory and with algorithms of the standard library.
It can be done using the upcoming ranges feature.
Here's an example using Eric Niebler's range-v3 library:
#include <iostream>
#include <vector>
#include <range/v3/view/concat.hpp>
#include <range/v3/view/single.hpp>
int main() {
std::vector<int> a = {1, 5, 3};
int additional = 6;
for (auto i : ranges::concat_view(ranges::single_view{additional}, a)) {
std::cout << i;
}
}
See it live!
by using views, all iterator operations are lazy, and no extra memory is used (e.g.: no extra vectors/arrays are created)
Or, without the for loop:
ranges::copy(ranges::concat_view(ranges::single_view{additional}, a), ranges::make_ostream_joiner(std::cout, ","));
See it live!
(Honestly, I like the for version better, though)
Standard-compliant solution
There's a small issue with the solution above: concat_view did not make it into C++20. If you want a strictly compliant solution, you may want to create your own version, or use join_view instead:
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<int> a = {1, 5, 3};
int additional = 6;
std::vector v{{additional}, a};
for(int i : std::ranges::join_view{v}) {
std::cout << i;
}
}
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've recently began to work with C++ std::sets, so there is a question I did not find answer to in Google.
I have a std::set of some int values (e.g., let it be 1, 2, 3, 4, 5). The task is to calculate difference between two first elements. Is it possible to do with C++?
I'm using data structure std::set; And I know that first element can be got like that:
int diff = *arSeq.begin();
Where arSeq is mentioned set.
Is there any way to get the second element?
Yes it is possible. Access the first element via the std::set::begin iterator and the next one using the std::next function.
#include <iostream>
#include <set>
int main() {
std::set<int> s = { 1, 2, 3, 4, 5 };
auto result = *s.begin() - *std::next(s.begin());
std::cout << result;
}
Please note that you will again get the same result of -1 even if you defined your set as:
std::set<int> s = { 5, 3, 1, 4, 2 };
because the std::set is a container that:
contains a sorted set of unique objects...
You can do it the following way
#include <iostream>
#include <set>
#include <iterator>
int main()
{
std::set<int> s({ 1, 2, 3, 4, 5 });
long long int diff = 0;
if (not (s.size() < 2))
{
auto first = s.begin();
auto second = std::next(first);
diff = *first < *second ? ( long long int )*second - *first : ( long long int )*first - *second;
}
std::cout << "difference = " << diff << std::endl;
return 0;
}
What did you mean by first two elements. First two element inserted? then its not possible.
Set elements are sorted with given comparator. By default primitive elements are sorted in ascending order. See the output of following program.
// set::begin/end
#include <iostream>
#include <set>
#include<functional>
int main ()
{
int myints[] = {75,23,65,42,13};
std::set<int, std::greater<int>> myset (myints,myints+5);
auto first = myset.begin();
auto second = std::next(first);
std::cout <<*first<< ", " <<*second<<"\n";
return 0;
}`enter code here`
This question already has answers here:
What is the correct way of using C++11's range-based for?
(4 answers)
Closed 7 years ago.
I want to do in c++ something like in python would be:
nums=[31, 46, 11, 6, 14, 26]
nlttf=[]
for n in nums:
if n<25:nlttf.append(n)
That would be the Range-based for loop:
SomethingIteratable cont;
for (const auto &v : cont) {
// Do something
}
As usual, const auto &v gives you immutable references, auto &v mutable references and auto v mutable deep copies.
Beware: You may not do anything in the loop that invalidates iterators of the container you iterate.
If you have C++11 then the code is the following:
for (int n: iterator) { /*Do stuff with n*/ }
If you have C++11 or greater, then you can do it this way.
#include <iostream>
#include <vector>
using namespace std;
int main() {
int num[] = {31, 46, 11, 6, 14, 26};
vector<int>nlttf;
for(int n:num){
if(n<25)nlttf.push_back(n);
}
return 0;
}
Read this Range-based for Statement (C++).
For std::vector see this and this link.
Here's another option, using C++11 and the boost libraries:
#include <iostream>
#include <boost/foreach.hpp>
#include <vector>
int main(){
std::vector<int> nums {31, 46, 11, 6, 14, 26};
std::vector<int> nltff;
BOOST_FOREACH(auto n, nums) if (n < 25) nltff.push_back(n);
BOOST_FOREACH(auto n, nltff) std::cout << n << " ";
std::cout << std::endl;
return 0;
}
Output:
11 6 14