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

Вниз

Транспонировать массив из бит.   Найти похожие ветки 

 
Иван Второй   (2004-05-28 17:06) [0]

Я тут видел вопрос такой, но найти больше не могу,
есть думерный (M на N) массив A из бит, нужно его транспонировать

procedure Trans1(var A; M,N: Integer);
//Здесь что писать ?
end;


 
Erik1   (2004-05-28 17:13) [1]

Немного непонятно зачем M,N итак ясно, что у тебя размер SizeOf(Integer) - 4 байта = 16бит. Или у тебя что то другое, есть например такая конструкция
TBytes = set of Byte
или
TCannels = (0..7);
TBytes = set of TCannels;


 
pasha_golub ©   (2004-05-28 17:14) [2]

Сколько платишь? И будут ли еще лабораторки?


 
evvcom ©   (2004-05-28 17:20) [3]


> Немного непонятно зачем M,N итак ясно, что у тебя размер
> SizeOf(Integer) - 4 байта = 16бит

4 байта = 32 бит! M и N могут быть и больше 32.


> Иван Второй  

Хорошо, что не четвертый, а то б порезал всех. Ну и каков будет ответ на pasha_golub ©   (28.05.04 17:14) [2] ?


 
Erik1   (2004-05-28 17:25) [4]

evvcom
Описался разумеется 32бита.  M и N могут быть и больше, но откуда биты возмем?! Переменая "A" всего 32.


 
Sandman25+1   (2004-05-28 17:26) [5]

[4] Erik1   (28.05.04 17:25)

Там между A и M не запятая, а точка с запятой.


 
WebErr ©   (2004-05-28 17:39) [6]

Мда!

TBitsMatrix = class
private
  FBits: array of Integer;
  function GetBit(I, J: Integer): Boolean;
  procedure SetBit(I, J: Integer; Value: Boolean);
public
  constructor Create(M, N: Integer);
published
  property Bits[I, J: Integer]: Boolean read GetBit write SetBit;
end;

function Transpose(Source: TBitsMatrix): TBitsMatrix;

Ни на какие мысли по поводу implementation части не наталкивает? :))))
P.S. Где тот урод, который месяц назад сказал, что я в ООП в Делфи нифига не понимаю!!!


 
Сергей Первый   (2004-05-28 17:40) [7]


>  Иван Второй   (28.05.04 17:06)


А что такое транспонировать?


 
Иван Второй   (2004-05-28 17:41) [8]


>  Переменая "A" всего 32.

С чего бы. "А" таки ссылка на переменную любой длины,
не знаете что за var A;, тогда вам и RTFM

> Хорошо, что не четвертый, а то б порезал всех. Ну и каков
> будет ответ на pasha_golub ©   (28.05.04 17:14) [2] ?

Первому ответили на халяву. Если уже хотите денег, то я таки сам подум


 
WebErr ©   (2004-05-28 17:42) [9]

Вернее не знаю, как себя будет чувствовать property Bits в published секции, личше всего это переметить в public.


 
Иван Второй   (2004-05-28 17:43) [10]


> транспонировать

Если дана такая "А"
1 0 1 1
0 1 1 0
0 0 0 1

Транспонированная будет:
1 0 0
0 1 0
1 1 0
1 0 1


 
WebErr ©   (2004-05-28 17:49) [11]


constructor TBitsMatrix.Create(M, N: Integer);
var
  ASize: Integer;
  AWidth: Integer;
begin
  ASize := SizeOf(Integer) shl 3; // сколько бит в Integer"e
  AWidth := (N + ASize - 1) div ASize; // сколько Integer"ов в строке из N бит.
  SetLength(FBits, M*AWidth);
end;

to be continued...


 
pasha_golub ©   (2004-05-28 17:51) [12]

Иван Второй   (28.05.04 17:43) [10]
По-моему, понятие транспонированной матрицы применяется только к квадратным или я ошибаюсь?


 
Иван Второй   (2004-05-28 17:54) [13]


>   AWidth := (N + ASize - 1) div ASize; // сколько Integer"ов
> в строке из N бит.


Так он DWord-Aligned получился, а у меня биты идут подряд...


 
WebErr ©   (2004-05-28 18:01) [14]


> Иван Второй   (28.05.04 17:43) [10]

Ежу понятно! :)
Если сохранить в классе переменные AWidth и ASize из предыдущего поста, скажем:

private
...
  FSize: Integer;
  FWidth: Integer;
...
function TBitsMatrix.GetBit(I, J: Integer): Boolean;
begin
  Result := (FBits[I*AWidth + J shr FSize] and (1 shl FSize)) <> 0;    
end;

procedure TBitsmatrix.SetBit(I, J: Integer; Value: Boolean);
begin
  if Value then
    FBits[I*AWidth + J shr FSize] := FBits[I*AWidth + J shr FSize] or (1 shl FSize)
  else
    FBits[I*AWidth + J shr FSize] := FBits[I*AWidth + J shr FSize] and  not (Integer(1) shl FSize)
end;

Вот так или почти так, ошибки наверное есть... :)


 
WebErr ©   (2004-05-28 18:08) [15]

А теперь, имея класс "двумерный массив из бит" можно воспользоваться функцией Transpose. Правда снова придётся подкорректировать класс - в него нужно сохранить размерности массива: M и N, т.е.

private
  FM: Integer;
  FN: Integer;
...
public
  property M: Integer read FM;
  property N: Integer read FN;
...
function Transpose(Source: TBitsMatrix): TBitsMatrix;
var
  I, J: Integer;
begin
  with TBitsMatrix.Create(Source.N, Source.M) do
    try
      for I := 0 to Source.M - 1 do
        for J := 0 to Source.N - 1 do
          Bits[I, J] := Source.Bits[J, I];
    except
      ShowMessage("Sorry!");
    end;
end;

Вот и всё.
ООП - это МОЩЬ, а не мощи!


 
WebErr ©   (2004-05-28 18:15) [16]

Т.е. окончательный вариант бета-юнита такой:

Unit BitsMatr;

interface

TBitsMatrix = class
private
 FBits: array of Integer;
 FM: Integer;
 FN: Integer;
 FSize: Integer;
 FWidth: Integer;
 function GetBit(I, J: Integer): Boolean;
 procedure SetBit(I, J: Integer; Value: Boolean);
public
 constructor Create(M, N: Integer);
published
 property Bits[I, J: Integer]: Boolean read GetBit write SetBit;
end;

function Transpose(Source: TBitsMatrix): TBitsMatrix;

implementation

constructor TBitsMatrix.Create(M, N: Integer);
begin
 FSize := SizeOf(Integer) shl 3; // сколько бит в Integer"e
 FWidth := (N + FSize - 1) div FSize; // сколько Integer"ов в строке из N бит.
 SetLength(FBits, M*AWidth);
end;

function TBitsMatrix.GetBit(I, J: Integer): Boolean;
begin
 Result := (FBits[I*AWidth + J shr FSize] and (1 shl FSize)) <> 0;    
end;

procedure TBitsMatrix.SetBit(I, J: Integer; Value: Boolean);
begin
 if Value then
   FBits[I*AWidth + J shr FSize] := FBits[I*AWidth + J shr FSize] or (1 shl FSize)
 else
   FBits[I*AWidth + J shr FSize] := FBits[I*AWidth + J shr FSize] and  not (Integer(1) shl FSize)
end;

function Transpose(Source: TBitsMatrix): TBitsMatrix;
var
 I, J: Integer;
begin
 with TBitsMatrix.Create(Source.N, Source.M) do
   try
     for I := 0 to Source.M - 1 do
       for J := 0 to Source.N - 1 do
         Bits[I, J] := Source.Bits[J, I];
   except
     ShowMessage("Sorry!");
   end;
end;

Попробуй его на вкус!
Подсказка:
используй силу конструкции uses BitsMatr;


 
WebErr ©   (2004-05-28 18:17) [17]

Везде AWidth заменить на FWidth, а ASize на FSize и использовать строго в соответствии с предписанием врача!


 
WebErr ©   (2004-05-28 18:19) [18]

Ой, забыл в конце Transpose нужно

with TBitsMatrix.Create(Source.N, Source.M) do
  try
    for I := 0 to Source.M - 1 do
      for J := 0 to Source.N - 1 do
        Bits[I, J] := Source.Bits[J, I];
    Result := Self;
  except
    ShowMessage("Sorry!");
  end;

или даже вообще
Result := TBitsMatrix.Create(Source.N, Source.M);а дальше просто
with Result do
...


 
WebErr ©   (2004-05-28 18:20) [19]

Уважаемые Мастера, извините за флуд, задача была очень интересная. :))))


 
Иван Второй   (2004-05-28 18:39) [20]


> Ежу понятно! :)

А Сергею Первому нет.

Спасибо, WebErr! И всё таки:


>     Result := Self;

Откуда Self в процедуре Transpose которая уже не метод.


>   except
>     ShowMessage("Sorry!");
>   end;

Пардон пардоном, а писать там правильно было бы:
except
 Free;
 raise;
end;


> задача была очень интересная. :))))

Интереснее чем вы сейчас думаете. см. [13]


 
WebErr ©   (2004-05-28 18:46) [21]


> >     Result := Self;
>
> Откуда Self в процедуре Transpose которая уже не метод.

Извините, тогда:

> Result := TBitsMatrix.Create(Source.N, Source.M);а дальше
> просто
> with Result do
> ...

-----------------------

> >   except
> >     ShowMessage("Sorry!");
> >   end;
>
> Пардон пардоном, а писать там правильно было бы:
> except
>  Free;
Free писать не надо - этот exception появится только в случае ошибки при выделении памяти в конструкторе - т.е. освобождать будет нечего! :)
raise тоже - выдайте сообщение сами.
>  raise;
> end;

Да всё равно что писать!
Автор сабжа - то есть Вы сами должны знать что нужно сделать в обработчике исключения.
-----------------------------------

> Так он DWord-Aligned получился, а у меня биты идут подряд...

Модифицируйте SetBit и GetBit. :)
Или ждите, пока я сам всё это сделаю.


 
WebErr ©   (2004-05-28 18:51) [22]


function TBitsMatrix.GetBit(I, J: Integer): Boolean;
begin
Result := (Bits[(I*N + J + FSize - 1) shr FSize] and (1 shl FSize)) <> 0;
end;


 
WebErr ©   (2004-05-28 18:53) [23]

Ну всё - мне домой пора.
SetBit оставлю Вам в качестве домашнего задания.
Всё это оч. просто, просто нужно создать нужный класс.


 
Иван Второй   (2004-05-28 18:56) [24]


> exception появится только в случае ошибки при выделении
> памяти в конструкторе

Именно в этом случае он не появится, т.к. Create у вас до try во всех предложеных вами вариантах. А если не освободить здесь, тогда нигде больше.

> Модифицируйте SetBit и GetBit. :)

Угу. и конструктор тоже...

2Модераторы. флудная ветка, ей уже место в потрепаться


 
WebErr ©   (2004-05-28 18:59) [25]


> Именно в этом случае он не появится, т.к. Create у вас до
> try во всех предложеных вами вариантах. А если не освободить
> здесь, тогда нигде больше.

Почитайте заодно дома про конструктор.
Он не выделит память если в нём ошибка, т.е. Result := Create будет присвоено nil. Следовательно, try .. except нужен для отлова AV, т.е. NULL pointer assignment.


 
WebErr ©   (2004-05-28 19:03) [26]


> Угу. и конструктор тоже...

Просто тогда нужно удалить FWidth и выделить память под
((N + FSize - 1) shr FSize)*M
Integer"ов.
Если где наврал - сори.


 
Иван Второй   (2004-05-28 19:13) [27]


> Result := Create будет присвоено nil.

Не важно, что ему будет присвоено. AV не будет. А вот и пример

type
 TMyClass = class (TObject)
 public
   constructor Create;
 end;

constructor TMyClass.Create;
begin
 raise Exception.Create("Today is Friday :)")
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 TMyClass.Create;
 ShowMessage("you""ll never see it");
end;


> Почитайте заодно дома про конструктор.
> Он не выделит память если в нём ошибка, т.е. Result := Create
> будет присвоено nil. Следовательно, try .. except нужен
> для отлова AV, т.е. NULL pointer assignment.

Это вы дома почитайте...


 
SergP ©   (2004-05-28 21:57) [28]


>  [10] Иван Второй   (28.05.04 17:43)
>
> > транспонировать
>
> Если дана такая "А"
> 1 0 1 1
> 0 1 1 0
> 0 0 0 1
> Транспонированная будет:
> 1 0 0
> 0 1 0
> 1 1 0
> 1 0 1


Дык поменяй местами индексы массива и будешь иметь транспонированый массив без всякого транспонирования.... :-))


 
Иван Второй   (2004-05-28 23:18) [29]


> (1 shl FSize)


Кстати, не катит. FSize-то больше 32 :-(

по поводу raise. случай из справки. См. raise - Re-raising exceptions



Страницы: 1 вся ветка

Текущий архив: 2004.06.13;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.067 c
1-1085722977
Susanoo
2004-05-28 09:42
2004.06.13
запуск OpenDialog


14-1085646645
negrila
2004-05-27 12:30
2004.06.13
Как изменить anchors во время работы программы


14-1085419845
Lm
2004-05-24 21:30
2004.06.13
shell+XP


1-1086160237
snake1977
2004-06-02 11:10
2004.06.13
Переустановка системы


14-1085468028
*Pavel
2004-05-25 10:53
2004.06.13
Международные платежные системы