Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
shuric
0 / 0 / 0
Регистрация: 04.08.2015
Сообщений: 5
1

Разбиение строки на подстроки

17.08.2015, 16:59. Просмотров 1474. Ответов 16
Метки нет (Все метки)

Есть строка "abc какой-либо текст любого размера qwerty какой-либо текст любого размера qazws какой-либо текст любого размера", где abc, qwerty и qazws являются началом подстроки, при этом abc, qwerty и qazws могут стоять в строке в любом порядке... Как нибудь возможно разбить такую строку?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.08.2015, 16:59
Ответы с готовыми решениями:

Разбиение строки
Доброго времени суток. Я новичок в кодинге. Передо мной такая задача: есть...

Разбиение строки на слова
Задача: Дана строка, например, "Hello Hello World", я ввожу слово, которое...

Разбиение символьной строки
Необходимо открыть существующий файл с расширением ".txt" и в данном файле...

Разбиение строки на слова
записываем слова через токен в массив))) не работает if который сразу после...

Разбиение строки на слова
Здравствуйте! При изучении С++ у меня возникла потребность в изучении...

16
fahtom
1 / 1 / 1
Регистрация: 13.08.2015
Сообщений: 15
17.08.2015, 17:02 2
С помощью метода split можно создать массив разделителей, и дальше уже использовать.
0
nmcf
6274 / 5577 / 2537
Регистрация: 14.04.2014
Сообщений: 23,468
17.08.2015, 17:08 3
В каком классе этот split? В стандартных такого нет.
0
fahtom
1 / 1 / 1
Регистрация: 13.08.2015
Сообщений: 15
17.08.2015, 17:11 4
Извините, я что-то не посмотрел, что речь о C++
0
shuric
0 / 0 / 0
Регистрация: 04.08.2015
Сообщений: 5
17.08.2015, 17:33  [ТС] 5
Да это c++)))

Добавлено через 2 минуты
Пока что на уме есть такой вариант:"Выполнить поиск ключевых слов, создать массив чисел( где будут например хранится номера вступления слов, упорядочить их), а дальше исходя из чисел массива резать строку"
0
fahtom
1 / 1 / 1
Регистрация: 13.08.2015
Сообщений: 15
17.08.2015, 17:35 6
Можно также сделать массив слов разделителей, проверять строку на совпадения, если совпадает, то отсекать
0
shuric
0 / 0 / 0
Регистрация: 04.08.2015
Сообщений: 5
17.08.2015, 17:48  [ТС] 7
Есть одна проблема в этом случае, если пользоваться rfind и разделитель qwerty будет первым в списке поиска, и отсекать до конца строки, то например в строке, которую я написал, отсечется вместе с разделителем qazws
0
gazlan
3140 / 1916 / 311
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
17.08.2015, 19:08 8
Цитата Сообщение от shuric Посмотреть сообщение
Как-нибудь
Множественным точным поиском, например AC automaton. Задаем паттерны (подстроки), отыскиваем позиции их вхожения в тест. Порядок неважен. Так работает любой сигнатурный анализатор (те же AV могут проверять до полумиллиона паттернов).

Aho–Corasick algorithm
0
Mr.X
Эксперт С++
3178 / 1705 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
17.08.2015, 19:28 9
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
#include <string>
#include <vector>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string                     T_str;
typedef std::vector     < T_str     >   T_strings;
typedef T_str::size_type                T_pos;
typedef std::set        < T_pos     >   T_positions;
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    T_strings     heads;
    heads.push_back( "lala" );
    heads.push_back( "bubu" );
    heads.push_back( "fafa" );
 
    T_str   s("1111bubu22222222fafa33333lala44444444444");
 
    std::cout   <<  s
                <<  std::endl;
 
    T_positions     head_positions;
 
    std::transform
        (
            heads.begin     (),
            heads.end       (),
 
            std::inserter
                (
                    head_positions,
                    head_positions.begin()
                ),
 
            [=]  ( T_str    const   &   substr )->T_pos
            {
                return  s.find( substr );
            }
        );
 
    T_strings   substrings;
 
    std::transform
        (
            head_positions.rbegin   (),
            head_positions.rend     (),
            std::back_inserter      ( substrings ),
 
            [&]                     ( T_pos     pos )->T_str
            {
                auto    substr  =   s.substr( pos );
                s.erase( pos );
                return  substr;
            }
        );
 
    std::copy
        (
            substrings.begin                (),
            substrings.end                  (),
            std::ostream_iterator<T_str>    ( std::cout, "\n" )
        );
 
    std::cout   <<  std::endl;
    system("pause");
}
2
Avazart
Эксперт С++
7722 / 5631 / 549
Регистрация: 10.12.2010
Сообщений: 25,397
Записей в блоге: 17
17.08.2015, 19:39 10
Цитата Сообщение от nmcf Посмотреть сообщение
В каком классе этот split? В стандартных такого нет.
http://avazart.zz.mu/2014/02/splitstrings/
0
nmcf
6274 / 5577 / 2537
Регистрация: 14.04.2014
Сообщений: 23,468
17.08.2015, 20:27 11
boost - отдельная вещь.
0
Ilot
Эксперт С++
1831 / 1189 / 342
Регистрация: 16.05.2013
Сообщений: 3,139
Записей в блоге: 5
Завершенные тесты: 1
18.08.2015, 07:41 12
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <regex>
#include <string>
#include <iostream>
 
int main()
{
    system("chcp 1251");
    std::regex reg("(abc|qwerty|qazws)");
    std::string str = "abc какой-либо текст любого размера qwerty какой-либо текст любого размера qazws какой-либо текст любого размера";
    std::regex_token_iterator<std::string::iterator> iter(str.begin(), str.end(), reg, -1);
    std::regex_token_iterator<std::string::iterator> end;
    for(; iter != end; ++iter)
        std::cout << iter->str() << std::endl;
    return 0;
}
3
shuric
0 / 0 / 0
Регистрация: 04.08.2015
Сообщений: 5
18.08.2015, 11:54  [ТС] 13
Решил таким способом
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
vector<string> razdelenie_temp(string *l)
{
    int e;
   vector<int> q;
   vector<string> o;
 
   
     
    
      if((e=l->find("FM"))!=l->npos) q.push_back(e);
      if((e=l->find("TEMPO"))!=l->npos) q.push_back(e);
      if((e=l->find("BECMG"))!=l->npos) q.push_back(e);
      if((e=l->find("PROB"))!=l->npos) q.push_back(e);
   
   for(int i=0;i<q.size();i++)
       for(int j=i+1;j<q.size();j++)
   
       if(q[j]>q[i]) swap(q[i],q[j]);
      
   
   for (int i = 0; i < q.size(); i++)
    {
             o.push_back(l->substr(q[i]));
             l->erase(l->begin()+q[i],l->end()); 
 
    }
   return o;
}
где FM, PROB, TEMPO, BECMG разделяющие слова в строке

Добавлено через 11 минут
Один косяк, если в строке появляются две подстроки с одинаковыми разделяющими словами, строка режется не правильно
0
Avazart
Эксперт С++
7722 / 5631 / 549
Регистрация: 10.12.2010
Сообщений: 25,397
Записей в блоге: 17
18.08.2015, 13:19 14
Диггинс К. "C++ сборник рецептов" - 2007 стр 176
0
Mr.X
Эксперт С++
3178 / 1705 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
18.08.2015, 14:35 15
Цитата Сообщение от shuric Посмотреть сообщение
Один косяк, если в строке появляются две подстроки с одинаковыми разделяющими словами, строка режется не правильно
Вот такую строку обрабатывает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
#include <string>
#include <vector>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string                     T_str;
typedef std::vector     < T_str     >   T_strings;
typedef T_str::size_type                T_pos;
typedef std::set        < T_pos     >   T_positions;
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    T_strings     heads;
    heads.push_back( "lala" );
    heads.push_back( "bubu" );
    heads.push_back( "fafa" );
 
    T_str   s   (
                    "1111"
                    "bubu22222222"
                    "fafa33333"
                    "lala44444444444"
                    "fafa5555555555"
                    "lala6666666666"
                    "bubu77777777777"
                );
 
    std::cout   <<  s
                <<  std::endl;
 
    T_positions     head_positions;
 
    std::for_each
        (
            heads.begin     (),
            heads.end       (),
            [&]             ( T_str     const   &   head )
            {
                T_pos   pos     =   0;
 
                while   (
                                (
                                    pos     =   s.find( head, pos )
                                )
 
                            !=  T_str::npos
                        )
                {
                    head_positions.insert( pos++ );
                }
            }
        );
 
    T_strings   substrings;
 
    std::transform
        (
            head_positions.rbegin   (),
            head_positions.rend     (),
            std::back_inserter      ( substrings ),
 
            [&]                     ( T_pos     pos )->T_str
            {
                auto    substr  =   s.substr( pos );
                s.erase( pos );
                return  substr;
            }
        );
 
    std::copy
        (
            substrings.begin                (),
            substrings.end                  (),
            std::ostream_iterator<T_str>    ( std::cout, "\n" )
        );
 
    std::cout   <<  std::endl;
    system("pause");
}
1
shuric
0 / 0 / 0
Регистрация: 04.08.2015
Сообщений: 5
18.08.2015, 17:41  [ТС] 16
Спасибо за помощь, последние ответы посмотрел только тогда, когда сам уже решил))
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
vector<string> razdelenie_temp(string *l)
{
    int e=0;
    vector<int> q;
    vector<string> o;
 
 
 
 while ((e = l->find("FM",e)) != l->npos)
    if (l->find("FM",e) != l->npos) {
        q.push_back(e);
        e=e+1;
    }
    e=0;
     while ((e = l->find("TEMPO",e)) != l->npos)
    if (l->find("TEMPO",e) != l->npos) {
        q.push_back(e);
        e=e+1;
    } 
    e=0;
    while ((e = l->find("PROB",e)) != l->npos)
    if (l->find("PROB",e) != l->npos) {
        q.push_back(e);
        e=e+1;
    } 
    e=0;
    while ((e = l->find("BECMG",e)) != l->npos)
    if (l->find("BECMG",e) != l->npos) {
        q.push_back(e);
        e=e+1;
    }
 
//    for (int i = 0; i < q.size(); i++)
//        for (int j = i + 1; j < q.size(); j++)
//            if (q[j] > q[i]) swap(q[i], q[j]);
    sort(q.begin(),q.end(),greater<int>());
 
        
    for (int i = 0; i < q.size(); i++)
    {
        o.push_back(l->substr(q[i]));
        l->erase(l->begin() + q[i], l->end());
 
    }
    return o;
}
Добавлено через 2 минуты
В вектор "о" записываются все подстроки, в векторе "l" остаётся все что предшествовало разделяющим словам
0
Avazart
Эксперт С++
7722 / 5631 / 549
Регистрация: 10.12.2010
Сообщений: 25,397
Записей в блоге: 17
18.08.2015, 18:43 17
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <string>
#include <iterator>
 
