0

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.

  • 2
    This is about as good as you can ask for. You could use `for_each` and lambda instead of a for loop but it doesn't gain you anything and would require more typing. – NathanOliver Jul 18 '19 at 19:53
  • 4
    Get rid of `pow()`. That's definitely more "elegant". `pow()` is ugly. It does; 1) convert int to double, 2) make a bunch of logarithmic calculations, 3) convert doubles back to ints. Why do you want to do this, when simple multiplication and division is sufficient? As shown, the multiplication also does a conversion to double, on `num`, perform a multiplication as a double, then convert back to int, for the `+=` operator. Not good. – Sam Varshavchik Jul 18 '19 at 19:58
  • [Do not use `pow` for integer exponents](https://stackoverflow.com/questions/25678481/why-does-pown-2-return-24-when-n-5-with-my-compiler-and-os) – PaulMcKenzie Jul 18 '19 at 22:29

3 Answers3

4

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
Zereges
  • 5,139
  • 1
  • 25
  • 49
4

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;
}
David G
  • 94,763
  • 41
  • 167
  • 253
0

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.

sv90
  • 522
  • 5
  • 11