How can I erase all items from a vector? C++ - c++

I am just trying to make all my elements 0 without doing it manually with
for (i = 1; i <= n; i++)
v[i] = 0;
I found online that i can use this command: v.clear(); but it doesn't work:
error: request for member 'clear' in 'v', which is of non-class type 'int [101]'
Here's my code:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n,i,v[101];
int main() {
cin>>n;
for(i=1;i<=n;i++)
cin>>v[i];
v.clear();
for(i=1;i<=n;i++)
cout<<v[i]<<" ";
return 0;
}

We have std::fill, that can be used with C-style arrays, too:
std::fill(std::begin(v), std::end(v), 0);

You have an array. Arrays in C++ do not have methods. What you need is to call the standard C function memset.
For example
#include <cstring>
//...
std::memset( v, 0, n * sizeof( int ) );
Also indices for arrays in C++ start from 0. So use for loops like
for( i = 0; i < n; i++ )

Maybe, you can use std::array , it can also specify the size like int v[101] .
Then, you can use v = {0} to make make all my elements 0.
For example:
#include <iostream>
#include <array>
using namespace std;
int main() {
array<int, 101> v;
for (auto &elem : v)
cin >> elem;
v = {0};
for (auto elem : v)
cout << elem << " ";
}
If you don't like std::array, you can also do like the following.
int v[5] = {1, 2, 3, 4, 5};
int *p = v;
while (*p++ = 0, *p != 0) { };
In fact, I think that std::fill(std::begin(v), std::end(v), 0); that user Evg answered is best.

Related

C++ How to sum only even values stored in vector?