template <typename SizeT>
class Place
{
  public:
   Place(SizeT pos,SizeT length):pos_(pos),length_(length){}
   SizeT pos()const{ return pos_; }
   SizeT length()const{ return length_; }
 
   bool operator<(const Place<SizeT>& place)const
   {
     return pos_  < place.pos_ ||
            (pos_ ==place.pos_ && length_ > place.length_);
   }
 
   bool operator==(const Place<SizeT>& place)const
   {
     return pos_==place.pos_;
   }
 
  private:
   SizeT pos_;
   SizeT length_;
};
 
 
template<typename String,
         template<typename T,typename A> class SplitterConteiner,
         template<typename T,typename A> class ResultConteiner
         >
void split(const String& str,
           const SplitterConteiner<String,std::allocator<String>>& splitters,
           ResultConteiner<String,std::allocator<String>>& strings,
           bool includeEmpty= false)
{
  typedef String::size_type size_type;
  std::vector< Place<size_type> > places;
 
  for(size_type i=0; i<splitters.size(); ++i)
  {
    for(size_type start=0; ; )
    {
      size_type pos= str.find(splitters[i],start);
      if(pos!=String::npos)
      {
        places.push_back(Place<size_type>(pos,splitters[i].size()));
        start= pos+splitters[i].size();
      }
      else
        break;
    }
  }
 
  std::sort(places.begin(),places.end());
  places.erase(std::unique(places.begin(),places.end()),
               places.end() );
 
 
  size_type start=0;
  for(size_type i=0; i<places.size(); ++i)
  {
    if(includeEmpty || start<places[i].pos())
       strings.push_back(str.substr(start,places[i].pos()-start));
    start= places[i].pos()+places[i].length();
  }
 
  if(includeEmpty || start<str.size())
     strings.push_back(str.substr(start));
}
 
int main()
{
  std::wstring str= L"||1&&2&&$$abc||de&&hg||&&34&&$$56&&77";
  std::vector<std::wstring> delemiters;
  delemiters.push_back(L"||");
  delemiters.push_back(L"&&");
  delemiters.push_back(L"&&$$");
 
  std::list<std::wstring> strings;
 
  split(str,delemiters,strings);
 
  std::copy(strings.begin(),strings.end(),
            std::ostream_iterator<std::wstring, wchar_t>(std::wcout,L"\n") ) ;
 
  return 0;
}
Цитата Сообщение от Вывод:
1
2
abc
de
hg
34
56
77
2
18.08.2015, 18:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.08.2015, 18:43

Разбиение строки на части
Стандартная функция С strtok() по-своему конечно очень удобна, но в С++ со...

Разбиение текстовой строки
Не могу вызвать функцию strtok(); Вот код: int main(){ char *value,...

Разбиение строки на слова
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std; int main() {...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru