Форум программистов, компьютерный форум, киберфорум
Boost C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
 Аватар для Egor138
32 / 13 / 3
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2

Выделение подстрок, алгоритмы поиска в строке

06.05.2014, 00:14. Показов 2896. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня есть строка типа:

command param1 param2.. paramn id
Где id может включать в себя конструкцию типа (param;.,: "") , тоесть это что-то типа команды.
Вот некоторые примеры таких строк:

1) MsgBox("hello");
2) int i(5);
3) find string by param(some params, some params; "params");

Пытаюсь написать алгоритм который разберет эту строку на некоторые части:

1) часть free_param включает в себя все команды вне скобок
2) часть p_param включает в себя все скобки.

Тоесть если есть такая строка find string by param(some params, some params; "params");
Вот такой результат мне нужен:

C++
1
2
vector<string> free_param; // содержит 4 элемента:  find string by param
vector<string> p_param; // содержит 1 элемент:  (some params, some params; "params")

Алгоритм сам я написал, но получился "грязный код" - куча переменных, никакой логики..
Его структура была примерно такова: во временную переменную кидаю по одному символу пока не встретится скобка. Если же она встречается, то меняем режим работы (меняем значение так называемой скобковой переменной), потом кладем временную переменную в вектор и также добавляем все что внутри скобки, пока int переменная не будет равна нулю (когда все скобки закрылись - +1 к переменной когда скобка открывается и -1 когда закрывается)

Собственно моя проблема заключается в нахождении оптимального алгоритма с наименьшими действиями. Пробовал использовать regex, но как-то не особо помогло. Можете подсказать какую нибудь идею для алгоритма или возможно в boost есть подходящие библиотеки???

Добавлено через 5 часов 32 минуты
upppppp
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.05.2014, 00:14
Ответы с готовыми решениями:

Проверить, содержится ли строка S0 в строке S. Не использовать стандартные средства для поиска подстрок
1)Дан целочисленный массив A размера N. Назовем серией группу подряд идущих одинаковых элементов, а длиной серии — количество этих...

Алгоритмы поиска подстроки в строке
Если не сложно, помогите пожалуйста и простенько объясните алгоритмы поиска последовательного прямого поиска, Рабина, Кнута-Морриса-Пратта...

Реализовать алгоритмы поиска подстроки в строке.
Здравствуйте,требуется на основе алгоритмов прямого поиска; Кнута, Морриса и Пратта; Боуера и Мура реализовать алгоритмы поиска...

8
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33399 / 21509 / 8236
Регистрация: 22.10.2011
Сообщений: 36,907
Записей в блоге: 12
06.05.2014, 12:34
Лучший ответ Сообщение было отмечено Egor138 как решение

Решение

Egor138, ну тебе же написали, как разбить строку boost::split-ом, чуть-чуть доработать, и будет то, что нужно:
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
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>
 
int main(int argc, char *argv[])
{
 
    std::string str("find string by param(some params, some params; \"params\")");
    
    std::vector<std::string> free_param;
    std::vector<std::string> p_param;
    
    boost::split(p_param, str, boost::is_any_of("()"));
    boost::split(free_param, p_param.front(), boost::is_any_of(" "));
    p_param.erase(p_param.begin(), p_param.begin() + 1);
    
    std::cout << "free_param:" << std::endl;
    for(std::vector<std::string>::iterator iter = free_param.begin(); iter != free_param.end(); ++iter)
        std::cout << *iter << std::endl;
    std::cout << "p_param:" << std::endl;
    for(std::vector<std::string>::iterator iter = p_param.begin(); iter != p_param.end(); ++iter)
        std::cout << *iter << std::endl;
    
    return 0;
}
1
 Аватар для Egor138
32 / 13 / 3
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
06.05.2014, 19:24  [ТС]
Вся проблема в том, что в скобках могут быть вложенные скобки, тогда разделение таким способом не пройдет
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33399 / 21509 / 8236
Регистрация: 22.10.2011
Сообщений: 36,907
Записей в блоге: 12
06.05.2014, 19:34
Приведи пример сложной строки и того, как она должна парситься.
0
 Аватар для Egor138
32 / 13 / 3
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
06.05.2014, 19:46  [ТС]
C++
1
SaveCode("file.txt", saveOne) (msgbox("DFD"); hi("")(func("param"))(param, param);)(endfunc(0););
Вот результат парсинга:
C++
1
2
3
4
free_param:  SaveCode
p_param:    1 элемент: ("file.txt", saveOne)
            2 элемент: (msgbox("DFD"); hi("")(func("param"))(param, param);)
            3 элемент: (endfunc(0);)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33399 / 21509 / 8236