I am new to C++, and I have run into a total lack of understanding on how to sum only even values stored in a vector in C++.
The task itself requests a user to input some amount of random integers, stop when input is 0, and then to return the amount of even values and the sum of those even values.
This is as far as I have managed to get:
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main()
{
vector<int> vet;
int s = 1;
while (s != 0) {
std::cin >> s;
vet.push_back(s);
}
int n = count_if(vet.begin(), vet.end(),
[](int n) { return (n % 2) == 0; });
cout << n << endl;
//here is the start of my problems and lack of undertanding. Basically bad improv from previous method
int m = accumulate(vet.begin(), vet.end(), 0,
[](int m) { for (auto m : vet) {
return (m % 2) == 0; });
cout << m << endl; //would love to see the sum of even values here
return 0;
}
The function to be passed to std::accumulate takes 2 values: current accumulation value and value of current element.
What you should do is add the value if it is even and make no change when not.
int m = accumulate(vet.begin(), vet.end(), 0,
[](int cur, int m) {
if ((m % 2) == 0) {
return cur + m; // add this element
} else {
return cur; // make no change
}
});
From c++20, you can separate out the logic that checks for even numbers, and the logic for summing up those values:
auto is_even = [](int i) { return i % 2 == 0; };
auto evens = vet | std::views::filter(is_even);
auto sum = std::accumulate(std::begin(evens), std::end(evens), 0);
Here's a demo.
This is my solution(sorry if it's not right I'm writing it on my phone)
You don't need a vector form this, you just need to check right from the input if the number is divisible to 2
My solution:(a littie bit ugly)
#include <iostream>
using namespace std;
int main()
{
int s {1};
int sum{};
int countNum{};
while (s != 0)
{
cin >> s;
if (s % 2 == 0)
{
sum += s;
countNum++;
}
}
cout << countNum << ' ' << sum;
}
i don't realy know what you want to do in the second part of your code but you can sum the even numbers by this way and i want to told you another thing when you using namespace std you don't need to write std::cin you can only write cin directly
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vet;
int s = 1;
//Take Input
while (s != 0) {
cin >> s;
vet.push_back(s);
}
//count elements
int elements_count = vet.size(); //vet.size() return the total number of elements of vector
//store the sum here
int sum=0;
//loop on the vector and sum only even numbers
for(int i=0;i<elements_count;i++){
if(vet[i] %2 ==0)
sum += vet[i];//check of the element of index i in the vector is even if it true it will add to sum
}
cout << sum;
return 0;
}
int sumEven=0;
int v[100];
int n;//number of elements you want to enter in the array
do{cout<<"Enter n";
cin>>n;}while(n<=0);
//in a normal 1 dimensional array
for(int i=0;i<n;i++)
if(v[i]%2==0)
sumEven+=v[i];
//in a vector
vector<int> v;
for(vector<int>::iterator it=v.begin();it!=v.end();it++)
if(*it%2==0)
sumEven+=v[i];
Similar to answers above, but if you want to keep the vector of even numbers as well, here are two approaches.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<int> vec = {1,2,3,4,5,6,7,8,9,10};
// Hold onto what we know is the right answer.
int known_sum = 2+4+6+8+10;
// Copy only even values into another vector
std::vector<int> even_values;
std::copy_if(vec.begin(), vec.end(),
std::back_inserter(even_values),
[](int val){ return val%2==0; });
// Compute sum from even values vector
int even_value_sum = std::accumulate(even_values.begin(), even_values.end(), 0);
// Compute sum from original vector
int even_value_second = std::accumulate(vec.begin(), vec.end(), 0,
[](int current_sum, int new_value) {
return new_value%2==0 ? current_sum + new_value:current_sum;
}
);
// These should all be the same.
std::cout << "Sum from only even vector: " << even_value_sum << std::endl;
std::cout << "Sum from binary op in std accumulate: " << even_value_second << std::endl;
std::cout << "Known Sum: " << known_sum << std::endl;
}
Range-based for loops
A range-based for loop is arguably always a valid alternative to the STL algos, particularly in cases where the operators for the algos are non-trivial.
In C++14 and C++17
E.g. wrapping a range-based even-only accumulating for loop in an immediately-executed mutable lambda:
#include <iostream>
#include <vector>
int main() {
// C++17: omit <int> and rely on CTAD.
const std::vector<int> v{1, 10, 2, 7, 4, 5, 8, 13, 18, 19};
const auto sum_of_even_values = [sum = 0, &v]() mutable {
for (auto val : v) {
if (val % 2 == 0) { sum += val; }
}
return sum;
}();
std::cout << sum_of_even_values; // 42
}
In C++20
As of C++20, you may use initialization statements in the range-based for loops, as well as the ranges library, allowing you to declare a binary comparator in the initialization statement of the range-based for loop, and subsequently apply it the range-expression of the loop, together with the std::ranges::filter_view adaptor:
#include <iostream>
#include <vector>
#include <ranges>
int main() {
const std::vector v{1, 10, 2, 7, 4, 5, 8, 13, 18, 19};
const auto sum_of_even_values = [sum = 0, &v]() mutable {
for (auto is_even = [](int i) { return i % 2 == 0; };
auto val : v | std::ranges::views::filter(is_even)) {
sum += val;
}
return sum;
}();
std::cout << sum_of_even_values; // 42
}

Converting from a std::vector<int> to a char[] C++

If I have an integer vector (std::vector) is there an easy way to convert everything in that vector to a char array(char[]) so (1,2,3) -> ('1','2','3')
This is what I have tried, but it doesn't work:
std::vector<int> v;
for(int i = 1; i < 10; i++){
v.push_back(i);
}
char *a = &v[0];
std::transform is the right tool for the job :
std::vector<int> iv {1, 2, 3, 4, 5, 6};
char ca[10] {};
using std::begin;
using std::end;
std::transform(begin(iv), end(iv), begin(ca), [](int i) { return '0' + i; });
If you don't need ca to be a C-style array, I'd recommend using std::array or std::vector instead. The latter needs std::back_inserter(ca) in place of begin(ca).
It can be as simple as this
std::vector<int> v { 1, 2, 3 };
std::vector<char> c;
for( int i : v ) c.push_back( '0' + i );
to realize why your way does not work you need to learn how integers and symbls represented on your platform.
Why not store it in char vector initially?
std::vector<char> v;
for(int i = 1; i < 10; i++){
v.push_back(i + '0');
}
Trick from: https://stackoverflow.com/a/2279401/47351
You can use std::transform with std::back_inserter, maybe something like this:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> vI{0,1,2,3,4,5,6,7,8,9};
std::vector<char> vC;
std::transform(vI.begin(), vI.end(), std::back_inserter(vC), [](const int &i){ return '0'+i; });
for(const auto &i: vC)
{
std::cout << i << std::endl;
}
return 0;
}
If you've already got the numbers in a vector then you can use std::transform and a back_inserter:
std::vector<int> v;
std::vector<char> c;
std::transform(v.begin(), v.end(), std::back_inserter(c), [](int i){return '0' + i;});
However, why not just say:
std::vector<char> v;
for(char i = '0'; i < '9'; i++)
{
v.push_back(i);
}

Switching data from array to vector

I'm trying to convert my array to a vector, yet I'm having trouble printing it.
It says in int main() in my for loop that v is undefined. When I define
vector v; inside int main() the program compiles and runs and yet prints nothing. What am I doing wrong?
#include <iostream>
#include <vector>
using namespace std;
vector<int> a2v(int x[], int n)
{
vector<int> v(n);
for(int i = 0; i < n; i++)
{
v.push_back(x[i]);
}
return(v);
}
int main()
{
vector<int> a2v(int x[], int n);
int array[] = {11,12,13,14,15,16,17,18};
a2v(array, 8);
for(int i = 0; i < v.size(); i++)
{
cout << v[i] <<" ";
}
cout << endl;
return(0);
}
This is your program corrected:
#include <iostream>
#include <vector>
using namespace std;
vector<int> a2v(int x[], int n)
{
vector<int> v(0);
v.reserve(n); //optional
for(int i = 0; i < n; i++)
{
v.push_back(x[i]);
}
return(v);
}
int main()
{
int array[] = {11,12,13,14,15,16,17,18};
auto v = a2v(array, 8);
for(size_t i = 0; i < v.size(); i++)
{
cout << v[i] <<" ";
}
cout << endl;
return(0);
}
There were 2 errors:
In the function a2v, you instantiated a vector of 0 with length n, and then you pushed back other elements;
You were not defining v inside the main, as the return value of a2v
The vector you want to read is the return of the a2v function.
But there is a lot more simpler than that to go from C-array to vector array , I put here the example in found the vector reference web page :
http://www.cplusplus.com/reference/vector/vector/vector/
int myints[] = {16,2,77,29};
std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
When you define a variable, such as your vector v, you always do it in a certain scope. The body of a function such as a2v, or main, is an example of a possible scope. So if you only do it in the function a2v, that's the only scope where it will be visible.
It says in int main() in my for loop that v is undefined.
Well it will be because there is no v in main()
a2v(array, 8);
The above function call returns a vector so you need to collect the returned vector like
vector<int> v=a2v(array,8)
Also,
vector<int> v(n);//creates a vector of size n
for(int i = 0; i < n; i++)
{
v.push_back(x[i]);//adds n more elements to the vector
}
The returned vector has 2n elements and not n
Finally you could directly create a vector from an array as
vector<int> v(arr,arr+n);//where n is the number of elements in arr

Remove all elements from array greater than n

