I have a vector of digits, for example {3, 6, 0, 1, 8}
I need to covert it to an integer using every digit of a vector consistently.
So the number i'll get is 36018.
Possible solution:
std::vector<int> values = {1, 3, 4, 5};
int res = 0, s = values.size();
for(int num : values) res += num * pow(10, --s);
I want to know if there is some more "elegant", or short maybe, way to do this using stl algorithms.
You could use std::accumulate
std::vector<int> values = {1, 3, 4, 5};
int result = std::accumulate(values.begin(), values.end(), 0, [](int acc, int val){
return 10 * acc + val;
});
std::cout << result << std::endl; // 1345
A regular for loop is easier to read and therefore IMO is the more elegant choice:
int num = 0;
for (int d : values) {
num = num * 10 + d;
}
With C++20-Ranges or range-v3 it can be made quite readable
#include <iostream>
#include <vector>
#include <range/v3/all.hpp>
int main() {
std::vector<int> values{1, 2, 3};
auto powers_of_10 = ranges::view::generate([n = 1]() mutable {
auto res = n;
n *= 10;
return res;
});
auto num = ranges::inner_product(powers_of_10, values | ranges::view::reverse, 0);
std::cout << num << '\n';
}
The idea here is to produce a range of powers of 10 [1, 10, 100, ...] and then to simply calculate the dot product with the reversed input vector.
It could have been even more expressive if there were a iterate_view that iteratively applies a function to a value.
Related
I am using gcc compiler on ubuntu 16 , when I am printing value garbage value is getting displayed
#include <bits/stdc++.h>
int Arrayprint(int r, int l, unsigned int* q)
{
r = 3;
l = 4;
for (int i = 0; i < r; i++) {
for (int j = 0; j < l; j++) {
cout << *(q + sizeof(unsigned int) * (i * l + j)); //Garbage getting diplay
cout << *(q + i + j); //this working
cout << "\t";
}
}
cout << "size of unsigned int : " << sizeof(unsigned int); //4
cout << "size of int : " << sizeof(int); //4
}
int main()
{
unsigned int image[R][L] = { { 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 } };
unsigned int* q = (unsigned int*)image;
Arrayprint(R, L, q);
}
From what I can tell, you understand at a low level that the address of the ith element of an array of T is base + sizeof(T) * i. That's correct, and it's good that you know that.
However, C and C++ handle this for you already. When you say q + i or q[i], it's actually compiling that into q + sizeof(T)*i anyway (with the latter also dereferencing the result).
So when you say q[sizeof(int)*i], that's actually compiling into *(q + sizeof(int)*sizeof(int)*i), which is clearly not what you wanted.
Thus, the index in the array you actually access is off by a factor of sizeof(int) and results in an out of bounds error, which is where your strange numbers are coming from.
I am using gcc compiler on ubuntu 16 , when I am printing value
garbage value is getting displayed
Instead of trying to fix what's broken in your raw array arimethics, consider using the standard containers:
#include <iostream>
#include <array>
constexpr size_t R = 3;
constexpr size_t L = 4;
using image_t = std::array<std::array<unsigned int, L>, R>;
void Arrayprint(const image_t& q) {
// range based for loops for convenience
for(auto& row : q) { // get references to each row
for(unsigned int colval : row) { // get the column values
std::cout << colval << "\t"; // print the values
}
std::cout << "\n";
}
}
int main() {
image_t image = {{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}};
Arrayprint(image);
}
Output:
1 2 3 4
5 6 7 8
9 10 11 12
I want to copy values from one vector to other one that will be stored in a specific order and the second vector will contain more elements than the first one.
For example:
vector<int> temp;
temp.push_back(2);
temp.push_back(0);
temp.push_back(1);
int size1 = temp.size();
int size2 = 4;
vector<int> temp2(size1 * size2);
And now I would like to fill temp2 like that: {2, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1}.
Is it possible to do this using only algorithms (e.g. fill)?
Yes, it is possible using std::generate_n algorithm:
int main() {
std::vector<int> base{1, 0, 2};
const int factor = 4;
std::vector<int> out{};
std::generate_n(std::back_inserter(out), base.size() * factor,
[&base, counter=0]() mutable {
return base[counter++ / factor];
});
for(const auto i : out) {
std::cout << i << ' ';
}
}
This code prints: 1 1 1 1 0 0 0 0 2 2 2 2
The key is the lambda used in std::generate_n. It operates on internal counter to know which values, based on base vector (and accessed depending on factor and counter values), to generate.
No, this is quite a specific use case, but you can trivially implement it yourself.
#include <vector>
#include <iostream>
std::vector<int> Elongate(const std::vector<int>& src, const size_t factor)
{
std::vector<int> result;
result.reserve(src.size() * factor);
for (const auto& el : src)
result.insert(result.end(), factor, el);
return result;
}
int main()
{
std::vector<int> temp{2, 0, 1};
std::vector<int> real = Elongate(temp, 4);
for (const auto& el : real)
std::cerr << el << ' ';
std::cerr << '\n';
}
(live demo)
I have a vector<int> of length n which contains only 0 and 1's. For example we can have the following vector of length 10:
0 1 1 0 1 0 0 1 0 0
Now I use the number represented by that vector to access a location in an array with 2^n entries (so in this case an array of 2^10 = 1024). I'm not sure how I can obtain one integer from the byte representation stored in this vector<int>.
Simply run through the vector and collect powers of 2.
It depends on which end of the vector you want as most significant digit but e.g.
auto to_int( const vector<int>& digits )
-> int
{
int result = 0;
for( int const digit : digits )
{
result += 2*result + digit;
}
return result;
}
Or the other way,
auto to_int( const vector<int>& digits )
-> int
{
int result = 0;
for( int i = (int)digits.size(); i --> 0; )
{
result += 2*result + digits[i];
}
return result;
}
Disclaimer: code not reviewed by compiler.
use a std::bitset (http://en.cppreference.com/w/cpp/utility/bitset) which has a to_ulong() method
Something like this:
int integer=0;
int c=0;
for(int i : intVector){
integer+=i<<c;
c++;
}
return integer;
A simply way using a for loop:
size_t val{0};
for (const auto i : vec)
val = (val << 1) + i;
You can keep the std::vector and use std::bitset:
#include <iostream>
#include <vector>
#include <bitset>
#include <algorithm>
#include <climits>
template <typename IterType>
unsigned long getValue(IterType i1, IterType i2)
{
unsigned long i = 0;
std::bitset<CHAR_BIT * sizeof(unsigned long)> b;
std::for_each(i1, i2, [&](auto n) { b.set(i++, n);});
return b.to_ulong();
}
int main()
{
std::vector<int> v = {0, 1, 1, 0, 1, 0, 0, 1, 0, 0};
auto val = getValue(v.rbegin(), v.rend());
std::cout << val << "\n";;
auto val2 = getValue(v.begin(), v.end());
std::cout << val2;
}
Note that depending on which bit is the most significant bit, you supply the iterators accordingly. For right-to-left, supply reverse iterators, otherwise supply forward iterators.
Live Example
I'm reading Accelerated C++. At the moment I'm at the end of chapter 3 and here's the exercise that I'm trying to do:
"Write a program to compute and print the quartiles of a set of integers."
I found the first and the second quartiles, but I have no idea how to find the third. Here's my code:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main(){
cout<<"Enter numbers:";
int x;
vector<int>integers;
while(cin>>x)
integers.push_back(x);
typedef vector<int>::size_type vec_sz;
vec_sz size = integers.size();
sort(integers.begin(), integers.end());
vec_sz mid = size/2;
vec_sz q1 = mid/2;
double median;
median = size % 2 == 0 ? ((double)integers[mid] + (double)integers[mid-1]) / 2
: integers[mid];
double quartOne = ((double)integers[q1] + (double)integers[q1-1])/2;
cout<<"The First Quartile is: "<<quartOne<<endl;
cout<<"The Second Quartile is: "<<median<<endl;
return 0;
}
One way would be to sort the collection and then take the 3 dividing items:
vector<int> v = ...;
sort(v.begin(), v.end());
int q12 = v[v.size()*1/4];
int q23 = v[v.size()*2/4];
int q34 = v[v.size()*3/4];
This is O(nlogn) in the number of data items.
Another way would be to perform a binary search of the data for the three divisions seperately. ie propose an initial q12, check if it is correct by making a pass of the data, if it is incorrect adjust it up or down by half, and repeat. Do likewise for q23 and q34.
This is technically O(n) because a 32-bit int has a fixed range and can be binary searched in 32 passes max.
This solutions implements the second method described in wikipedia for computing quartiles. It provides the correct values both for vectors with odd and even lengths.
#include <vector>
#include <tuple>
#include <iostream>
using namespace std;
double median(vector<double>::const_iterator begin,
vector<double>::const_iterator end) {
int len = end - begin;
auto it = begin + len / 2;
double m = *it;
if ((len % 2) == 0) m = (m + *(--it)) / 2;
return m;
}
tuple<double, double, double> quartiles(const vector<double>& v) {
auto it_second_half = v.cbegin() + v.size() / 2;
auto it_first_half = it_second_half;
if ((v.size() % 2) == 0) --it_first_half;
double q1 = median(v.begin(), it_first_half);
double q2 = median(v.begin(), v.end());
double q3 = median(it_second_half, v.end());
return make_tuple(q1, q2, q3);
}
int main() {
vector<double> v = {2, 2, 3, 4, 4, 5, 5, 10};
auto q = quartiles(v);
cout << get<0>(q) << "," << get<1>(q) << "," << get<2>(q) << endl;
return 0;
}
It is designed for real numbers, but it is easily adaptable for integer values (just round the values to their nearest integer).
With Boost's accumulators I can easily calculate statistical quantities for
weighted or unweighted input sets. I wonder if it is possible to mix weighted
and unweighted quantities inside the same accumulator. Looking at the
docs it doesn't seem that way.
This compiles fine but produces another result than I would have liked:
using namespace boost::accumulators;
const double a[] = {1, 1, 1, 1, 1, 2, 2, 2, 2};
const double w[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
accumulator_set<double, features<tag::sum, tag::weighted_sum>, double> stats;
for (size_t i=0; i<9; ++i)
stats(a[i], weight = w[i]);
std::cout << sum(stats) <<" "<< weighted_sum(stats) << std::endl;
// outputs "75 75" instead of "13 75"
Also, with a third template parameter to accumulator_set I always seems to
get weighted quantities, even when using an "unweighted" feature and extractor:
accumulator_set<double, features<tag::sum>, double> stats;
for (size_t i=0; i<9; ++i)
stats(a[i], weight = w[i]);
std::cout << sum(stats) << std::endl;
// outputs "75" instead of 13
Do I always have to use two different accumulators if I want to calculate both
weighted and unweighted quantities?
EDIT
I just use sum as an example, in reality I am interested in multiple, more complicated quantities.
It does say in the documentation that
When you specify a weight, all the
accumulators in the set are replaced
with their weighted equivalents.
There are probably better ways to do it but you can try something like this (basically swapping the meaning of the value with that of the weight):
accumulator_set< double, stats< tag::sum, tag::sum_of_weights >, double > acc;
const double a[] = {1, 1, 1, 1, 1, 2, 2, 2, 2};
const double w[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
for( int i = 0; i < sizeof( a ) / sizeof( a[ 0 ] ); i++ )
acc( w[ i ], weight = a[ i ] );
std::cout << extract_result< tag::sum >( acc ) << std::endl; // weighted sum, prints 75
std::cout << extract_result< tag::sum_of_weights >( acc ) << std::endl; // sum, prints 13