Deklaracja macierzy rozmiarze wczytywanym z pliku

0

Wczytuje macierz z pliku, która ma określona na samym początku n - wierszy i m - kolumn. W jaki sposób tą macierz określić jako L. Zeby potem na działaniach pisac sobie np. L[i,2]. Zapisałam

VAR L:Array [1..n,1..m] of integer;

ale program dopiero później odczytuje wymiary amcirzy z pliku i wyskakuje błąd. Ktoś ma jakiś pomysł?

1

Nie możesz użyć macierzy o znanym rozmiarze, jeśli jej rozmiar nie jest znany. Co więcej, w Pascalu nie ma czegoś takiego jak Variable Length Aarray, więc albo musisz określić stały rozmiar (znany już podczas kompilacji), albo skorzystać z macierzy dynamicznych.

W Twoim przypadku będzie to dynamiczna tablica tablic:

var
  DynamicArray = array of array of Integer;

Po odczytaniu rozmiarów – przyjmijmy że do zmiennych Cols oraz Rows – używasz SetLength:

SetLength(DynamicArray, Cols, Rows);

Napisz jeszcze o jakie Delphi chodzi, bo powyższy (trójargumentowy) zapis pseudoprocedury SetLength może nie być dostępny. W takim przypadku trzeba będzie najpierw nadać rozmiar jednego wymiaru, a następnie w pętli ustawić rozmiar drugiego wymiaru, dla każdego wiersza z osobna.
@woolfik niżej potwierdził, że Delphi też wspiera ten zapis.


Zwróć też uwagę na kolejność Cols i Rows, jaką podałem wyżej. Pierwszy wymiar dotyczy kolumn, nie wierszy, bo zwykło się używać współrzędnych w kolejności [X,Y], gdzie X określa położenie na osi poziomej (czyli numer kolumny), a Y na pionowej (czyli numer wiersza).

Oczywiście można sobi przyjąć, że pierwszy wymiar dotyczy wierszy – byle stosować go wszędzie w kodzie i byle każdy pracujący przy tym kodzie wiedział, że takie są założenia.

1

Jeśli masz rozmiar tablicy dynamiczny (n i m odczytujesz z pliku czyli w runtime aplikacji) to nie możesz tego tak zrobić. Deklaracja musi być dynamiczna czyli

var
  l: array of array of integer;
begin
  //tu ustawiasz rozmiar tablicy
  setlength(l, n, m);
end;
0

Dziękuje za edytowanie postu, niestety nie umiem tu ładnie wpisac kodów.

Nie ukrywam, że programowanie u mnie dopiero się zaczyna i mało co umiem.
Generalnie mam napisać program kóry odczytuje z pliku macierz i liczy iloczyn kolumny drugiej.
i mam to opracowane przez kogoś (nie znam) jako że sam ten procen liczenia iloczynu jest
read(f,a); read(f,a) i to read odczytuje jakby najpierw pierwszy element z danego wiersza a za drugim razem juz drugi :D na jakiej zasadzie to działa?
Moge wstawić cały program tylko nie zabardzo wiem jak

0
Wielki Programis napisał(a):

Dziękuje za edytowanie postu, niestety nie umiem tu ładnie wpisac kodów.

Korzystaj z przycisków do formatowania treści, umiejscowionych nad polem do pisania posta. No i z zakładki Podgląd przed wysłaniem posta, aby sprawdzić czy wszystko gra.

i mam to opracowane przez kogoś (nie znam) jako że sam ten procen liczenia iloczynu jest

read(f,a);
read(f,a);

i to read odczytuje jakby najpierw pierwszy element z danego wiersza a za drugim razem juz drugi :D na jakiej zasadzie to działa?

Samo Read odczytuje porcję danych (w zależności od typu zmiennej lub zmiennych), automatycznie przesuwając wskaźnik w pliku. Dlatego też wołanie w kółko Read umożliwia sukcesywne wczytywanie danych, porcja po porcji, bez konieczności wykonywania dodatkowych czynności związanych z samym plikiem.

Moge wstawić cały program tylko nie zabardzo wiem jak

Najlepiej tak będzie. Wrzuć tak jak umiesz – jak Ci nie wyjdzie to poprawię. ;)

0
program zad4;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const
  nazwaPliku = 'A.txt';

var
  f: Text;   {zmienna plikowa}
  n,m: integer;   {wczytane (z pliku) wymiary macierzy (liczba wierszy/kolumn)}
  i: integer;
  a: real;
  Ilocz: real;   {iloczyn elementów w 2. kolumnie macierzy (wynik)}

begin
  Assign(f,nazwaPliku);   {skojarz zmienną plikową z nazwą pliku}

  Reset(f);   {otwórz plik}

  readln(f, n,m);   {wczytaj (z pliku) wymiary macierzy}

  if m<2   {macierz nie ma 2 kolumn (tylko mniej)}
  then
    writeln('Macierz nie ma drugiej kolumny.')
  else   {macierz ma (co najmniej) 2 kolumny}
    begin
      Ilocz := 1;   {zainicjalizuj wartość wyniku}
      for i:=1 to n do
        begin
          read(f, a);   {pierwsza liczba z wiersza (tylko ją wczytujemy)}
          read(f, a);   {druga liczba z wiersza}
          Ilocz := Ilocz * a;   {dolicz wczytaną liczbę do iloczynu}
          readln(f);   {"przeskocz" w pliku na początek następnej linii}
        end;

      writeln('Iloczyn elementow w drugiej kolumnie macierzy wynosi:  ',
              Ilocz:0:3);
    end;

  Close(f);   {zamknij plik}

  readln
end.


Czy da się to jakoś prościej napisać? Wiem ze jest wszystko wytłumaczone, tylko chciałam w jakis inny sposób liczyć ten iloczyn

0
var
  Input: TextFile;
  Matrix: array of array of Integer;
var
  Row, Rows, Col, Cols: Integer;
begin
  AssignFile(Input, 'a.txt');
  Reset(Input);
  try
    ReadLn(Input, Rows, Cols);
    SetLength(Matrix, Cols, Rows);
    
    for Row := 0 to Rows - 1 do
      for Col := 0 to Cols - 1 do
        Read(Input, Matrix[Col, Row]);
  finally
    CloseFile(Input);
  end;

  // dalsze operacje na macierzy
end;

IMO coś takiego powinno wystarczyć do załadowania danych z pliku do macierzy (ale nie testowałem).

Edit: edytowałem kod, bo zgubiłem Input w pętli.

0
furious programming napisał(a):

Zwróć też uwagę na kolejność Cols i Rows, jaką podałem wyżej. Pierwszy wymiar dotyczy kolumn, nie wierszy, bo zwykło się używać współrzędnych w kolejności [X,Y], gdzie X określa położenie na osi poziomej (czyli numer kolumny), a Y na pionowej (czyli numer wiersza).

Tu tak uwaga -- niekoniecznie. Kolejność Cols, Rows jest używana w geometrii (ze względu na X, Y), ale już akurat w macierzach (i w ogóle w algebrze liniowej) odwrotnie -- zwykle najpierw wiersze a potem kolumny...

0

@koszalek-opalek: w przypadku macierzy – jako struktur danych – kolejność argumentów indeksujących nie ma żadnego znaczenia. Równie dobrze będzie indeksować [x,y], jak i [y,x] (czy [col,row] lub [row,col]).

Ważne jest, aby jeden sposób używać dla wszystkich algorytmów operujących na danej macierzy. A jeśli się kolejność pomyli, to kod przestanie działać prawidłowo (w większości przypadków).

0

@furious programming U, tu się mylisz grubo -- klejność składowania ma ogramne znaczenie jeśli chodzi o dostęp do cache'u... I jest ściśle związana z konkretnym algorytmem. Czasem wręcz się opłaca przetransponować macierz fizycznie.

0

I jak ma się to do problemu z bieżącego wątku? Nijak – mamy kupkę liczb, trzeba je wrzucić do macierzy i przetworzyć. To wszystko. Kolejność indeksowania nie ma żadnego znaczenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1