Регистрация: 22.10.2011
Сообщений: 36,907
Записей в блоге: 12
06.05.2014, 20:37
Такие вещи регэкспами не парсятся.Тут без прохода по строке не обойтись. Например, так:
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
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>
 
 
int main ()
{
    std::string s ("SaveCode(\"file.txt\", saveOne) (msgbox(\"DFD\"); hi(\"\")(func(\"param\"))(param, param);)(endfunc(0););");
    // std::string s("MsgBox(\"hello\");");
    // std::string s("int i(5);");
    // std::string s("find string by param(some params, some params; \"params\");");
    // std::string s("find string by param");
 
    std::vector<std::string> free_param;
    std::vector<std::string> p_param;
 
    std::size_t found = s.find("(");
    std::string str = s.substr(0, found != std::string::npos ? found : std::string::npos);
    boost::split(free_param, str, boost::is_any_of(" "));
 
    if(found != std::string::npos)
    {
        int p = 0, start = found;
        for(std::string::size_type i = start; i < s.size(); ++i)
        {
            switch(s[i])
            {
            case '(' :
                p += 1;
                break;
            case ')' :
                p -= 1;
                if(!p)
                {
                    p_param.push_back(s.substr(start, i - start + 1));
                    start = i + 1;
                }
            }
 
        }
    }
 
    std::cout << "free_param:" << std::endl;
    for(std::vector<std::string>::iterator iter = free_param.begin(); iter != free_param.end(); ++iter)
        std::cout << *iter << std::endl;
    std::cout << "p_param:" << std::endl;
    for(std::vector<std::string>::iterator iter = p_param.begin(); iter != p_param.end(); ++iter)
        std::cout << *iter << std::endl;
    return 0;
}
Все закомментированные строки возвращают ожидаемый результат...
1
 Аватар для Egor138
32 / 13 / 3
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
06.05.2014, 20:49  [ТС]
UI, Спасибо, сейчас попробую скомпилировать )

Добавлено через 11 минут
UI, Спасибо все работает, только единственное, что если строка такая
C++
1
std::string s ("SaveCode(\"file.txt\", saveOne) free_param2  (msgbox(\"DFD\"); hi(\"\")(func(\"param\"))(param, param);)(endfunc(0););");
то вторую free_param не находит. Сейчас попробую доработать
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33399 / 21509 / 8236
Регистрация: 22.10.2011
Сообщений: 36,907
Записей в блоге: 12
08.05.2014, 20:26
Лучший ответ Сообщение было отмечено Egor138 как решение

Решение

Egor138, вот тебе еще вариант, с boost::xpressive.

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
#include <boost/algorithm/string.hpp>
#include <boost/xpressive/xpressive.hpp>
#include <iostream>
 
using namespace std;
using namespace boost::xpressive;
 
vector<string> free_param;
vector<string> p_param;
 
int main()
{
    sregex_compiler comp;
    comp.compile("(?$nonbrace=)[^()]");
    sregex braced = comp.compile("(?$braced=)\\(((?$nonbrace)+|(?$braced))*\\)");
    
    std::string test("SaveCode(\"file.txt\", saveOne, hi(\"\")) free_param2  (msgbox(\"DFD\"); hi(\"\")(func(\"param\"))(param, param);)(endfunc(0););");
    std::string test_copy(test);
    
    smatch what;
    while(regex_search(test, what, braced))
    {
        p_param.push_back(what[0]);
        test = what.suffix().str();
    }
    
    
    std::string free_param_str("");
    regex_replace (std::back_inserter(free_param_str), test_copy.begin(), test_copy.end(), braced, "");
    boost::split(free_param, free_param_str, boost::is_any_of(" ;"));
    
    
    std::cout << "free_param: " << std::endl;
    for(std::vector<std::string>::iterator iter = free_param.begin(); iter != free_param.end(); ++iter)
        std::cout << *iter << std::endl;
    
    std::cout << "p_param:" << std::endl;
    for(std::vector<std::string>::iterator iter = p_param.begin(); iter != p_param.end(); ++iter)
        std::cout << *iter << std::endl;
    return 0;
}
Выдает:
Code
free_param: 
SaveCode
free_param2
 
 
p_param:
("file.txt", saveOne, hi(""))
(msgbox("DFD"); hi("")(func("param"))(param, param);)
(endfunc(0);)
По-моему, все нормально...
1
 Аватар для Egor138
32 / 13 / 3
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
09.05.2014, 14:32  [ТС]
Большое спасибо Теперь все отлично!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.05.2014, 14:32
Помогаю со студенческими работами здесь

Выделение подстрок по ключевым словам
Доброго времени суток уважаемые форумчане. Есть проблема. допустим дан массив тегов: string tags =...

Реализация алгоритма поиска подстрок чжу такаоки на c++
У кого нибудь есть алгоритм поиска подстрок чжу такаоки на c++?)

Выделение определённых подстрок из каждой строки одного текстового файла и их запись в другой текстовый файл
Добрый вечер. Столкнулся с проблемой во время создания bat файла. Bат файл должен из каждой строки заданного txt файла вытащить последние...

Алгоритмы поиска перебором и бинарного поиска
Здравствуйте. Не могли бы вы мне помочь в программой , пожалуйста. в оперативной памяти имеется таблица слов(строковый массив)...

Замена подстрок в строке
Кто знает, как в данной строке заменить все подстроки &quot;123&quot; на &quot;456&quot;?


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru