Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Алгоритм] Разбиение строки 
:(
    Опции темы
ShavarRsh
Дата 12.9.2011, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 12.3.2007

Репутация: нет
Всего: нет



Всем привет!
Вот такая задачка: есть строка. Надо ее разбить на подстроки одинаковой длины (длина задана), причем чтобы каждая подстрока начиналась с префикса [x\y] где x - номер подстроки, а y - общее количество подстрок.

Например, исходная строка: "In the beginner's mind there are many possibilities, but in the expert's there are few." Пусть длина подстроки 20, тогда в результате получим следующие подстроки:

"[1\6]In the beginner"
"[2\6]'s mind there a"
"[3\6]re many possibi"
"[4\6]lities, but in "
"[5\6]the expert's th"
"[6\6]ere are few."

Заметьте, что размер "In the beginner" равен 15, т.к. 5 символов занимает префикс "[1\6]".
Сложность в том, что при увеличении размера исходной строки, префикс будет расти, оставляя меньшее количество символов, которые могут поместиться в оставшуюся часть подстроки. Т.е. если бы нам понадобилось 10 подстрок, то размер префикса был бы равен 6 для первых 9-и подстрок и 7 для последней.

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

Естественно, вариант простого перебора  smile  (когда мы просто делаем предположение о количестве подстрок, а если не помеситлось - увеличиваем и проверяем снова) - не самое красивое решение  smile 

Заранее спаибо за участие  smile 

Это сообщение отредактировал(а) ShavarRsh - 12.9.2011, 23:21
PM MAIL   Вверх
volatile
Дата 13.9.2011, 02:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 8
Всего: 85



Цитата(ShavarRsh @  12.9.2011,  23:06 Найти цитируемый пост)
В принципе, ответом можно считать функцию, которая принимает два параметра - длину исходной строки и длину подстроки, а возвращает сколько подстрок для такого разбиения прийдется использовать. 

Код

int substring_count ( int str_size, int sub_size )
{
   int max = 0, dec = 0, prev = 0;
   int i = sub_size - 3;
   do
   {
      if ( i <= 2 ) return 0;
      i -= 2;
      dec = dec * 10 + ! dec;
      prev = max - dec + 1;
      max = prev + i * dec * 9;
   } while ( max < str_size );

   return dec - 1 + ( str_size - prev + i - 1 ) / i;
}


Цикл выполняется быстро. Не более log10(N) раз.
т.е например, для строки размером 1000000 (мульон) символов, не более 6 раз.

При невозможности разбиения,  возвращает 0

Проверить на разные значения можете здесь:
http://liveworkspace.org/code/fd164556eb57...61aeb62611e7dc1

Проверяйте!
smile 


PM MAIL   Вверх
volatile
Дата 13.9.2011, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 8
Всего: 85



Вчера ночью не заметил:

Цитата(volatile @  13.9.2011,  02:40 Найти цитируемый пост)
   return dec - 1 + ( str_size - prev + i - 1 ) / i;

Последний ретурн можно слегка сократить:
Код

   return dec + ( str_size - prev - 1 ) / i;

Впрочем, это не ошибка.

PM MAIL   Вверх
ShavarRsh
Дата 13.9.2011, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 12.3.2007

Репутация: нет
Всего: нет



Круто! Большое спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0732 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.