Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
2 / 2 / 2
Регистрация: 01.11.2013
Сообщений: 154

Распаковать строку

03.04.2017, 01:50. Показов 2699. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет,имеется следующая строка на входе "2[abc]",на выходе должен получить "abcabc",вот еще пример:
на входе "2[abc3[abcd]]",а на выходе "abcabcdabcdabcabcdabcd",на входе"3[d]3[nm]",а на выходе "dddnmnmnm",то есть string в квадратных скобках должен повторяться N раз. Предположим что входные данные будут введены пользователем без ошибок(в квадратных скобках могут находиться только буквы,N>0,а формат скобок будет введен правильно).
Никак не приходит в голову разделить это все по частям и подобраться к верному решению.
Буду благодарен за подсказку,решить хотелось бы самому,поэтому прошу не писать готовый код. Спасибо

Добавлено через 4 часа 41 минуту
Все еще нужна помощь
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.04.2017, 01:50
Ответы с готовыми решениями:

Распаковать zip архив
Нужно распаковать все файлы из zip архива (или tar.gz). Подключил zlib. zip архив находится рядом с .exe файлом приложения. Не могу...

Как распаковать архив ZLib C++
Даже в документации офф. сайта, и в и примере ничего не понятно. Надо написать класс для распаковки zip архива на основе ZLib, с методом...

Распаковать беззнаковое целое число в четыре символа
«Распаковать» беззнаковое целое число в четыре символа. Длина беззнакового целого равна 4. Помогите написать программу

10
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
03.04.2017, 03:17
Как вариант можно так:
1 - проверяем баланс скобок
2 - находим последнюю [ и первую ] после неё, сохраняем подстроку внутри скобок и значение слева
3 - вырезаем значение слева и скобочки
4 - на это место ставим N сохранённый подстрок, где N - значение, которое сохранили на шаге 2
2 - переходим ко второму пункту

Или так:
Описываем древовидную структуру, в основе которой лежит связный список, который может хранить элементы 2-ух типов, либо строку, либо число и указатель на следующий список, который также может хранить элементы двух типов, таким образом
test string1[a]2[b3[c]]
превращается в
Python
1
2
3
4
5
["test string", 
                    (1, ["a"]), 
                    (2, ["b", 
                                (3, ["c"],)],),
]
Это питоновская запись, если что [] - массив () - кортеж.
И обрабатываем дерево, допустим рекурсивно.
В теории должно работать
0
2 / 2 / 2
Регистрация: 01.11.2013
Сообщений: 154
03.04.2017, 04:54  [ТС]
Цитата Сообщение от DevAlone Посмотреть сообщение
вырезаем значение слева и скобочки
я так понял нужно вырезать еще и саму строку в скобках,а то при вставке будет (N сохраненных подстрок + 1 дефолтная строка в скобках которую не вырезали)
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.04.2017, 09:16
1.
Цитата Сообщение от Yarik199 Посмотреть сообщение
на входе "2[abc3[abcd]]",а на выходе "abcabcdabcdabcabcdabcd"
В данном случае разве не должно получится: "abc abcd abcd abcd abc abcd abcd abcd" (без пробелов)?

2. Перед квадратными скобками читается только одна десятеричная цифра? Что должно получиться в случае: "32[X]"?
0
2 / 2 / 2
Регистрация: 01.11.2013
Сообщений: 154
03.04.2017, 14:26  [ТС]
Цитата Сообщение от DevAlone Посмотреть сообщение
Как вариант можно так:
1 - проверяем баланс скобок
2 - находим последнюю [ и первую ] после неё, сохраняем подстроку внутри скобок и значение слева
3 - вырезаем значение слева и скобочки
4 - на это место ставим N сохранённый подстрок, где N - значение, которое сохранили на шаге 2
2 - переходим ко второму пункту
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
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void func(string output){
        string out = output;
        int i = 0;
        int p = 0;
        string g = "";
        while(true){
            size_t lastOne = out.find_last_of("["); //сохраняем индекс [
            size_t firstOne = out.find_first_of("]"); //сохраняем индекс ]
            if(lastOne == string::npos || firstOne == string::npos) break; //если [ или ] не существуют выходим
            int leftValue = atoi(out.substr(lastOne - 1).c_str()); //сохраняем значение слева 
            string underString = out.substr(lastOne + 1, firstOne - lastOne - 1 ); //вырезаем и сохраняем подстроку которая была в скобках
    
            out.erase(out.begin() + (lastOne-1)); //удаляем значение слева
    
            out.erase(out.begin() + (lastOne-1)); //удаляем [
    
            out.erase(out.begin() + (firstOne -2)); //удаляем ]
    
            out.erase(lastOne-1,underString.length()); //удаляем нашу подстроку(чтобы при вставке не копировалась) 
            //проблема в erase так erase смещает строку на -1 элемент влево
            while(leftValue!=0){
                g += underString; //умножаем наш стринг на leftValue раз и сохраняем его в "g"
                leftValue--;
            }
            out.insert(lastOne-1, g); //вставляем нашу строку g в основной out и возвращаемся в начало while  
            
        } 
        cout<<out<<endl; //ответ
        
        
}
 
 
 
