Форум: "Начинающим";
Текущий архив: 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