Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.93/56: Рейтинг темы: голосов - 56, средняя оценка - 4.93
 Аватар для MayaNash
1296 / 470 / 151
Регистрация: 24.08.2011
Сообщений: 2,249

Поиск наиболее часто встречающейся подстроки в строке

31.10.2014, 15:05. Показов 12487. Ответов 57
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Прошло уже немало лет с тех пор, как Лич Сандро ушёл на заслуженный отдых. Иногда по вечерам, когда ему становится совсем тоскливо, он берёт в руки книгу, которую ему подарили воспитанники-маги по случаю выхода на пенсию.
Вот и сейчас великий маг взял с полки книгу и углубился в чтение. В одной из глав рассказывалось про знаменитое открытие Сандро — много лет назад он придумал универсальное заклинание. Оказалось, что любая его подстрока (последовательность подряд идущих букв) тоже является заклинанием, а сила любого заклинания равна количеству раз, которое это заклинание встречается в универсальном (например, строка «ue» встречается в строке «queue» дважды, а строка «aba» в строке «abababa» — трижды).
Сейчас у Сандро много свободного времени, и он решил найти самое сильное заклинание. Помогите ему в этом.

Исходные данные
Единственная строка содержит универсальное заклинание, которое открыл Сандро. Заклинание — непустая строка из строчных латинских букв длиной не более 50.

Результат
Выведите любое из заклинаний, обладающих, по мнению Сандро, наибольшей силой.

Пример
Code
1
2
исходные данные   результат
tebidohtebidoh    tebidoh
На какой подстроке ответ может быть неверный? Программа неправильно отвечает на второй тест...
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
#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str, podstr, maxpodstr;
    // строка, текущая подстрока, подстр., которая встречается максимальное количество раз
    int maxk = 0, k, pos; // количество maxpodstr, количество текущей podstr, последняя найденная позиция podstr
    cin >> str;
    for (int i = 0; i < str.length(); i++) // с первого по последний символ
        for (int j = 1; j < str.length()-i; j++) // берем с одного до конца строки символов
        { // и смотрим сколько раз эта подстрока встретится
            podstr = str.substr(i, j);
            k = (str.find(podstr, 0) == 0? 1 : 0), pos = 0; // если на нулевой позиции есть эта подстрока,
                                                            // то одно вхождение уже есть
            do
            {
                pos = str.find(podstr, pos+1); // находим следующее вхождение (при pos==0 ищем со второго символа)
                if (pos != string::npos) // если нашли, увеличиваем количество вхождений, иначе выходим из цикла
                    k++;
                else
                    break;
            }
            while (true);
            if (k > maxk) // если нашли чаще встречающуюся подстроку
            {
                maxk = k; // запоминаем ее
                maxpodstr = podstr;
            }
        };
    cout << maxpodstr;
    return 0;
}
Добавлено через 1 час 27 минут
актуально
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.10.2014, 15:05
Ответы с готовыми решениями:

Пользуясь указателями найти слова с наиболее часто встречающейся длиной
Заданный текст длиной более 10 слов распечатать по строкам, понимая под строкой либо последовательность из 12 символов, если в нее не...

Вывести слово, наиболее часто встречающееся в строке
Дана строка, состоящая из слов, разделенных пробелами. Вывести слово, наиболее часто встречающееся в строке.

Определить наиболее часто встречающийся символ в строке
Определить наиболее часто встречающийся символ в строке.

57
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
01.11.2014, 04:42
Студворк — интернет-сервис помощи студентам
_Ivana, ну да, неправильный ответ на тесте 3, и он даже, как ты заметил, не проходит тест к == 12.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
01.11.2014, 04:47
У меня ошибка в алгоритме все-таки, а это боюсь быстро не вылечится пару 20 30 я им никак не могу получить.

Добавлено через 3 минуты
Но я еще думаю
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
01.11.2014, 11:40
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
/////////////////////////////////////////////////////////////////////////////////////////
//дано натуральное число k <= 10^9. найдите все такие упорядоченные пары (a, b), 
//(a > 0, b > 0, b <= 10^18, a <= 10^18), такие что сумма чисел в этой паре ровно в к раз 
//меньше чем произведение чисел в паре.
//
//Эта задачка была на соревновании, надеюсь никто не будет ругаться(надеюсь, тут никого нет, 
//кто писал это соревнование xD).
//
//Формат ввода: одно число k(k > 0 && k <= 10^9);
//Формат вывода: выведите все пары, удовлетворяющие условию.
//
//Примеры:
//input: 1
//output: 2 2
//
//Еще один
//input: 2
//output:3 6
//6 3
//4 4
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
/////////////////////////////////////////////////////////////////////////////////////////
typedef long long   T_int;
/////////////////////////////////////////////////////////////////////////////////////////
void    print_pairs( T_int    k )
{
    for( T_int  p = 1; p <= k; ++p )
    {
        if  (
                k * k % p   == 0
            )
        {
            std::cout   <<  k + p
                        <<  '\t'
                        <<  k + k * k / p
                        <<  std::endl;
        }
    }//for
}
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    for(;;)
    {
        std::cout   <<  std::endl
                    <<  std::endl
                    <<  std::endl
                    <<  std::endl
                    <<  "k = ";
        T_int   k   =   0;
        std::cin    >>  k;
        print_pairs(k);
    }//for
}
1
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
01.11.2014, 19:36
Проиграл я этот раунд - полетел с шашкой наголо и не смог реализовать алгоритм который в конце концов придумал, а тем временем Mr.X выложил свой красивый лаконичный вариант, по крайней мере k=12 он отрабатывает, и мне расхотелось реализовывать свой, т.к. он более громоздок. Вообще что-то последние дни ошибаюсь часто и чушь пишу - начиная с простейшей задачи удачных 6-значных билетов....

Не по теме:

Высыпаться надо наверное.

0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
01.11.2014, 22:30
_Ivana, Mr.X, кстати, решение МрИкс работает правильно, но долго. Каюсь, забыл сказать лимиты времени и памяти. Но вот решение МрИкс можно существенно ускорить. А так оно в секунду не уложится.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
02.11.2014, 02:39
Отоспался днем и с новой шашкой наваял вот такой код, вроде по всем проверкам и сравнениям с кодом Mr.X результаты совпадают, насчет скорости не знаю, но старался уложиться:
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
typedef unsigned long long int uintll;
 
int _tmain(int argc, _TCHAR* argv[]) 
{
    uintll k, f[100], p[500][2]; // размеры массивов от балды, можно увеличить если надо
    cout << "Input k: "; cin >> k;
 
    uintll k_=k; int i_f=0, i=1;
    while (k_>1 && i++) if(k_%i==0) {f[i_f++]=i; k_/=i; i=1;} // факторизация
    int nf=i_f;
 
    p[0][0]=1; p[0][1]=1; int np=1;
    uintll fx = 1;
    for (int i_f=0; i_f<nf; i_f++) {
        fx = (i_f==0 || f[i_f]!=f[i_f-1]) ? 1 : fx*=f[i_f];
        int iip = np;
        for (int i_p=0; i_p<np; i_p++)
            if (fx==1 || p[i_p][1]%fx==0) {p[iip][0]=p[i_p][0]; p[iip][1]=p[i_p][1]*f[i_f]; iip++;}
        for (int i_p=1; i_p<np; i_p++)
            if (fx==1 || p[i_p][0]%fx==0) {p[iip][0]=p[i_p][0]*f[i_f]; p[iip][1]=p[i_p][1]; iip++;}
        np = iip;
    }
 
    int count_pairs=0;
    for (int i_p=np-1; i_p>0; i_p--) {
        uintll u = k/p[i_p][0] + k/p[i_p][1], a=p[i_p][0]*u, b=p[i_p][1]*u;
        cout << a << ' ' << b << '\n' << b << ' ' << a << '\n'; count_pairs+=2;
    }
    uintll u = k/p[0][0] + k/p[0][1], a=p[0][0]*u, b=p[0][1]*u;
    cout << a << ' ' << b << '\n'; count_pairs++;
    cout << "Total: "<<count_pairs<<"\n";
 
    system("pause");
    return 0;
}
Простора для особой оптимизации в рамках данного алгоритма не так чтобы много, но факторизацию можно конечно дошлифовать - бежать до корня и скидывать остаток числа, если до корня не делится. Сейчас попробую.

Добавлено через 13 минут
UPD если k велико, то наверное факторизовать его будет лучше так:
C++
1
2
3
4
    uintll k_=k; int i_f=0, i=1;
    while (k_>1 || i*i<=k) {i++; if(k_%i==0) {f[i_f++]=i; k_/=i; i=1;}} // факторизация
    if(k_>1) f[i_f++]=k_;
    int nf=i_f;
, может можно еще оптимальнее алгоритм взять, их вроде много разных придумали, задача типовая. Ну а потом заполнение массива сочетаний множителей по факторизованному массиву простых делителей k сильно убыстрить не знаю как.

