Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.08.2012, 12:13   #1
rainbow
Форумчанин
 
Регистрация: 06.09.2008
Сообщений: 156
По умолчанию Подсчет элементов в StringGrid

Доброго времени суток!
Возникла следующая проблема:
Необходимо подсчитать количество элементов в StringGrid за исключением областей, заданных в массиве TRect
Код:
var
massivobj: array of TRect; //координаты исключаемых областей
b,i,j,k,s:integer
begin
...........
// k - количество значений в массиве massivobj
s:=0; //обнуляем счетчик элементов
for i := 0 to StringGrid1.ColCount-1 do
for j := 0 to Stringgrid1.RowCount-1 do
for b:= 0  to k-1 do
if (i < massivobj[k].Left) and (i > massivobj[k].Right) //
and (j < massivobj[k].Top) and (j > massivobj.[k].Bottom) then
inc (s) //добавляем счетчик элементов
............
end;
Но счетчик элементов s почему то не срабатывает. Помогите пожалуйста! Спасибо!
Ужас, как я устал от тупизны...

Последний раз редактировалось rainbow; 06.08.2012 в 12:17.
rainbow вне форума Ответить с цитированием
Старый 06.08.2012, 12:42   #2
astecenko
Homo Interneticus
Форумчанин
 
Аватар для astecenko
 
Регистрация: 04.03.2011
Сообщений: 611
По умолчанию

Операция логического умножения (and) будет давать ложь если один из аргументов ложь.
Ложь = 0, Истина = 1
Умножить что угодно на 0 будет 0

По логике i не может быть одновременно и меньше massivobj[k].Left и больше massivobj[k].Right и т.п. (хотя что именно Вы туда занесли - мне не ведомо)

Почитайте про логические операции в Delphi, булеву алгебру и правильно составьте условие для проверки.

Upd
Кстати переменную цикла b может всё же стоит использовать где-нибудь...

Последний раз редактировалось astecenko; 06.08.2012 в 12:44.
astecenko вне форума Ответить с цитированием
Старый 06.08.2012, 12:46   #3
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

а также
Код:
for b:= 0  to k-1 do
if (i < massivobj[k].Left) and (i > massivobj[k].Right) //
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 06.08.2012, 14:39   #4
rainbow
Форумчанин
 
Регистрация: 06.09.2008
Сообщений: 156
По умолчанию

Спасибо за советы.
Сделал так:
Цитата:
if (i<massivobj[b].Left) or ((i>=massivobj[b].Left) and (i<=massivobj[b].Right) and (j<massivobj[b].Top)) or
(i>massivobj[b].Right) or ((i>=massivobj[b].Left) and (i<=massivobj[b].Right) and (j>massivobj[b].Bottom)) then
inc(s);
Работает нормально, но только если k=1. При k>1 считает неправильно.
Ужас, как я устал от тупизны...
rainbow вне форума Ответить с цитированием
Старый 06.08.2012, 15:07   #5
astecenko
Homo Interneticus
Форумчанин
 
Аватар для astecenko
 
Регистрация: 04.03.2011
Сообщений: 611
По умолчанию

А накрутили то :-D
Так не проще?
Код:
if ((i<massivobj[b].Left) or (i>massivobj[b].Right)) and ((j<massivobj[b].Top) or (j>massivobj[b].Bottom)) then
inc(s);
astecenko вне форума Ответить с цитированием
Старый 06.08.2012, 15:43   #6
rainbow
Форумчанин
 
Регистрация: 06.09.2008
Сообщений: 156
По умолчанию

Цитата:
Сообщение от astecenko Посмотреть сообщение
А накрутили то :-D
Так не проще?
Код:
if ((i<massivobj[b].Left) or (i>massivobj[b].Right)) and ((j<massivobj[b].Top) or (j>massivobj[b].Bottom)) then
inc(s);
Так пробовал, программа считала неправильно.
Работает при k=1 из за того, что программа суммирует счетчик s на каждую область (или элемент TRect) отдельно, необходимо сделать, чтобы это условие проверялось на весь массив TRect целиком а не только на текущий элемент b. Только как это сделать, пока в голову не приходит.
Ужас, как я устал от тупизны...
rainbow вне форума Ответить с цитированием
Старый 06.08.2012, 15:50   #7
astecenko
Homo Interneticus
Форумчанин
 
Аватар для astecenko
 
Регистрация: 04.03.2011
Сообщений: 611
По умолчанию

Области в массиве TRect могут пересекаться?
astecenko вне форума Ответить с цитированием
Старый 06.08.2012, 16:07   #8
rainbow
Форумчанин
 
Регистрация: 06.09.2008
Сообщений: 156
По умолчанию

Цитата:
Сообщение от astecenko Посмотреть сообщение
Области в массиве TRect могут пересекаться?
Да, могут. Я вот и думаю как сделать. Пока ничего в голову не приходит, кроме как сделать двухмерный массив типа boolean размером StringGrid1.ColCount-1 на StringGrid1.RowCount-1, записать в него все значения true потом прогуляться по нему, и записать false там где эти области должны быть (или наоборот) и потом подсчитать количество элементов со значением true (или false), но это как то не очень хорошо получится.
Ужас, как я устал от тупизны...
rainbow вне форума Ответить с цитированием
Старый 06.08.2012, 16:16   #9
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Код:
var inrect: boolean;
   
inrect:=false;
// проверяем ВХОЖДЕНИЕ в каждую из областей
for b:=0 to k-1 do
  if (i>=massivobj[b].Left) and (i<=massivobj[b].Right) and (j>=massivobj[b].Top) and (j>=massivobj[b].Bottom) then 
  begin
    irect:=true; // вошла в ОДНУ ИЗ областей!!!!
    break;
  end;

// инвертирование результата эквивалентно НЕ ВХОДИТ НИ В ОДНУ 
if not inrect then inc(s);
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 06.08.2012 в 16:20.
evg_m вне форума Ответить с цитированием
Старый 07.08.2012, 07:02   #10
rainbow
Форумчанин
 
Регистрация: 06.09.2008
Сообщений: 156
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
Код:
var inrect: boolean;
   
inrect:=false;
// проверяем ВХОЖДЕНИЕ в каждую из областей
for b:=0 to k-1 do
  if (i>=massivobj[b].Left) and (i<=massivobj[b].Right) and (j>=massivobj[b].Top) and (j>=massivobj[b].Bottom) then 
  begin
    irect:=true; // вошла в ОДНУ ИЗ областей!!!!
    break;
  end;

// инвертирование результата эквивалентно НЕ ВХОДИТ НИ В ОДНУ 
if not inrect then inc(s);
Так тоже не хочет нормально считать
Придется видимо через массив типа boolean делать.
Сделал так:
Код:
var
tabl: array of array of boolean;
................................................
s:=0;
Setlength(tabl,StringGrid1.ColCount,StringGrid1.RowCount);
for i := 0 to Length(tabl[0])-1 do
for j := 0 to Length(tabl)-1 do
tabl[i,j]:=false; //заполняем вспомогательный массив значениями false
for i := 0 to StringGrid1.ColCount-1 do
for j := 0 to Stringgrid1.RowCount-1 do
for b := 0 to k-1 do
if (i>=massivobj[b].Left) and (i<=massivobj[b].Right)
and (j>=massivobj[b].Top) and (j<=massivobj[b].Bottom) then tabl[i,j]:=true //если попадает в область записываем в соответствующий
//элемент массива tabl
for i := 0 to Length(tabl[0])-1 do
for j := 0 to Length(tabl)-1 do
if not tabl[i,j] then inc(s); //если не входит в область, добавляем счетчик s
SetLength(tabl,0,0); //очищаем память tabl
Вроде нормально работает.
Ужас, как я устал от тупизны...

Последний раз редактировалось rainbow; 07.08.2012 в 08:42.
rainbow вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Подсчет элементов массива manoichi Общие вопросы C/C++ 1 09.01.2012 23:02
подсчет элементов в массиве счастливая Помощь студентам 1 17.05.2010 19:11
Подсчет ячеек определенного цвета в StringGrid Juliya_U Компоненты Delphi 4 22.04.2010 22:39
Подсчет количества цифр и их занесение в StringGrid artemavd Общие вопросы Delphi 4 27.12.2009 20:55