Как сделать матрицу?
От: Ozone Россия  
Дата: 08.09.03 01:14
Оценка:
Есть такая задачка:

Как с помощью указателей в TurboPascal'e сделать такую матрицу, у которой ни кол-во строк, ни кол-во столбцов неизвестно (кажадая строка может иметь свой какой-то размер)

Помогите кто чем может.
Re: Как сделать матрицу?
От: ZigmundFreid  
Дата: 08.09.03 04:28
Оценка:
Здравствуйте, Ozone, Вы писали:

O>Есть такая задачка:


O>Как с помощью указателей в TurboPascal'e сделать такую матрицу, у которой ни кол-во строк, ни кол-во столбцов неизвестно (кажадая строка может иметь свой какой-то размер)


O>Помогите кто чем может.


Матрица она на то и матрица.
Копай в сторону указателей.
Re[2]: Как сделать матрицу?
От: Ozone Россия  
Дата: 08.09.03 04:32
Оценка:
Здравствуйте, ZigmundFreid, Вы писали:

ZF>Матрица она на то и матрица.

ZF>Копай в сторону указателей.

Копаю, но докопаться не могу.
Знаю, что в Си это можно сделать, в принципе, так:
int **matrix;


А как в TurboPascal'e?
Re[3]: Как сделать матрицу?
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.09.03 05:34
Оценка:
Здравствуйте, Ozone, Вы писали:

O>
O>int **matrix;
O>


O>А как в TurboPascal'e?

type
  PInt = ^Int;
    PPInt = ^PInt;
var
  M: PPInt;

Вроде так...
... << RSDN@Home 1.1 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Как сделать матрицу?
От: Ozone Россия  
Дата: 08.09.03 05:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Ozone, Вы писали:


O>>
O>>int **matrix;
O>>


O>>А как в TurboPascal'e?

S>
S>type
S>  PInt = ^Int;
S>    PPInt = ^PInt;
S>var
S>  M: PPInt;
S>

S>Вроде так...

Да так, но это я уже понял.
Как мне теперь правильно выделять память и заполнять ее (матрицу).
Re[5]: Как сделать матрицу?
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.09.03 06:17
Оценка:
Здравствуйте, Ozone, Вы писали:

O>Да так, но это я уже понял.

O>Как мне теперь правильно выделять память и заполнять ее (матрицу).
Как насчет GetMem/FreeMem?
... << RSDN@Home 1.1 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Как сделать матрицу?
От: Ozone Россия  
Дата: 08.09.03 06:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Ozone, Вы писали:


O>>Да так, но это я уже понял.

O>>Как мне теперь правильно выделять память и заполнять ее (матрицу).
S>Как насчет GetMem/FreeMem?

Это все конечно здорово
Все эти процедуры я конечно знаю, просто я не могу сообразить как ее (матрицу) создать.
rCOLS:=random(100);
{ ??? под что выделить память ??? }
for i:=1 to rCOLS do begin
  rROWS:=random(100);
  { ??? под что выделить память ??? }
  for j:=1 to rROWS do begin
    {??? чему присваивать ???} := random(50);  
  end;
end;
{И как это все потом вывести на экран?}
Re[7]: Как сделать матрицу?
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.09.03 06:54
Оценка:
Здравствуйте, Ozone, Вы писали:

O>Все эти процедуры я конечно знаю, просто я не могу сообразить как ее (матрицу) создать.

Ну как под что? Ты же задекларировал переменную M типа PPInt?
ну вот под нее и выделяешь:
var
  M: PPInt;
  Col: PInt
begin
rCOLS:=random(100);
GetMem(M, sizeof(PInt)*rCOLS);
for i:=0 to rCOLS-1 do begin
  rROWS:=random(100);
    Col:= PInt(Integer(M)+i*sizeof(PInt));
    GetMem(Col, rROWS*sizeof(Integer));
  for j:=0 to rROWS-1 do begin
    PInt(Integer(Col)+j*sizeof(Integer))^ := random(50);  
  end;
end;

{И как это все потом вывести на экран?}
... << RSDN@Home 1.1 beta 1 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Как сделать матрицу?
От: Ozone Россия  
Дата: 08.09.03 07:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>
S>var
S>  M: PPInt;
S>  Col: PInt
S>begin
S>rCOLS:=random(100);
S>GetMem(M, sizeof(PInt)*rCOLS);
S>for i:=0 to rCOLS-1 do begin
S>  rROWS:=random(100);
S>    Col:= PInt(Integer(M)+i*sizeof(PInt));
S>    GetMem(Col, rROWS*sizeof(Integer));
S>  for j:=0 to rROWS-1 do begin
      <B>{В этом месте программа вылетает из DOS}</B>
S>    PInt(Integer(Col)+j*sizeof(Integer))^ := random(50);  
S>  end;
S>end;
S>
Re[5]: Как сделать матрицу?
От: akasoft Россия  
Дата: 08.09.03 07:38
Оценка:
Здравствуйте, Ozone, Вы писали:

O>Да так, но это я уже понял.

O>Как мне теперь правильно выделять память и заполнять ее (матрицу).

Дык всё не просто, в Турбо то Паскале. Там ДОС правит, а значит есть куча ограничений.

Придётся или object свой написать для инкапсуляции действий с такой матрицей, или бороться через записи.

Анализируем.

Для Дельфи мы бы написали

var
    Matrix: array of array of Integer;
begin
    SetLength(Matrix, N); // Задаём количество строк
    
    ...
    
    // по строкам
    SetLength(Matrix[i], M); // Задяём количество элементов в i-той строке
    ...


Вуалля. Теперь хотим то же, но по 3 рубля.

Пусть тип элементов матрицы будет Integer. Никто не мешает его потом изменить на нужный или record.

Объявляем данные

type
    PMatrixData = ^TMatrixData;
    TMatrixData = array[1..16384] of Integer;


Объявляем строку матрицы

type
    PMatrixRow = ^TMatrixRow;
    TMatrixRow = record
      Count: Integer; // количество элементов
        Data: PMatrixData; // сами данные
    end;


Объявляем колонки матрицы

type
    PMatrixRowList = ^TMatrixRowList;
    TMatrixRowList = array [1..16384] of PMatrixRow;


И саму матрицу

type
    TMatrix = record
        Count: Integer; // количество строк в матрице
        Row: PMatrixRowList; // список строк
    end;


Магика 16384 заключается в ограничении на размер блока в 64К и тем, что MaxInteger div SizeOf(Integer) = 16384 (32768 div 2 = 16384). Т.е. надо вложиться в непрерывный блок. Иначе придётся делать связанные списки, а это производительность.

Теперь смотрим, для чего всё затея была.

var
    Matrix: TMatrix;
    Item: Integer;
begin
    with Matrix do
    begin
        Count := N;
        GetMem(Row, Count * SizeOf(PMatrixRow));
    end;
    
    // по строкам
    GetMem(Matrix.Row^[i], SizeOf(TMatrixRow));
    with Matrix.Row^[i] do
    begin
        Count := M;
        GetMem(Data, Count * SizeOf(Integer));
    end;
    
    // обращение
    Item := Matrix.Row^[i].Data^[j];
    Matrix.Row^[i].Data^[j] := Item;


Контроль индексов остаётся на совести программиста.

Конечно, я могу ошибиться в синтаксисе, давно BP не пользую, но идея-то понятна. И обернуть это дело в object труда не представляет, зато сколько потом пользы...
... << RSDN@Home 1.1 beta 3 >>
Re[6]: Как сделать матрицу?
От: DOOM Россия  
Дата: 08.09.03 10:31
Оценка: 3 (1)
Здравствуйте, akasoft, Вы писали:

A>Здравствуйте, Ozone, Вы писали:


O>>Да так, но это я уже понял.

O>>Как мне теперь правильно выделять память и заполнять ее (матрицу).

A>Дык всё не просто, в Турбо то Паскале. Там ДОС правит, а значит есть куча ограничений.



A>Контроль индексов остаётся на совести программиста.


A>Конечно, я могу ошибиться в синтаксисе, давно BP не пользую, но идея-то понятна. И обернуть это дело в object труда не представляет, зато сколько потом пользы...


Маленькие хитрости старого доброго ДОСа:


var
 matr: array [1..1,1..1] of integer;
begin
 GetMem(@matr,versize*horsize*sizeof(integer));
{$R-} 
{адресуем как хотим. Память есть} 
 matr[10,20]:=111;
...
Re: Как сделать матрицу?
От: Shadowspan Россия  
Дата: 08.09.03 10:42
Оценка: +1
Здравствуйте, Ozone, Вы писали:

O>Есть такая задачка:


O>Как с помощью указателей в TurboPascal'e сделать такую матрицу, у которой ни кол-во строк, ни кол-во столбцов неизвестно (кажадая строка может иметь свой какой-то размер)


O>Помогите кто чем может.


Можно описать массивы:
type
  TIntArray = array [0..0] of Integer;
  PIntArray = ^TIntArray;
  TMatrixArray = array [0..0] of PIntArray;
  PMatrixArray = ^TMatrixArray;

Снимаешь range checking при компиляции.
Далее:
var
  Matrix : PMatrixArray;
  i : Integer;
begin
  GetMem(Matrix, sizeof(PIntArray) * ROW_COUNT);
  for i:= 0 to ROW_COUNT do
    GetMem(Matrix^[i], sizeof(Integer) * COL_COUNTI);
  // далее обращение к элементам Matrix^[i]^[j]
end;


Если это все таки Delphi старших версий — то реализация н6а динамических массивах более универсальна.
... <<shadowspan RSDN@Home 1.0 beta 6a >>
Re[7]: Как сделать матрицу?
От: akasoft Россия  
Дата: 08.09.03 11:26
Оценка:
Здравствуйте, DOOM, Вы писали:

DOO>Маленькие хитрости старого доброго ДОСа:


Да... Потому что ячейки идут слева направо сверху вниз. Но 64К всё равно остаётся.
... << RSDN@Home 1.1 beta 3 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.