0

I have a string that looks like this:

"{{2,3},{10,1},9}" 

and I want to convert it to an array (or vector) of strings:

["{", "{", "2", "}", ",", "{", "10", ",", "1", "}", ",", "9", "}"]

I can't just pull out each character separately because some of the integers may be double-digit, and I can't figure out how to use stringstream because there are multiple delimiters on the integers (could be followed by , or })

JMLdev
  • 846
  • 2
  • 10
  • 21

3 Answers3

3

Just walk through the string. If we're on a digit, walk 'til we're not on a digit:

std::vector<std::string> split(std::string const& s)
{
    std::vector<std::string> results;
    std::locale loc{};

    for (auto it = s.begin(); it != s.end(); )
    {
        if (std::isdigit(*it, loc)) {
            auto next = std::find_if(it+1, s.end(), [&](char c){
                return !std::isdigit(c, loc);
            });
            results.emplace_back(it, next);
            it = next;
        }
        else {
            results.emplace_back(1, *it);
            ++it;
        }
    }

    return results;
}
Barry
  • 286,269
  • 29
  • 621
  • 977
0

The logic is straightforward:

  1. Iterate over the string.

  2. push_back() each character as a string of its own into the output vector, unless it's a digit and the last character was a digit, in which case append the digit to the last string in the output vector:

That's it.

std::string s="{{2,3},{10,1},9}";

std::vector<std::string> v;

bool last_character_was_a_digit=false;

for (auto c:s)
{
    if ( c >= '0' && c <= '9')
    {
        if (last_character_was_a_digit)
        {
            v.back().push_back(c);
            continue;
        }
        last_character_was_a_digit=true;
    }
    else
    {
        last_character_was_a_digit=false;
    }
    v.push_back(std::string(&c, 1));
}
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
-1

Thank you Sam and Barry for answering! I actually came up with my own solution (sometimes posting a question here helps me see things more clearly) but yours are much more elegant and delimiter-independent, I'll study them further!

std::vector<std::string> myVector;
std::string nextSubStr;
for (int i=0; i<myString.size(); i++)
{
    nextSubStr = myString[i];

    // if we pulled a single-digit integer out of myString
    if (nextSubStr != "{" && nextSubStr != "}" && nextSubStr != ",")
    {
        // let's make sure we get the whole integer!
        int j=i;
        peekNext = myString[++j];
        while (peekNext != "{" && peekNext != "}" && peekNext != ",")
        {
            // another digit on the integer
            nextSubStr += peekNext;
            peekNext = myString[++j];
            i++;
        }            
    }

    myVector.push_back(nextSubStr);
}
JMLdev
  • 846
  • 2
  • 10
  • 21