int main(int argc, char** argv) {
    
    string input = "";
    cin>>input;
    func(input);
    return 0;
}
вот есть набросок,проблема с erase

Добавлено через 1 минуту
Цитата Сообщение от castaway Посмотреть сообщение
В данном случае разве не должно получится: "abc abcd abcd abcd abc abcd abcd abcd" (без пробелов)?
да все верно,моя ошибка.
Цитата Сообщение от castaway Посмотреть сообщение
2. Перед квадратными скобками читается только одна десятеричная цифра? Что должно получиться в случае: "32[X]"?
Может читаться больше и это проблема,в вашем случае строка должна повториться 32 раза.Есть идеи?

Добавлено через 23 минуты
Цитата Сообщение от Yarik199 Посмотреть сообщение
вот есть набросок,проблема с erase
все таки это не в erase,а в том случае когда у нас нет иерархии,и вместо out.find_first_of должно быть out.find_last_of

Добавлено через 21 минуту
Цитата Сообщение от Yarik199 Посмотреть сообщение
string g = "";
этот стринг должен быть в 25 строке перед вайлом,так как он должен очищаться при каждой итерации

Добавлено через 45 минут
код вроде более менее работает,и у меня следующие вопросы:
1) как обработать входные данные так чтобы метод второй переменной менялся в зависимости от случая на find_first_one или find_last_one? так как метод find_first_one второй переменной подходит для иерархии и может обработать строку "3[v2[b]]",но такого типа строку "2[a]3[bc]" уже не обработает,так как здесь понадобиться на входе метод find_last_one для второй переменной.
2)Как обработать в моем случае N>=10 ?
3)А такой тип строк "[[]][]" потребует разных значений,один раз find_last_of,а при следующей итерации уже find_first_of должно вызываться,то есть эти методы должны вызываться переменно,как следует проверить в какой итерации какой метод вызывать?
Спасибо.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
03.04.2017, 16:41
Yarik199, запакованными могут быть только буквы? В результирующей строке не может быть десятеричных цифр?
0
2 / 2 / 2
Регистрация: 01.11.2013
Сообщений: 154
03.04.2017, 16:49  [ТС]
Цитата Сообщение от castaway Посмотреть сообщение
запакованными могут быть только буквы? В результирующей строке не может быть десятеричных цифр?
Именно. Запакованными могут быть только буквы и на выходе в результате получаем так же буквы(без цифр,они там находиться не могут).
0
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
03.04.2017, 20:48
Лучший ответ Сообщение было отмечено Yarik199 как решение

Решение

Цитата Сообщение от DevAlone Посмотреть сообщение
Как вариант можно так:
1 - проверяем баланс скобок
2 - находим последнюю [ и первую ] после неё, сохраняем подстроку внутри скобок и значение слева
3 - вырезаем значение слева и скобочки
4 - на это место ставим N сохранённый подстрок, где N - значение, которое сохранили на шаге 2
2 - переходим ко второму пункту
Как-то так:
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
#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
 
using std::cout;
using std::endl;
using std::cin;
 
std::string unpackString(std::string str)
{
    int open_bracket_pos;
    int close_bracket_pos;
    while ( (open_bracket_pos = str.find_last_of('[')) != str.npos) {
        close_bracket_pos = str.find_first_of(']', open_bracket_pos);
        if(close_bracket_pos == str.npos)
            throw std::exception();
        int value = 0;
        int i = 0;
        for( ;i < 10; i++) {
            if(open_bracket_pos - i - 1 >= 0
                    && open_bracket_pos - i - 1 < str.size()
                    && str[open_bracket_pos - i - 1] >= '0' && str[open_bracket_pos - i - 1] <= '9')
                value += pow(10, i) * (str[open_bracket_pos - i - 1] - '0');
            else
                break;
        }
        std::string substr = str.substr(open_bracket_pos + 1, close_bracket_pos - open_bracket_pos - 1);
        str.erase(open_bracket_pos - i, close_bracket_pos - open_bracket_pos + i + 1);
        for(int j = 0; j < value; j++)
            str.insert(open_bracket_pos - i, substr);
//        cout << str << endl;
    }
 
    return str;
}
 
bool checkBracketBalance(const std::string &str, char lb = '(', char rb = ')')
{
    int i = 0;
    for(char symbol : str) {
        if (symbol == lb)
            i++;
        else if (symbol == rb)
            i--;
        if(i < 0)
            return false;
    }
    return i == 0;
}
 
int main()
{
 
    std::string str = "test string 2[b] asdf 3[a2[c]] qqq";
    if(!checkBracketBalance(str, '[', ']'))
        throw std::exception();
    cout << str << endl;
    cout << unpackString(str) << endl;
 
    return 0;
}
0
2 / 2 / 2
Регистрация: 01.11.2013
Сообщений: 154
04.04.2017, 01:44  [ТС]
Цитата Сообщение от DevAlone Посмотреть сообщение
int i = 0;
* * * * for( ;i < 10; i++) {
* * * * * * if(open_bracket_pos - i - 1 >= 0
* * * * * * * * * * && open_bracket_pos - i - 1 < str.size()
* * * * * * * * * * && str[open_bracket_pos - i - 1] >= '0' && str[open_bracket_pos - i - 1] <= '9')
* * * * * * * * value += pow(10, i) * (str[open_bracket_pos - i - 1] - '0');
* * * * * * else
* * * * * * * * break;
* * * * }
спасибо,объясните пожалуйста эти строчки,и что за магия написанная в переменной value?
0
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
04.04.2017, 02:17
Цитата Сообщение от Yarik199 Посмотреть сообщение
спасибо,объясните пожалуйста эти строчки,и что за магия написанная в переменной value?
здесь я перебираю строку от первого символа перед левой скобкой до тех пор, пока идут цифры, не вышли за пределы массива и не перебрали 10 символов(10 взял от балды, а вообще, если value сделать unsigned, то количество цифр должно быть равно количеству цифр в максимальном значении данного типа - 1, ну или как-то детектить переполнение). Каждый символ я из кода ascii преобразую в значение от 0 до 9 с помощью (str[open_bracket_pos - i - 1] - '0'); и умножаю на степень 10, т.к. это позиционная система счисления. Т.е.
1201
value += 1 * 1
value += 10 * 0
value += 100 * 2
value += 1000 * 1
1
2 / 2 / 2
Регистрация: 01.11.2013
Сообщений: 154
04.04.2017, 02:52  [ТС]
Цитата Сообщение от DevAlone Посмотреть сообщение
(str[open_bracket_pos - i - 1] - '0');
atoi(output[firstOne - i - 1].c_str())
Спасибо,все понятно.Хотел немного видоизменить код,но почему то компилятор ругается если вместо вашей строки вставить функцию atoi
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.04.2017, 02:52
Помогаю со студенческими работами здесь

Как распаковать из xlsx в xml с использованием zlib?
Заранее благодарен за вашу любую помощь!

Как программно распаковать ISO (образ диска)?
Как программно распаковать ISO (образ диска) с выбором того, что именно нужно распаковать, куда распокавать, нужно ли перезаписать и тд ?...

Распаковать zip строку
Смотрим на заголовок - именно СТРОКУ, а не файл!!! Есть строка string pack= &quot;xњмЅ‹rG’(ъ+Flњs#(є&quot; Строка сжата методом ZIP, есть...

Как запаковать и распаковать файлы? Ну хотя бы распаковать?
Как распаковать архив rar или zip из кода? Знаю, что есть библиотеки UnRar.dll и UnZip.dll, но как точно их использовать - не знаю. ...

распаковать
Мне надо что бы при запуске программы я нажимал на кнопку я в место где лежит моя программа(exe) распаковывался длл файл(вроде легко но я...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
YAFU@home — распределённые вычисления для математики. На CPU
Programma_Boinc 20.01.2026
YAFU@home — распределённые вычисления для математики. На CPU YAFU@home — это BOINC-проект, который занимается факторизацией больших чисел и исследованием aliquot-последовательностей. Звучит. . .
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru