Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.12.04;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.01 c
15-1313181004
Юрий
2011-08-13 00:30
2011.12.04
С днем рождения ! 13 августа 2011 суббота


2-1313476457
Cobalt
2011-08-16 10:34
2011.12.04
Left side cannot be assigned to (D2007)


4-1252505872
Игорь
2009-09-09 18:17
2011.12.04
SYSTEM_HANDLE_INFORMATION


15-1304575753
samalex2504
2011-05-05 10:09
2011.12.04
Нет копирования содержимого компонентов Delphi в Excel и Word


2-1313414426
TComponent
2011-08-15 17:20
2011.12.04
Использование курсора для навигации по страницам в TWebBrwser-e