1

Suppose I have a string containing 00101 and I need to convert it to a vector containing each single digit as an element, like vector<int> num{0,0,1,0,1}.

I looked up many solutions but the numbers in the string were space-separated.

janekb04
  • 4,304
  • 2
  • 20
  • 51
Shreyas
  • 36
  • 1
  • 6
  • The question is really broad. What should `std::vector` contain? The digits as individual `char`, as `int` , …? If it should be `char` why do you need a `std::vector`, a `std::string` is already a container. – t.niese Sep 03 '21 at 14:34

3 Answers3

4

You can easily do this by initializing a new vector with an iterator pair like this:

std::string s = "2345676543456789"; // for example

std::vector<int> nums {s.begin(), s.end()};
for (auto&& num : nums)
    num -= '0';

If you now print the vector, like this:

for (const auto& n : nums) 
     std::cout << n << ' ';

it will contain all of the digits:

2 3 4 5 6 7 6 5 4 3 4 5 6 7 8 9 

Working demo link.

Note that this breaks if the source string (s in this case) isn't composed only of digits. This is because this solution is based on the fact that in ASCII, digits are encoded with consecutive values.

janekb04
  • 4,304
  • 2
  • 20
  • 51
1

It may not be the best solution...but a solution nonetheless, please feel free to reply and improve my code:

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
    vector<int> v;
    string s = "101010";
    
    for(char c : s)
    {
        v.push_back(((int)c - 48));
    }
    
    for(int i = 0; i < v.size(); i++)
    {
        cout << v.at(i) << endl;
    }
    return 0;
}

The cout at the end isn't essential, just to see that the vector truly holds all the needed values.

As for the - 48 while pushing to the vector is because number chars in the ASCII table are denoted from the number 48 onwards, so to subtract the numerical values, we get the originally needed int. EDIT: Instead of subtracting from the typecast, we can also use the notation:

for(char c : s)
    {
        v.push_back(c - '0');
    }

which performs exactly the same thing but in a more readable way. This will bring a bit more clarity into why this is.

iyers16
  • 30
  • 6
  • 1
    Subtracting `'0'` is better than using the 'magic' number of `48`. – Adrian Mole Sep 03 '21 at 14:51
  • 1
    Recommendation: use `'0'` instead of 48. What the `'0'` is doing is immediately obvious to anyone modestly familiar with C++ (And won't need a paragraph explaining) and is portable to the rare systems that don't use ASCII. – user4581301 Sep 03 '21 at 14:52
  • You should not suggest to use `using namespace std;` this leads to various problems. – t.niese Sep 03 '21 at 15:25
  • 1
    A link just in case: https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice . – janekb04 Sep 03 '21 at 15:29
1

You can use std::transform and and std::back_inserter.

c - '0' converts textual representation number to its value.

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

int main() {
  std::string s = "00101";

  std::vector<unsigned short> digits;
  std::transform(s.begin(), s.end(), std::back_inserter(digits),
                 [](const auto &c) { return c - '0'; });

  for (const auto &digit : digits) {
    std::cout << digit << std::endl;
  }

  return 0;
}

You could also get rid of back_inserter by initializing the std::vector with a set of elements.

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

int main() {
  std::string s = "00101";

  std::vector<unsigned short> digits(s.size());
  std::transform(s.begin(), s.end(), digits.begin(),
                 [](const auto &c) { return c - '0'; });

  for (const auto &digit : digits) {
    std::cout << digit << std::endl;
  }

  return 0;
}
t.niese
  • 39,256
  • 9
  • 74
  • 101