简体   繁体   中英

pushing strings into multidimensional vector c++

I am currently trying to separate a string by the number 2 and pushing the sub characters that i get into a 2d vector, the problem is that every time I try, I get a segmentation fault when I try to push the second row of characters in the vector. After trying a few things, I think the problem lies in the vector "some" after I clear the content of the vector. It seems to me that after the clearing, I am no longer able to push values into the vector. I hope that somebody has any suggestions because I am stuck.

std::string str = "11121112111";
std::vector<int> some;
std::vector<std::vector<int> > somemore;
for (unsigned int i = 0; i < str.length(); i++)
{
    if (str[i] == '2')
    {
        somemore.push_back(some);
        some.clear();
    }
    else
    {
        some.push_back(1);
    }
}
for (unsigned int i = 0; i <= 3; i++)
{
    for (unsigned int j = 0; j <= 3; j++)
    {
        std::cout << somemore[i][j] << std::endl;
    }
}

I would change the last part:

for(unsigned int i = 0; i <=3; i++)
{
   for(unsigned int j = 0; j <=3; j++)
      {
          std::cout << somemore[i][j] << std::endl;
      }
}

Into this:

for(unsigned int i = 0; i < somemore.size(); i++)
{
   for(unsigned int j = 0; j < some.size(); j++)
      {
          std::cout << somemore[i][j] << std::endl;
      }
}

It is much safer.

In this loop

for(unsigned int i = 0; i < str.length(); i++)
{ 
  if(str[i] == '2')
  {
      sommore.push_back(som);
      som.clear();
  }
  else
  {
      som.push_back(1);
  }
}

where it is not clear whether som is the vector declared like

std::vector<int> some;
                 ^^^^^

the last part of the string

std::string str = "11121112111";
                           ^^^

is ignored by vector sommore . So the vector contains only two elements that corresponds to two 2(s) in the string.

As result these loops

   for(unsigned int i = 0; i <=3; i++)
   {
       for(unsigned int j = 0; j <=3; j++)
       {
           std::cout << sommore[i][j] << std::endl;
       }
   }

that use the magic number 3 have undefined behaviour.

Even if the vector and its sub-vectors contain 3 elements even in this case conditions i <=3 and j <=3 are wrong.

You can adopt the following approach shown in this demonstratrive program

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

int main()
{
    std::vector<std::vector<int>> v;
    std::string str = "11121112111";

    for ( std::string::size_type pos = 0; ( pos = str.find_first_not_of( "2", pos ) ) != std::string::npos; )
    {
        auto n = str.find( "2", pos );
        if ( n == std::string::npos ) n = str.size();
        v.push_back( std::vector<int>( n - pos, 1 ) );
        pos = n;
    }

    for ( const auto &row : v )
    {
        for ( int x : row ) std::cout << x;
        std::cout << std::endl;
    }        

}    

The program output is

111
111
111

With c++11 and Boost you can make a much more elegant solution, without the need for loops with an incrementing index.

#include <vector>
#include <string>
#include <iostream>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

int main()
{ 
    std::string str = "11121112111";
    std::vector<std::string> string_vector;
    boost::split(string_vector, str, boost::is_any_of("2"));

    std::vector<std::vector<int>> int_vector;

    for (auto& s : string_vector)
        int_vector.push_back(std::vector<int>(s.size(), 1));

    for (auto& v : int_vector)
        for (auto& i : v)
            std::cout << i << std::endl;

    return 0;
}

As I already mentioned in comments, you have two problems in your code:

  1. You are not pushing the last some into somemore because there is no 2 at the end of str .
  2. Your last loops are too large - You have a 3x3 matrix but you expect a 4x4 since you go from 0 to 3.

By the way, since you are only counting ones, you don't need some :

std::string str = "11121112111";
std::vector<std::vector<int>> somemore;
size_t count = 0;
for (size_t = 0; i < str.length(); i++) {
    if (str[i] == '2') {
        somemore.push_back(std::vector<int>(count, 1));
        count = 0;
    }
    else {
        ++count;
    }
}
for (size_t i = 0; i < somemore.size(); ++i) {
    for (size_t j = 0; j < somemore[i].size(); ++j) {
        std::cout << somemore[i][j] << std::endl;
    }
}

You could also replace the last two loops with iterators, or if you have c++11 available:

for (const auto &s: somemore) {
    for (const auto &v: s) {
        std::cout << v << std::endl;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM