|
Вопрос # 4 835/ вопрос решён / |
|
Здравствуйте! Уважаемые эксперты! это опять я.
в StringGrid нужно проверить содержимое ячейки и выполнить действие(изменение шрифта и цвета ячейки).
выполняю проверку (код описан).
собственно вопрос, можно ли заменить это огромное перечисление
каким-нибудь набором? пробовал Set of компилятор выдаёт ошибку про несовместимость данных.
 |
Вопрос задал: Ham_ele_on (статус: Посетитель)
Вопрос отправлен: 18 декабря 2010, 19:51
Состояние вопроса: решён, ответов: 1.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, Ham_ele_on!
Да, можно! И что интересно, оно будет даже несколько быстрее вашего кода, заметно легче модифицироваться, иметь пару плюшек и выглядеть красивее.
Для начала объявим себе где то глобально или как свойство формы TStringList, который будет хранить слова, которые нужно будет сравнивать.
private
sl:TStringList;
В конструкторе формы (FormCreate) создадим и заполним его
sl := TStringList.create;
sl.add('Привет');
sl.add('пока');
sl.add('Да');
sl.add('нет');
sl.add('возможно');
// отсортируем его.
sl.sorted := true;
// это очень хорошо, так как теперь поиск будет не ленейный, а логарифмический.
// к примеру, на 1024 элемента, при линейном поиске нужно сделать в среднем 512 шагов, а в линейном - 10
теперь при удалении формы (FormDestroy)добавим освобождение ресурсов
sl.free;
А теперь самое интересное. Условие для сравнения.
if (sl.find(SG.Cells[ACol,ARow]) <> -1) then begin
// строка найдена.
end;
Преимущества - теперь массив строк можно менять на лету - все будет работать.
Преимущество второе, скрытое. у TStringList есть свойство object, куда можно добавлять свой объект. Можно создать свои объекты, которые хранят параметры ячейки для данного слова и получать все что угодно:) Но это уже для домашнего задания.
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 18 декабря 2010, 21:25
Оценка за ответ: 5
|
Мини-форум вопроса
Всего сообщений: 58; последнее сообщение — 24 февраля 2011, 11:23; участников в обсуждении: 3.
Страницы: [« Предыдущая] [1] [2] [3] [Следующая »]
|
Вадим К (статус: Академик), 17 февраля 2011, 10:41 [#21]:
Сделаю маленькую подсказку. Какая бы не была сортировка, ее можно разложить на две части
- выбор элементов и расстановка их в правильном порядке
- сравнение двух элементов, для определения их порядка.
и если первой частью занимаются внутренности компонента и нам туда лазить не нужно, то с второй ему нужно помочь. Наша задача определить некую функцию (формат ее можно найти по ссылкам), которую StringList будет вызывать каждый раз, когда ему нужно сравнить два элемента и узнать, кто из них "больше". я не даром взял слово "больше" в кавычки, потому что можно определить так, что к примеру "1" < "2" и "00001" < "02". тут уж только по потребностям.
Функция должна возвращать 1, если первый аргумент больше, -1, если наоборот и 0, если элементы "равны".
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Ham_ele_on (статус: Посетитель), 17 февраля 2011, 17:56 [#22]:
>Неужели трудно погуглить?
до того как вас "задолбать", я сначала спросил у гугла и яндекса, много чего нашёл в том числе и ссылки которые вы мне предоставили, прочитал, ничё немогу понять.
Вадим К- интуитивно я всё это понимаю, но реализовать не получается.
нашёл вот такую реализацию procedure GetNumAndStr(s: String; var Num: Integer; var St: String);
var i,k: Integer;
begin
St:= ''; k:= 0; Num:= 0;
for i:= 1 to Length(s) do
if s[i] in ['0'..'9'] then St:= St + s[i] else begin k:= i; break; end;
if St <> '' then Num:= StrToInt(St);
if k=0 then St:='' else St:= Copy(s,k,MaxInt);
end;
function TwoCompare(L: TStringList; i1,i2: Integer): Integer;
var Num1,Num2: Integer; St1,St2: String;
begin
GetNumAndStr(L[i1],Num1,St1);
GetNumAndStr(L[i2],Num2,St2);
if Num1=Num2 then Result:= CompareStr(St1,St2) else Result:= Num1-Num2;
end;
procedure ComboSort(c: TComboBox);
var SL: TStringList;
begin
SL:= TStringList.Create;
SL.Assign(c.Items);
SL.CustomSort(TwoCompare);
c.Items.Assign(SL);
SL.Free;
end;
с GetNumAndStr всё понятно, берём строку и раскладываем её на цифры и буквы.
а вот дальше "тёмный лес"
откуда берутся параметры function TwoCompare(L: TStringList; i1,i2: Integer): Integer;
ну с L понятно это стринглист, а что такое i1,i2??
если в тупую копирую то всё работает, но когда я не понимаю КАК это работает, мне как то не по себе.
|
|
Вадим К (статус: Академик), 17 февраля 2011, 18:51 [#23]:
i1 и i2 - это номера элементов. то есть, номера строк.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
min@y™ (статус: Доктор наук), 17 февраля 2011, 19:00 [#24]:
Давай начнём сначала. Какие числа у тебя будут храниться в списке? Плясать надо именно от этого.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Ham_ele_on (статус: Посетитель), 17 февраля 2011, 19:50 [#25]:
вот в этом то и гвоздь, числа будут с разделителем 1000*2000
приведённый здесь пример не до конца работает,
2000*6000 стоит после 2000*12000
его нужно переделывать, но я не могу этого сделать, так как не понимаю как это работает.....номера строк "возникают" откуда???
|
|
min@y™ (статус: Доктор наук), 17 февраля 2011, 20:06 [#26]:
А нухрена всё это? Я имею в виду хранение чисел в виде произведения Х*Y? Может эту задачу можно решить как-то по-другому?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Ham_ele_on (статус: Посетитель), 17 февраля 2011, 20:14 [#27]:
это не произведение. "*" это разделитель, таким образом определяется прямоугольная область, разделитель может быть любым. можно конечно и x=2000,y=3000, но мне кажется, что в целом проблема не решится. может я не прав конечно, но использование стринг лист мне почему то показалось наиболее удобным
задача стоит такая, есть несколько прямоугольников.мы воодим размеры и проверяем есть ли похожий прямоугольник или меньший по размерам. вообщем подбирается максимально близкий по размерам
P\S.за статью спасибо, об этом правиле забыл совсем
|
|
min@y™ (статус: Доктор наук), 17 февраля 2011, 22:38 [#28]:
А зачем тогда их сортировать-то? Какой тогда критерий сортировки, кроме площади?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Ham_ele_on (статус: Посетитель), 17 февраля 2011, 23:30 [#29]:
не площадь, а длинна и ширина, габаритные размеры прямоугольника.
есть три прямоугольника 500*700,500*900,700*800
мы хотим проверить размер 400*600, в принципе, все прямоугольники подходят, но нам нужно, что бы был выбран наиболее близкий по размеру, то есть 500*700. при сортировке
это легко достигается, мы пилим каждую строку на две части и проверяем эти части, и как только результат достигнут, выходим.
но при неправильной сортировке, сначало будет результат больший, а вот это уже не верно. то есть из 2100*6000 и 2100*12000 вперёд выберется 2100*12000 каким бы нибыл размер..
|
|
Вадим К (статус: Академик), 17 февраля 2011, 23:53 [#30]:
откуда индексы? они же номера строк?
Суть сортировки понимаем? нужно выставить элементы так, что бы каждый последующий элемент был больше (или меньше) предыдущего. А для этого их нужно сравнивать. Вот процедура сортировки берет попарно их и сравнивает (внутри оно то на самом деле сложнее, но это на потом).
В принципе она то и элементы могла бы давать, но их нужно либо по ссылке давать, либо по значению, а это плохо. В первом случае можно будет отделаться через указатели и приведение типа (а это ох как чревато ошибками), во втором случае сложно сделать универсальную процедуру.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Ham_ele_on (статус: Посетитель), 18 февраля 2011, 08:01 [#31]:
>откуда индексы? они же номера строк?
беруться то они откуда??? не сам же компилятор их придумывает??
или их передаёт функция CustomSort?
вот мои действия:
1)я раскладываю строку на числа(до и после разделителя).
procedure GetNumAndStr(s: String; var Num: Integer; var St: String);
begin
Num:=strtoint(Copy(s,1,Pos('*',s)-1));
Num2:=strtoint(Copy(s,Pos('*',s)+1,Length(s)));
end;
2)если первая половина является рвной то нужно проверить вторую.(вот как работает эта функция, я не до конца понимаю)
function TwoCompare(L: TStringList; i1,i2: Integer): Integer;
var Num1,Num2: Integer; St1,St2: String;
begin
GetNumAndStr(L[i1],Num1,N);
GetNumAndStr(L[i2],Num2,N2);
if Num1=Num2 then Result:= Max(N,N2) else Result:= Num1-Num2;
end;
но такой вариант не работает, что не так?
|
|
min@y™ (статус: Доктор наук), 18 февраля 2011, 08:16 [#32]:
А размеры прямоугольников имеют какие-то пределы? Какой максимальный размер стороны прямоугольника?
Сдаётся мне, сортировать тут не строки надо, а числа.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Ham_ele_on (статус: Посетитель), 18 февраля 2011, 09:45 [#33]:
размеры прямоугольников это и есть строки в StringList.(некоторые остатки материала, одна строка один кусок X/Y)
нам нужно узнать есть ли подходящий кусок(вводится в ручную в edit-ы) или нам нужно бежать за новым полноразмерным листом материала.
по идее да, сортировать нужно числа, но только пару чисел, именно пару X/Y по возрастанию.
|
|
min@y™ (статус: Доктор наук), 18 февраля 2011, 10:14 [#34]:
Цитата (Ham_ele_on):
сортировать нужно числа, но только пару чисел, именно пару X/Y по возрастанию.
Ну дык вот я и спрашиваю, какие пределы этих чисел. Я так понял, это миллиметры, да? Если максимальный размер стороны прямоугольника не превышает 65535 мм, то тут и StringList не нужен, и сортировка будет в разы быстрее из-за ненадобности преобразования "строка --> пара чисел".
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Ham_ele_on (статус: Посетитель), 18 февраля 2011, 10:33 [#35]:
ага миллиметры, нет не превышает 65535.
как? и как хранить?
|
|
min@y™ (статус: Доктор наук), 18 февраля 2011, 10:46 [#36]:
Цитата (Ham_ele_on):
ага миллиметры, нет не превышает 65535.
Замечательно! Тогда пара X*Y спокойно укладывается в 32-битное беззнаковое целое, т.е. Cardinal (DWORD), где, например, младшее слово - это X, а старшее - Y, или наоборот.
Хранить списки на HDD можно в простом бинарном файле.
Сортировать с помощью TList - самое то. Написать функцию типа TListSortCompare() - это 5-10 минут времени.
А выводить на экран можно вообще как угодно, хоть в TListBox в виртуальном режиме.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Вадим К (статус: Академик), 18 февраля 2011, 10:46 [#37]:
в целом, в этой задаче все это постоянное преобразование может убить на корню производительность. если конечно там не 20-30 строк. тогда и печалится не стоит на первое время.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
min@y™ (статус: Доктор наук), 18 февраля 2011, 10:52 [#38]:
Цитата (Вадим К):
все это постоянное преобразование может убить на корню производительность
Вот я и предложил альтернативчик.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Ham_ele_on (статус: Посетитель), 18 февраля 2011, 10:53 [#39]:
то есть была одна не решённая задача, теперь их две. очень хорошо
точнее одна из задач так и не решена, функцию всё равно писать, а я всё равно не понимаю как она работает. TList это универсальный контейнер данных, но я почему то думал, что он тоже с строками работает
|
|
min@y™ (статус: Доктор наук), 18 февраля 2011, 11:11 [#40]:
Сортировку я тебе, так и быть напишу. Давай исходные данные и критерии сравнения, желательно с примерами.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
Страницы: [« Предыдущая] [1] [2] [3] [Следующая »]
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|