Добавлено через 12 минут
ЗЫ к примеру, для волшебного k=65488500 количество вариантов = 5775, моему алгоритму требуется массив как минимум в половину этого размера (понимаю что память ем, но такой вот шашечный алноритм), поэтому вышнаписанные в коде "размеры от балды" лучше задать с учетом диапазона входных аргументов:
C++
1
uintll k, f[30], p[3000][2]; // размеры массивов от балды, можно увеличить если надо
Добавлено через 12 минут
UPD опечатка (хотя работает и с ней, но не оптимизированно) -
C++
1
while (k_>1 || i*i<=k)
следует читать как
C++
1
while (k_>1 || i*i<=k_)
Добавлено через 10 минут
UPD вместо двух внутренних циклов заполнения вариантов можно сделать 1 - в 2 раза убыстрится алгоритм:
C++
1
2
3
4
5
6
7
8
9
10
11
12
    p[0][0]=1; p[0][1]=1; int np=1;
    uintll fx = 1;
    for (int i_f=0; i_f<nf; i_f++) {
        fx = (i_f==0 || f[i_f]!=f[i_f-1]) ? 1 : fx*=f[i_f];
        int iip = np;
        for (int i_p=0; i_p<np; i_p++) {
            if (fx==1 || p[i_p][1]%fx==0) {p[iip][0]=p[i_p][0]; p[iip][1]=p[i_p][1]*f[i_f]; iip++;}
            if (i_p==0) continue; 
            if (fx==1 || p[i_p][0]%fx==0) {p[iip][0]=p[i_p][0]*f[i_f]; p[iip][1]=p[i_p][1]; iip++;}
        }
        np = iip;
    }
Но если это все вообще имеет смысл, а то большой размер массива и может неоптимальность логики ставят крест на любой оптимизации данного алгоритма, как изначально далекого от идеала.
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
02.11.2014, 02:47
_Ivana, все эти оптимизации необязательны. и памяти это немного.

вот несколько рандомных тестов с ответами(колво пар в ответе)

k == 605126698 ans == 27
k == 868358335 ans == 45
k == 515263202 ans == 9
k == 962014423 ans == 27
k == 801663315 ans == 27
k == 922261066 ans == 27
k == 551410418 ans == 243
k == 16099050 ans == 675
k == 391318452 ans == 1755
k == 178131676 ans == 45
k == 478576264 ans == 189
k == 5017407 ans == 9
k == 405733669 ans == 27
k == 613303310 ans == 243
k == 651939079 ans == 9
k == 711923016 ans == 567
k == 378091956 ans == 405
k == 652478286 ans == 81
k == 861791300 ans == 225
k == 324223628 ans == 45

Добавлено через 1 минуту
_Ivana, решение написать?
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
02.11.2014, 02:53
SlavaSSU, несколько тестов навскидку совпадают. Но в этом алгоритме и его реализации я уверен побольше чем в предыдущем, думаю тут все в порядке с результатами, я его сравнивал с выложенным Mr.X на достаточном количестве данных. А оптимизации - пытаюсь улучшить что возможно и несложно.
И в результате, скажите, доктор - мой код пройдет ограничения по скорости и памяти? Могу я считать, что победил задачу с шашкой или как?

Добавлено через 1 минуту
Решение - не знаю, может кто еще решает и хочет подумать без подсказок (хотя вероятность этого невелика ) Мне то конечно интересно посмотреть решение. Как и выслушать вашу оценку моего кода в сравнении с ним.
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
02.11.2014, 02:55
_Ivana, тогда можешь допилить код так:

чтение из консоли, вывод в консоль без всяких "введите k" и т.д.

и сначала надо вывести колво пар, а затем и сами пары.

я отправлю его в систему.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
02.11.2014, 03:08
Если я правильно понимаю, то будет что-то типа такого (хотя у меня тесты из файла не проходит почему-то, может не то читаю):
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
int _tmain(int argc, _TCHAR* argv[]) 
{
    uintll k, f[30], p[3000][2]; // размеры массивов от балды, можно увеличить если надо
    //cout << "Input k: "; cin >> k;
 
    freopen("TESTS2.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
 
    while (cin >> k) {
        uintll k_=k; int i_f=0, i=1;
        while (k_>1 || i*i<=k_) {i++; if(k_%i==0) {f[i_f++]=i; k_/=i; i=1;}} // факторизация
        if(k_>1) f[i_f++]=k_;
        int nf=i_f;
        //for (int i_f=0; i_f<nf; i_f++) cout<<f[i_f]<<'\n';
        //cout << "--------------------------------------------------------------------\n";
 
        p[0][0]=1; p[0][1]=1; int np=1;
        uintll fx = 1;
        for (int i_f=0; i_f<nf; i_f++) {
            fx = (i_f==0 || f[i_f]!=f[i_f-1]) ? 1 : fx*=f[i_f];
            int iip = np;
            for (int i_p=0; i_p<np; i_p++) {
                if (fx==1 || p[i_p][1]%fx==0) {p[iip][0]=p[i_p][0]; p[iip][1]=p[i_p][1]*f[i_f]; iip++;}
                if (i_p==0) continue; 
                if (fx==1 || p[i_p][0]%fx==0) {p[iip][0]=p[i_p][0]*f[i_f]; p[iip][1]=p[i_p][1]; iip++;}
            }
            np = iip;
        }
        cout << np*2-1 << "\n";
        for (int i_p=np-1; i_p>0; i_p--) {
            uintll u = k/p[i_p][0] + k/p[i_p][1], a=p[i_p][0]*u, b=p[i_p][1]*u;
            cout << a << ' ' << b << '\n' << b << ' ' << a << '\n';
        }
        uintll u = k/p[0][0] + k/p[0][1], a=p[0][0]*u, b=p[0][1]*u;
        cout << a << ' ' << b << '\n';
    }
 
    system("pause");
    return 0;
}
Добавлено через 4 минуты
А, не, нормально вроде читает каждое новое k, и выводит результаты в один файл. Я сначала не тот входной файл подсунул Ну и в конце системпаузу конечно надо убрать, она пишет в файл кракозябры перекодированной кириллицы...
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
02.11.2014, 03:09
_Ivana, превышено ограничение времени на тесте 21. там лимит по времени 2 секунды. он не уложился.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
02.11.2014, 03:13
Эх... Не знаю, смогу ли еще ужать алгоритм, похоже этот уже врядли, я и так почти всех блох собрал. Принципиально новый подход нужен, без многократным пробежкам удлинняющегося массива.
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
02.11.2014, 03:20
_Ivana, решение.

a * b == (a + b) * k;

a * b == a * k + b * k;

a * b - a * k - b * k == 0;

a * (b - k) - b * k == 0;

a * (b - k) - b * k + (k^2 - k^2) == 0;

a * (b - k) - k * (b - k) - k^2 == 0;

(b - k) * (a - k) == k^2;

произведение скобок равно числу, значит эти скобки - его делители.

найдем все делители числа k^2 и таким образом найдем все пары (a, b);
1
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
02.11.2014, 03:23
Красиво. А я дятел дошел только до 1/k = 1/a + 1/b и на этой формуле строил логику...
И k^2 как раз в лонг лонг влезает, специально ограничение размера дано максимальное. В общем, 1:0 в вашу пользу Теперь жду на своем поле, где поединок с Фарроу - рассчитываю сравнять счет
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
02.11.2014, 03:27
_Ivana,
теперь еще 1 сложность.

нам надо найти все делители числа k^2. все знают как за корень искать.

так вот МрИкс и стал идти до корня числа k^2, т.е. до k, но k может быть около миллиарда.

и тут надо воспользоваться тем, что чтобы найти все делители числа k^2, достаточно перебрать все пары делителей числа k.

т.е. решение такое, находим все делители числа k(идя до корня т.е. всего до 10^5 грубо говоря). и кидаем все делители в векторок.

теперь перебираем пару наших делитлей, умножаем их и получаем делитель k^2. все.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
02.11.2014, 03:31
Цитата Сообщение от SlavaSSU Посмотреть сообщение
найдем все делители числа k^2
да там уже все понятно, достаточно k факторизовать и удвоить каждый множитель, и все сочетания перебрать. До формулы додуматься надо было

Добавлено через 1 минуту
Идея лежит на поверхности, и это то как раз не сложность - я написал свой пост до прочтения вашего.
0
221 / 166 / 47
Регистрация: 17.07.2012
Сообщений: 587
02.11.2014, 03:33
_Ivana, я, ксожалению, не знаю что такое фарроу. я читал тот топик - я ничего оттуда не знаю!
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
02.11.2014, 03:36
Фамилие такое (С) Кот Матроскин Но это не важно, там ссылка на топик с теорией вопроса, все очень просто. Суть - решение системы линейных уравнений 4*4 для получения коэффициентов полинома, проходящего через 4 очки равномерной сетки.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.11.2014, 03:36

Вывести слово, наиболее часто встречающееся в строке
Дальше не знаю как решать, помогите пожалуйста. #include &quot;pch.h&quot; #include &lt;iostream&gt; #include &lt;ctime&gt; #include...

Поиск наиболее часто встречающихся слов
Помогите пожалуйста, нужно определить десятку наиболее часто встречающихся слов в 5 столбце Strigngrid

В строке символов найти наиболее часто повторяющуюся цифру
В строке символов, введенных в StringGrid(1строка), найти наиболее часто повторяющуюся цифру я неочень понимаю, в стринггриде может...

Поиск наиболее часто встречаемого слова на сайте
Добрый вечер ув. Форумчане! :) Требуется написать программу, которая выводит наиболее встречаемое слово на сайте (на любом) с выводом в...

Поиск наиболее часто встречающихся слов в файле
Дан символьный файл f, содержащий произвольный текст длиной более 5000 слов. Слова в тексте разделены пробелами и знаками препинания....


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

Или воспользуйтесь поиском по форуму:
58
Ответ Создать тему
Новые блоги и статьи
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru