Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.06.13;
Скачать: [xml.tar.bz2];

Вниз

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

 
Иван Второй   (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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.037 c
1-1085721989
Артем К.
2004-05-28 09:26
2004.06.13
Создание компонента на основе TCustomControl с полосой прокрутки


8-1080728522
Tolik.R.V.
2004-03-31 14:22
2004.06.13
Help!!! Как вывести массив точек на Canvas.


14-1085426948
тихий вовочка
2004-05-24 23:29
2004.06.13
Показуха


14-1085720232
ORMADA
2004-05-28 08:57
2004.06.13
Хде Дельфим держит свои иконки ?


3-1084949648
cad2206
2004-05-19 10:54
2004.06.13
Просмотр нескольких таблиц





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский