Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.12.04;
Скачать: [xml.tar.bz2];

Вниз

Получение массива строк из шаблона со счетчиками   Найти похожие ветки 

 
lazy BEGINner ©   (2011-08-13 20:24) [0]

Есть строка-шаблон задаваяемая в виде:
1stconst1[min1-max1]1stconst2[min2-max2]1stconst3...
И строка-шаблон вида:
2ndconst1[]2ndconst2[]2ndconst3...,
где 1stconst1..2ndconst3 - любые текстовые строки;
в квадратных скобках первой строки указываются минимальные и максимальные значения счетчика, разделяемые "-" (причем min и max могут быть либо числами с одинаковым числом десятичных разрядов, либо нет), величина приращения счетчика 1;
квадратные скобки второй строки пустые и указывают лишь позицию счетчика.
Необходим код, результатом которого станут два массива строк.
Например, заданы шаблоны:
firstbla[9-11]firstblabla[09-10]firstblablabla и
secondbla[]secondblabla[]
В результате должны получить строки:
firstbla9firstblabla09firstblablabla
firstbla9firstblabla10firstblablabla
firstbla10firstblabla09firstblablabla
firstbla10firstblabla10firstblablabla
firstbla11firstblabla09firstblablabla
firstbla11firstblabla10firstblablabla
и
secondbla9secondblabla09
secondbla9secondblabla10
secondbla10secondblabla09
secondbla10secondblabla10
secondbla11secondblabla09
secondbla11secondblabla10

Обе строки задаются пользователем и поэтому число счетчиков заранее неизвестно.
Как бы поизящнее решить задачку.


 
Sha ©   (2011-08-13 22:31) [1]

А не изящно уже решил?


 
lazy BEGINner ©   (2011-08-13 22:42) [2]


> А не изящно уже решил?

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


 
Jeer ©   (2011-08-13 22:47) [3]


> Просто я до него не могу пока дойти.


"Иди, да и воздастся"


 
lazy BEGINner ©   (2011-08-14 00:02) [4]


> "Иди, да и воздастся"

буду пока пробовать решать, как получится


 
DiamondShark ©   (2011-08-15 13:01) [5]


> Необходим код, результатом которого станут два массива строк.

Программа со встроенным експлойтом?
Скромный шаблон
a[1-100]b[1-100]c[1-100]
прородит массив из 1000000 строк.


> Как бы поизящнее решить задачку.

Твои шаблоны -- это некая грамматика. Напиши парсер, который будет преобразовывать входные строки в некую структуру. Т.к. у тебя грамматика простая, у тебя будут только два типа лексем: литералы и счётчики.
Для внутреннего представления вполне подойдёт упорядоченный список объектов. В списке будут объекты двух типов: "Литерал" (основное свойство -- "Значение") и "Счётчик" (основные свойства -- "Мин.Знач.", "Макс.Знач", "Шаг").
С этой структурой можно эффективно работать.

Для разбора строк можно или написать нисходящий сканер, или взять готовый процессор регулярных выражений.


 
lazy BEGINner ©   (2011-08-17 16:48) [6]


> Программа со встроенным експлойтом?

Спасибо за замечание.
В принципе в реальности мне и нужен массив.
От него откажусь, поэкономлю оперативку.
Строки буду использоваться в процессе генерации.
Разберусь с делами, допишу код.
Выложу, может интересно кому.
Там все гораздо проще, чем я думал.


 
lazy BEGINner ©   (2011-08-17 17:09) [7]


> В принципе в реальности мне и нужен массив.

Очепятка, хотел сказать НЕ нужен


 
Oleg_teacher   (2011-08-17 19:07) [8]

считали структуру... вытянули числовые значения и в двойном цыкле выполнили вывод строк.


 
Oleg_teacher   (2011-08-17 19:09) [9]

ага, стоп не досмотрел троеточие (( мое решение не подходит.


 
lazy BEGINner ©   (2011-08-18 01:52) [10]

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


 
lazy BEGINner ©   (2011-08-19 20:18) [11]

Вот примерно так это выглядит.

procedure TForm1.Button1Click(Sender: TObject);
var
 fullstrnum: integer; //Общее число строк
 i,ii,j,ostatok: integer;
 firststring: string; //Шаблон 1
 secondstring: string; //Шаблон 2
 counters: integer; //Число счетчиков
 firstconst: array of string; //Массив констант 1
 secondconst: array of string; //Массив констант 2
 minstring: array of string; //Массив минимумов в строковом виде
 maxstring: array of string; //Массив максимумов в строковом виде
 minnum: array of integer; //Массив минимумов в целочисленном виде
 maxnum: array of integer; //Массив максимумов в целочисленном виде
 nownum: array of integer; //Массив текущих значений счетчиков при переборе
 firstitem: string; //Строка 1
 seconditem: string; //Строка 2
begin
 //Обрабатываем данные
 firststring:=Edit1.Text;
 secondstring:=Edit2.Text;
 //Разбиение шаблонов 1 и 2 на константы и счетчики
 counters:=-1;
 SetLength(firstconst,1);
 SetLength(secondconst,1);
 SetLength(minstring,1);
 SetLength(maxstring,1);
 SetLength(minnum,1);
 SetLength(maxnum,1);
 ii:=1;
 //Разбиваем 1 шаблон
 while ii<=length(firststring) do begin //Перебираем строку
   if firststring[ii]="["then begin //Найден счетчик
     ii:=ii+1; //Собираем минимум
     counters:=counters+1; //Увеличиваем счетчик счетчиков
     SetLength(firstconst,(Length(firstconst)+1)); //Увеличиваем массивы минимумов и максимумов
     firstconst[counters+1]:="";
     SetLength(minstring,(Length(minstring)+1));
     SetLength(maxstring,(Length(maxstring)+1));
     SetLength(minnum,(Length(minnum)+1));
     SetLength(maxnum,(Length(maxnum)+1));
     while firststring[ii]<>"-" do begin //Пока не встретили "-" собираем число
       minstring[counters]:=minstring[counters]+firststring[ii];
       ii:=ii+1;
     end;
     minnum[counters]:=StrToInt(minstring[counters]); //Получаем минимум в виде числа
     ii:=ii+1; //Пропускаем "-"
     while firststring[ii]<>"]" do begin //Пока не встретили "]" собираем максимум
       maxstring[counters]:=maxstring[counters]+firststring[ii];
       ii:=ii+1;
     end;
     maxnum[counters]:=StrToInt(maxstring[counters]); //Получаем минимум в виде числа
     ii:=ii+1; //Переходим к след. символу в константе
   end else begin //Обрабатываем константу
     firstconst[counters+1]:=firstconst[counters+1]+firststring[ii];
     ii:=ii+1;
   end;
 end;
 //Разбиваем 2 шаблон
 SetLength(secondconst,(Length(firstconst)));
 ii:=1;
 j:=0;
 secondconst[j]:="";
 while ii<=length(secondstring) do begin //Перебираем строку
   if secondstring[ii]<>"[" then begin
     secondconst[j]:=secondconst[j]+secondstring[ii];
     ii:=ii+1;
   end
   else begin
     j:=j+1;
     secondconst[j]:="";
     ii:=ii+2;
   end;
 end;

 //Начинаем обрабатывать сами строки
 //Выясняем полное число всех строк
 fullstrnum:=1;
 for i:=0 to counters do fullstrnum:=fullstrnum*(maxnum[i]-minnum[i]+1);
 //Генерируем и обрабатываем все строки
 SetLength(nownum,(counters+1));
 for i:=0 to (fullstrnum-1) do begin
   firstitem:="";
   seconditem:="";
   //Разбиваем текущий номер строки на разряды (значения счетчиком)
   ostatok:=i;
   for ii:=0 to counters do begin
     nownum[ii]:=ostatok;
     for j:=(ii+1) to counters do nownum[ii]:=trunc(nownum[ii]/(maxnum[j]-minnum[j]+1));
     for j:=(ii+1) to counters do ostatok:=ostatok-nownum[ii]*(maxnum[j]-minnum[j]+1);
   end;
   //Собираем строку из констант и счетчиков
   for ii:=0 to counters do firstitem:=firstitem+firstconst[ii]+IntToStr(nownum[ii]+minnum[ii]);
   firstitem:=firstitem+firstconst[counters+1];
   for ii:=0 to counters do seconditem:=seconditem+secondconst[ii]+IntToStr(nownum[ii]+minnum[ii]);
   seconditem:=seconditem+secondconst[counters+1];

   //Строки получены. Можно с ними работать (здесь просто вывод в memo).
   Memo1.Lines.Add(firstitem));
   Memo1.Lines.Add(seconditem));
 end;
end;                  

Думаю, много лишних движений, но работает.


 
lazy BEGINner ©   (2011-08-21 01:36) [12]

Еще пару строк напоследок по сути. Если, вдруг, кому-то станет интересно.
Задача оказалось чисто алгоритмической.
В первую, когда взгляд зацепляется за счетчики, руки тянутся написать кучу циклов, но вот число то этих циклов заранее и неизвестно. Для меня проблема была отойти от этого подхода, и понять, что цикл на самом деле один. А счетчики, это своего рода разряды, заранее нам уже известного числа. И задача заключается в том, чтобы внутри одного цикла разбить текущее значение переменной цикла на эти разряды. В итоге все просто.

Да и еще, данный код не совсем соответствует условием. А именно, для счетчика [01-10] он выдаст первым значением 1, а не 01, но, думаю, добавить лишний нолик, где это необходимо, уже не проблема.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.12.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.004 c
1-1274783463
Deltas
2010-05-25 14:31
2011.12.04
Анимация сворачивания окна


2-1313560814
Oleg_teacher
2011-08-17 10:00
2011.12.04
Взаимодействие ворд+делфи


15-1312916966
Petr V. Abramov
2011-08-09 23:09
2011.12.04
carrier planning


8-1220686144
dmitry_12_08_73
2008-09-06 11:29
2011.12.04
Реализация полупрозрачной рамки, прямоугольника


1-1276083003
Омлет
2010-06-09 15:30
2011.12.04
TDateTimePicker - ввод максимальной даты с клавиатуры





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский