Можно ли реализовать связанные списки объектов разных типов?
Модератор: Модераторы
>>Fpc-Stl - опять 25 страниц читать. Пойду, что ж делать, раз настаиваете.
че там читать та? исходники есть, минимальные примеры есть, структуры данных классические...
Надо свести задачу к однотипному value, т.е. по ключу в виде стринга из хэшмапы получается описание что этот ключик значит (грубо говоря тип стринг-чекбокс и его индекс в линейной структуре например в векторе). Имеем хэшмап описаний, вектор стрингов и вектор боолеанов
>>В DeCAL меня привлекли не столько сами структуры, сколько алгоритмы, посмотрите примеры, насколько всё интересно там.
1 Ненадо завязываться на variant - ущербный тип (имхо)
2 DeCAL существенно проигрывает в скорости перед fpc-stl
3 Неустраивает fpc-stl - в последних версиях есть rtl-generics - делфи совместимая реализация generics.collections, но я ее не пользовал - ниче сказать про нее немогу
Добавлено спустя 7 минут 30 секунд:
Re: Можно ли реализовать связанные списки объектов разных типов?
vitaly_l
>>а он по этому поводу седуксинчик стаканами
по пятницам я пивко пью стаканами.
Перенял опыт "штурма" у алекс2013)) это никакой не штурм. нечего и некому штурмовать.
че там читать та? исходники есть, минимальные примеры есть, структуры данных классические...
Надо свести задачу к однотипному value, т.е. по ключу в виде стринга из хэшмапы получается описание что этот ключик значит (грубо говоря тип стринг-чекбокс и его индекс в линейной структуре например в векторе). Имеем хэшмап описаний, вектор стрингов и вектор боолеанов
>>В DeCAL меня привлекли не столько сами структуры, сколько алгоритмы, посмотрите примеры, насколько всё интересно там.
1 Ненадо завязываться на variant - ущербный тип (имхо)
2 DeCAL существенно проигрывает в скорости перед fpc-stl
3 Неустраивает fpc-stl - в последних версиях есть rtl-generics - делфи совместимая реализация generics.collections, но я ее не пользовал - ниче сказать про нее немогу
Добавлено спустя 7 минут 30 секунд:
Re: Можно ли реализовать связанные списки объектов разных типов?
vitaly_l
>>а он по этому поводу седуксинчик стаканами
по пятницам я пивко пью стаканами.
Перенял опыт "штурма" у алекс2013)) это никакой не штурм. нечего и некому штурмовать.
Последний раз редактировалось zub 24.03.2017 15:08:17, всего редактировалось 1 раз.
zub писал(а):Надо свести задачу к однотипному value ... это никакой не штурм. нечего и некому штурмовать.
Вот видишь, благодаря "штурму", даже ты уже стал понимать почему художники предлагали string's в рекордах и хочешь привести всё к одному типу.
На вот киношку про экологию посмотри: https://www.youtube.com/watch?v=tn-zGJDl4TM, там много красивых картинок с видами Земли.
vitaly_l писал(а):Рекомендую заменить DeCal на один record, в котором предусмотреть все значения формы из HTML, благо все они заранее известны, тогда вы сможете хранить много однотипных документов в массиве. Заполнять и перебирать их. А вообще, раз уж вы объединили темы, то vada Вам правильно подсказал, избавьтесь от HTML. Элементы на форме - тоже можно скролить как портянку.
В том-то и дело, что НЕТ. На примере одного заявления я начал топик, но форм заявлений больше, все они разные и постоянно изменяются. Поэтому и ответ про HTML - что проще, переделывать форму или чуток подправить html-шаблон?
Добавлено спустя 2 минуты 49 секунд:
Re: Можно ли реализовать связанные списки объектов разных типов?
zub писал(а):Надо свести задачу к однотипному value, т.е. по ключу в виде стринга из хэшмапы получается описание что этот ключик значит (грубо говоря тип стрингчекбокс и его индекс в линейной структуре например в векторе). Имеем хэшмап описаний, вектор стрингов и вектор боолеанов
Я, кажется, начал понимать, но давайте для тупых художников разберем))
У меня есть список ключ-значение, плюс появляется третье неизвестное - тип значения (ну или пусть тип ключа, string или bool).
Насчет хэшмапа и векторов опишите еще раз.
java73 писал(а):что проще, переделывать форму или чуток подправить html-шаблон?
На первый взгляд, без разницы. Но при внимательном рассмотрении абсолютно ясно, что родные лазаревские контролы - проще размещать, нежели формировать HTML и потом из HTML получать данные. Вы в этой части - делаете Филькин труд. Все элементы на формах - можно набирать динамически.
java73 писал(а):тупых художников
Говорите пожалуйста в единственном лице, меня к себе не приписывайте.
.
хэшмап - мап для типов которые быстрее сравнивать по их хэшу, стринг какраз такой тип. можно использовать просто мап, но он будет для сортировки и поиска сравнивать стринги - это медленней чем сравнивать хэши
вектор - грубо говоря линейный массив.
в фпц-стл это THashmap, TMap, TVector соответственно.
грубо говоря както так:
получаем из TKey2Desk описание ключа, в зависимости от KeyType лезем или в TStringsVector или в TBooleanVector за конкретикой.
Еще лучше будет если в TKeyDesk сразу хранить методы для обработки этих ключей - тогда небудет разницы что это - стринг или булен, получили описание из TKey2Desk, выполнили хранимые там методы...
вектор - грубо говоря линейный массив.
в фпц-стл это THashmap, TMap, TVector соответственно.
грубо говоря както так:
Код: Выделить всё
TKeyType=(TKT_Boolean,TKT_String);
TKeyDesk=record
KeyType:TKeyType;
KeyIndex:Integer;
KeySomethingData:TKeySomethingData;
...
end;
TKey2Desk=THashmap<string,TKeyDesk>;//илиTKey2Desk=TMap<string,TKeyDesk>;
TStringsVector=TVector<string>
TBooleanVector=TVector<boolean>получаем из TKey2Desk описание ключа, в зависимости от KeyType лезем или в TStringsVector или в TBooleanVector за конкретикой.
Еще лучше будет если в TKeyDesk сразу хранить методы для обработки этих ключей - тогда небудет разницы что это - стринг или булен, получили описание из TKey2Desk, выполнили хранимые там методы...
vitaly_l писал(а):На первый взгляд, без разницы. Но при внимательном рассмотрении абсолютно ясно, что родные лазаревские контролы - проще размещать, нежели формировать HTML и потом из HTML получать данные. Вы в этой части - делаете Филькин труд. Все элементы на формах - можно набирать динамически.
Чтобы разместить лазаревские контролы нужно как минимум открыть проект, изменить форму, написать новые обработки, пересобрать проект и обновить у пользователя. По вашему это тоже самое, что поменять один html файл, без какого либо воздействия на саму программу?
java73 писал(а):Чтобы разместить лазаревские контролы нужно как минимум открыть проект, изменить форму, написать новые обработки, пересобрать проект и обновить у пользователя. По вашему это тоже самое, что поменять один html файл, без какого либо воздействия на саму программу?
Ключевое слово в моей фразе: динамически. Оно - не от слова динамить. Абсолютно любые элементы, можно создавать динамически в процессе работы программы. И соответственно, набирать их динамически как в HTML.
А почему Вы говорили про PHP ? Вы хотите разместить этот свой проект в интернете? Суть в том что если Ваш проект должен быть в интернете, то лучше потратить несколько дней на изучение PHP, т.к. чтобы научиться программировать на Паскале - нужны годы.
.
Последний раз редактировалось vitaly_l 24.03.2017 16:20:34, всего редактировалось 1 раз.
Контролы можно разместить в рантайме на основе какогото описания загруженого в рантайме. В часности можно парой строк загрузить левую лфм, лижбы контролы описаные ей были зареганы в программе.
zub писал(а):zub » 24.03.2017 16:32:32
Я вот в общем еще подумал, должна быть следующая структура, включающая в себя следующие элементы:
Код: Выделить всё
TagParse KeyType Key Value
======== ======= ======== ========
"<%Check1%>" "bool" "Check1" "On"
"<%Check2%>" "bool" "Check2" ""
"<%edit1%> "str" "edit1" "some text"
Key и Value берутся при обработке OnFormSubmit в htmlviewer из полей формы, из Key делается TagParse путем обрамления нужными символами и keytype определяется также путем чтения соотв. свойства, предоставленного htmlviewer.
Так вот, главным будет тогда элемент TagParse, потому что следующая обработка выглядит так (при генерировании html из шаблона с заменой тэгов на данные) упрощенно:
Код: Выделить всё
s1:=GetNextStringWithTag // построчно читаем html шаблон
s:=GetNextTag (s1); // возвращает что-то типа "<%check1%>, тут я упростил, в строке ведь может и не быть тэгов
if MyStruct[s].KeyType="bool"
then RepalceBoolValue(s1, MyStruct[s].Value)
else ReplaceStrValue(s1, MyStruct[s].Value);
Вот, на какой основе мне тогда построить эту структуру? То есть элемент TagValue используется как ключ, поиск идет на соответствующее ему значение KeyType для проверки и потом риплейсится
Добавлено спустя 2 минуты 7 секунд:
Re: Можно ли реализовать связанные списки объектов разных типов?
vitaly_l писал(а): т.к. чтобы научиться программировать на Паскале - нужны годы.
именно потому, что эти годы я уже потратил, вот и пишу на паскале)
Нет, изначально не было нужды делать веб. Меня устраивает оконная приложуха, но хочется привнести некоторые удобства в проект.
java73
чето ты усложняешь. я бы делал как то так:
<%Check1%>,<%Check2%>, <%edit1%> - синтаксис бы чуток усложнил, чтоб можно было без проблем разделить на команду и параметр
например
<%Check_1%>,<%Check_2%>, <%edit1_%> - режем по нижнему прочерку - имеем например "Check" и "2". ищем "Check" в TKey2Desk, находим, берем оттуда процедуру замены, в эту процедуру передаем "2"(или уже в виде интегер) и координаты <%Check_2%> в исходном потоке, она меняет <%Check_2%> на то что надо.
Сам имею аналогичную процедуру подстановки всякой всячины в стринг.
например строку @@[NMO_Prefix]@@[NMO_BaseName]@@[NMO_Suffix]_%%DATE она меняет на 1BTH22_03.17 потомучто NMO_Prefix='1', NMO_BaseName='BTH', NMO_Suffix='22' - это "переменные" в внутреннем "скриптовом" языке, %%DATE - подстановка месяца и года.
соответственно в TKey2Desk зарегистрированы '@@' - подстановщик "переменных" - он считает что за ним в квадратных скобках идет имя переменной, '%%' подстановщик разных "спецзначений" - за ним просто идет название "спецзначения"
чето ты усложняешь. я бы делал как то так:
<%Check1%>,<%Check2%>, <%edit1%> - синтаксис бы чуток усложнил, чтоб можно было без проблем разделить на команду и параметр
например
<%Check_1%>,<%Check_2%>, <%edit1_%> - режем по нижнему прочерку - имеем например "Check" и "2". ищем "Check" в TKey2Desk, находим, берем оттуда процедуру замены, в эту процедуру передаем "2"(или уже в виде интегер) и координаты <%Check_2%> в исходном потоке, она меняет <%Check_2%> на то что надо.
Сам имею аналогичную процедуру подстановки всякой всячины в стринг.
например строку @@[NMO_Prefix]@@[NMO_BaseName]@@[NMO_Suffix]_%%DATE она меняет на 1BTH22_03.17 потомучто NMO_Prefix='1', NMO_BaseName='BTH', NMO_Suffix='22' - это "переменные" в внутреннем "скриптовом" языке, %%DATE - подстановка месяца и года.
соответственно в TKey2Desk зарегистрированы '@@' - подстановщик "переменных" - он считает что за ним в квадратных скобках идет имя переменной, '%%' подстановщик разных "спецзначений" - за ним просто идет название "спецзначения"
Ладно, я мож как-то не так объясняюсь) курну на выходных про sdl и decal, сам попробую что-то набросать, потом принесу сюда.
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
decal работает очень быстро, реализации с дженериками - медленнее. Проверял несколько лет назад, может, в последних версиях дженерики ускорили, не знаю.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
vitaly_l писал(а):О графах речи не шло.
очередь это пример вырожденного графа.. и даже при этом это может быть: односвязная очередь, двусвязная, стек, дек, кольцевая очередь (в свою очередь одно и двусвязная)... и каждая организуется на программном уровне немного по разному.
Причем, я не уверен, что перечислил все типы. И, самая изюминка, любому графу абсолютно без разницы что будет узлом (листом). На программном уровне код управляющий указателем зависит только от типа графа. Key, Value ets... это уже относится к коду управляющему узлом(листом). И, самое забавное, сам код создания и управления списками (очередями) можно подсмотреть в практически самых первых учебниках по паскалю и он даже будет работать)))
Кстати, если заменить в нем запись на класс, то в нем легко можно реализовать как низкоуровневый код, так и высокоуровневый. У меня где-то даже валялся пример, то так как это была лишь проба, то я не стал его заканчивать (написание ерунда, а вот отладка слишком нудная).
[обновил - упростил вариант модуля]
Итак, вот мое творение))
Сделано на основе DMap, ассоциированного массива из deCAL. Почему все ж я выбрал deCAL? Да потому что в его документации с первого раза всё понял. Я честно пытался врубиться в fcl-stl. Но в пером случае все прошло быстро - от проекта на бумажке до готового класса - час, все остальное на отладку строковых функций).
Пример использования в том же коротком проекте испытательном:
Вывод heaptrc:
Итак, вот мое творение))
Сделано на основе DMap, ассоциированного массива из deCAL. Почему все ж я выбрал deCAL? Да потому что в его документации с первого раза всё понял. Я честно пытался врубиться в fcl-stl. Но в пером случае все прошло быстро - от проекта на бумажке до готового класса - час, все остальное на отладку строковых функций).
Код: Выделить всё
const
JC_EMPTYBOX = '☐'; // пустой бокс
JC_CHECKEDBOX = '☑'; // отмеченный бокс
type
{ TMapElement }
TMapElement = class
TagKey: string;
Key: string;
KeyType: string;
Value: string;
constructor Create (_key, _keytype, _value: string);
end;
{ TJHTMLParse }
TJHTMLParse = class
private
fHTMLFile: TStringList;
fReady: boolean;
fValues: DMap;
public
property HTMLFile: TStringList read fHTMLFile write fHTMLFile;
property Values: DMap read fValues;
property Ready: boolean read fReady;
constructor Create (filename: string);
destructor Free;
procedure Add (key, keytype, value: string);
function Parse (filename: string): boolean;
end;
implementation
{ TMapElement }
constructor TMapElement.Create(_key, _keytype, _value: string);
begin
TagKey:='<%'+_key+'%>';
Key:=_key;
KeyType:=_keytype;
Value:=_value;
end;
{ TJHTMLParse }
constructor TJHTMLParse.Create(filename: string);
begin
inherited Create;
try
fValues:=DMap.Create;
HTMLFile:=TStringList.Create;
HTMLFile.LoadFromFile(filename);
if HTMLFile.Count>0 then fReady:=TRUE else fReady:=FALSE;
except
fReady:=FALSE;
end;
end;
destructor TJHTMLParse.Free;
begin
ObjFree(fValues);
fVAlues.Free;
HTMLFile.Free;
end;
procedure TJHTMLParse.Add(key, keytype, value: string);
var
mapE: TMapElement;
begin
mapE:=TMapElement.Create(key,keytype,value);
fValues.putPair([mapE.TagKey,mapE]);
end;
function TJHTMLParse.Parse(filename: string): boolean;
var
i,p,p1: integer;
Cur, CurTag, Rep: string;
iter: DIterator;
E: TMapElement;
begin
if not Ready then exit;
for i:=0 to HTMLFile.Count-1 do
begin
Cur:=HTMLFile[i];
p:=Pos('<%',Cur);
if p=0 then Continue; // обрабатываем только строки, содержащие спец.тэги
p1:=Pos('%>',Cur);
CurTag:=Copy(Cur,p,p1-p+2);
iter:=fValues.locate([CurTag]);
if not atEnd(iter) then
begin
E:=getObject(iter) as TMapElement;
Rep:=E.Value;
if E.KeyType='bool' then
case E.Value of
'': Rep:=JC_EMPTYBOX;
'On': Rep:=JC_CHECKEDBOX;
end;
HTMLFile[i]:=ReplaceStr(Cur,CurTag,Rep);
end;
end;
try
HTMLFile.SaveToFile(filename);
Result:=TRUE;
except
Result:=FALSE;
end;
end;
Пример использования в том же коротком проекте испытательном:
Код: Выделить всё
procedure TForm1.Button2Click(Sender: TObject);
var
JParse: TJHTMLParse;
s_key,s_type,s_value: string;
i: integer;
//Iter: DIterator;
E: TMapElement;
begin
JParse:=TJHTMLParse.Create('11.t');
if JParse.Ready then
for i:=0 to HTML.FormControlList.Count-1 do begin
if TFormControlObj(HTML.FormControlList.Items[i]).TheControl is TCheckbox then
s_type:='bool'
else s_type:='str';
s_key:=HTML.FormControlList[i].Name;
s_value:=GetValue(i); // с этим чуть сложнее из-за html формы, но проще, чем парсить строку
JParse.Add(s_key,s_type,s_value);
end;
{// выведем в мемо для проверки
Memo1.Lines.Clear;
Iter:=JParse.Values.start;
While iterateOver(Iter) do
begin
E:=getObject(Iter) as TMapElement;
Memo1.Lines.Add(E.TagKey+', '+E.Key+', '+E.KeyType+', '+E.Value);
end; }
// генерируем новый файл на основе шаблона
if JParse.Parse('11_ready.html') then ShowMessage ('Успешно вышло')
else ShowMessage ('Случилось неведомое');
JParse.Free;
end;
Вывод heaptrc:
Код: Выделить всё
Heap dump by heaptrc unit
51246 memory blocks allocated : 3965877/4126416
51246 memory blocks freed : 3965877/4126416
0 unfreed memory blocks : 0
True heap size : 786432
True free heap : 786432
Вот залил итоговый модуль для парсинга))
https://bitbucket.org/java73/jhtmlparser/overview
https://bitbucket.org/java73/jhtmlparser/overview