I'm beginner in programming. Something is giving me trouble to code. Suppose, I've an array.
int Array[] = {3,6,9,5,10,21,3,25,14,12,32,41,3,24,15,26,7,8,11,4};
I want to remove all elements which are greater than 9. How can I do this?
You can do this if you use vector. First initialize vector with your array. Then use remove_if() function. Hope this will help.
#include <algorithm>
#include <vector>
int main()
{
int Array[] = {3,6,9,5,10,21,3,25,14,12,32,41,3,24,15,26,7,8,11,4};
vector<int> V(Array, Array+20);
vector<int> :: iterator it;
it = remove_if(V.begin(), V.end(), bind2nd(greater<int>(), 9));
V.erase (it, V.end()); // This is your required vector if you wish to use vector
}
You cannot remove items from an array, since they are fixed in size.
If you used std::vector, then the solution would look like this:
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
std::vector<int> Array = {3,6,9,5,10,21,3,25,14,12,32,41,3,24,15,26,7,8,11,4};
Array.erase(remove_if(Array.begin(), Array.end(), [](int n) { return n > 9; }),
Array.end());
copy(Array.begin(), Array.end(), ostream_iterator<int>(cout, " "));
}
Live example: http://ideone.com/UjdJ5h
If you want to stick with your array, but mark the items that are greater than 10, you can use the same algorithm std::remove_if.
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
int Array[] = {3,6,9,5,10,21,3,25,14,12,32,41,3,24,15,26,7,8,11,4};
int *overwrite_start = remove_if(std::begin(Array), std::end(Array), [](int n){ return n>9; });
fill(overwrite_start, std::end(Array), -1);
copy(std::begin(Array), std::end(Array), ostream_iterator<int>(cout, " "));
}
The above will move the "erased" items to the end of the array, and mark them with -1.
Live example: http://ideone.com/7rwaXy
Note the usage in both examples of the STL algorithm functions. The second example with the array uses the same remove_if algorithm function. The remove_if returns the start of the "erased" data, as remove_if doesn't actually remove, but moves the data to the end of the sequence.
i am try swap concept without using vector
int Array[] = {3,6,9,5,10,21,3,25,14,12,32,41,3,24,15,26,7,8,11,4};
int n;
int arr_len = sizeof(Array)/sizeof(int);
void print_array_value() {
int i;
cout << "\n";
for (i = 0; i < arr_len; i++) {
cout << Array[i] << ", ";
}
cout << " : " << arr_len << "\n";
}
void swap_array_value(int start) {
int i;
for ( ; (start+1) < arr_len; start++) {
Array[start] = Array[start+1];
}
}
void remove_array_value() {
int i;
for (i = 0; i < arr_len; i++) {
if (Array[i] > n) {
swap_array_value(i);
arr_len--;
i--;
}
}
}
void main () {
clrscr();
cout << "Enter the N value : ";
cin >> n;
print_array_value();
remove_array_value();
print_array_value();
cout << "Array Length : " << arr_len;
getch();
}

Creating a new C++ subvector?

Say I have a vector with values [1,2,3,4,5,6,7,8,9,10]. I want to create a new vector that refers to, for example, [5,6,7,8]. I imagine this is just a matter of creating a vector with pointers or do I have to push_back all the intermediary values I need?
One of std::vector's constructor accepts a range:
std::vector<int> v;
// Populate v.
for (int i = 1; i <= 10; i++) v.push_back(i);
// Construct v1 from subrange in v.
std::vector<int> v1(v.begin() + 4, v.end() - 2);
This is fairly easy to do with std::valarray instead of a vector:
#include <valarray>
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
const std::valarray<int> arr={0,1,2,3,4,5,6,7,8,9,10};
const std::valarray<int>& slice = arr[std::slice(5, // start pos
4, // size
1 // stride
)];
}
Which takes a "slice" of the valarray, more generically than a vector.
For a vector you can do it with the constructor that takes two iterators though:
const std::vector<int> arr={0,1,2,3,4,5,6,7,8,9,10};
std::vector<int> slice(arr.begin()+5, arr.begin()+9);
You don't have to use push_back if you don't want to, you can use std::copy:
std::vector<int> subvector;
copy ( v1.begin() + 4, v1.begin() + 8, std::back_inserter(subvector) );
I would do the following:
#include <vector>
#include <iostream>
using namespace std;
void printvec(vector<int>& v){
for(int i = 0;i < v.size();i++){
cout << v[i] << " ";
}
cout << endl;
}
int main(){
vector<int> v;
for(int i = 1;i <= 10;i++) v.push_back(i);
printvec(v);
vector<int> v2(v.begin()+4, v.end()-2);
printvec(v2);
return 0;
}
~