Najczęściej występujący element w pliku.

0

Witam. Zadanie polega na znalezieniu najczęściej występującego elementu w pliku typu byte zawierającego 2048 liczb z przedziału <1,100>. Teoretycznie wydaje się proste, jednak chodzi o to, że ma być wykonane w taki sposób aby nie przeglądać pliku 100 razy. Przepisałem te liczby do tablicy i zliczająca procedura wygląda tak:

procedure sprawdz(t:tablica);
var
i:integer;
wynik,j,licznik,max:byte;
begin
max:=0;
for j:=1 to 100 do
begin
licznik:=0;
for i:=1 to 2048 do
if j=t[i] then licznik:=licznik+1;
if licznik>max then
begin
max:=licznik;
wynik:=j;
end;
end;
writeln('Najczesciej powtarza sie ',wynik);
end;

Teoretycznie plik nie jest przeglądany 100 razy, ale tablica już tak. Jak zrobić to zadanie pomijając tę pętlę for liczącą do 100?

0

Kod niesformatowany jak wspomniał Patryk, więc nawet patrzeć się nie chce, ale nie rozumiem w czym problem. Liczb jest od 1 do 100, jeżeli włacznie to robisz tablicę integerów od 1 do 100, jak nie to do 99 i na początku wszystkie elementy tablicy zerujesz, a później robisz coś w stylu Tablica[Liczba_Wczytana_Z_Pliku] := Tablica[Liczba_Wczytana_Z_Pliku] + 1;, także nadal nie wiem w czym jest problem, nie widze w takim rozwiązaniu przeszukiwania tej tablicy 100 razy.

0

Rozumiem. Tylko jak potem w możliwie najszybszy sposób wypisać tę najczęściej występującą liczbę?

0

Dla tablicy 100 elementowej to nawet najwolniejsze algorytmy sortujące z przestawianiem elementów będą - według mnie - wystarczająco szybkie, ale jak chcesz coś na prawdę szybkiego to polecam kod poniżej. A wystarczyło pogooglowac chwilę. Tutaj sortuje tablicę Wordów, ale przy przedziale liczb jaki podałeś wystarcza. Oczywiście nie ma problemu aby posortować tablicę innego typu, trzeba wtedy tylko poprawić typy zmiennych w owym kodzie.

{Procedura sortująca elementy tablicy ze zmiennymi typu Word rosnąco.}
{Aby posortować malejąco "and (A[J] > A[J + K]) do" - zamienić należy}
{na: "and (A[J] < a[J + K]) do":}

procedure Sort_Shell(var A : array of Word);
// poniższa procedura sortująca liczby rosnąco jest ze strony
// http://www.swissdelphicenter.ch/torry/showcode.php?id=1616
var
  H : Word;
  Bis, I, J, K : LongInt;
begin
  Bis := High(A);
  K := Bis shr 1;
  while K > 0 do
  begin
    for I := 0 to Bis - K do
    begin
      J := I;
      while (J >= 0) and (A[J] > A[J + K]) do
      begin
        H := A[J];
        A[J] := A[J + K];
        A[J + K] := H;
        if J > K then
          Dec(J, K)
        else
          J := 0;
      end;
    end;
    K := K shr 1;
  end;
end;
0

Przepraszam, ale chyba jednak do końca nie łapę. Jeżeli utworzę tablicę taką jak podałeś w pierwszym poście, to po przeleceniu wszystkich liczb powinienem uzyskać w niej ilości powtórzeń każdej liczby z przedziału <1,100>, gdzie indeks tablicy określa daną liczbę. Więc jeżeli posortuję tę tablicę, to najczęściej występująca liczba przeniesie się do innej komórki tablicy. Chcę konkretnie znać, która liczba najczęściej się powtarza i ile razy. Trochę nie bardzo łapę, jak to potem odczytać z posortowanej tablicy, maksymalną liczbę powtórzeń ok, ale danej liczby to już nie.

0

Źle pomyślałem. Przepraszam. Zrób to tak. Tutaj zamiast wczytywania z pliku jest losowanie, ale to nie powinno znacznie wpłynąć na prędkośc programu. Wykona się on jak podejrzewam w góra kilkadziesiąt milisekund. Teraz całośc jak pokazuje mi poniższy kod wykonuje się w zero milisekund, a więc samo ustalenie najczęściej występującej liczby również zajmie tyle co nic.

program a;

{$APPTYPE CONSOLE}

uses
  Windows;

var
  I, R, Max : integer;
  Start, Stop : Cardinal;
  Arr : array[1..100] of Word;
begin
  Start := GetTickCount;
  Randomize;
  for I := Low(Arr) to High(Arr) do
  begin
    Arr[I] := 0;
  end;
  for I := 1 to 2048 do
  begin
    R := Random(100) + 1;
    Arr[R] := Arr[R] + 1;
  end;
  Max := 0;
  for I := Low(Arr) to High(Arr) do
  begin
    if Arr[I] > Max then
    begin
      R := I;
      Max := Arr[I];
    end;
  end;
  Stop := GetTickCount;
  Writeln('Najczesciej wystepuje liczba: ', R);
  Writeln('Program wykonal sie w: ', Stop - Start, ' ms.');
  Readln;
end.

EDIT: nawet z zapisem do pliku i odczytem z niego. Trwa to u mnie zero milisekund. Fakt, że mam proces cztero rdzeniowy, a komputer nie ma jeszcze roku, ale nawet na wolniejszej maszynie i nie pod Windowsem siedem, podejrzewam że dla Delphi 7, wyniki będą takie same.

program a2;

{$APPTYPE CONSOLE}

uses
  Windows;

const
  AFileName = 'D:\digits.txt';
var
  S : string;
  F : TextFile;
  I, R, Max : integer;
  Start, Stop : Cardinal;
  Arr : array[1..100] of Word;
begin
  Start := GetTickCount;
  Randomize;
  AssignFile(F, AFileName);
  Rewrite(F);
  for I := 1 to 2048 do
  begin
    R := Random(100) + 1;
    Writeln(F, R);
  end;
  for I := Low(Arr) to High(Arr) do
  begin
    Arr[I] := 0;
  end;
  Reset(F);
  while not EOF(F) do
  begin
    Readln(F, S);
    Val(S, I, R);
    if R = 0 then
    begin
      Arr[I] := Arr[I] + 1;
    end;
  end;
  CloseFile(F);
  Max := 0;
  for I := Low(Arr) to High(Arr) do
  begin
    if Arr[I] > Max then
    begin
      R := I;
      Max := Arr[I];
    end;
  end;
  Stop := GetTickCount;
  Writeln('Najczesciej wystepuje liczba: ', R);
  Writeln('Program wykonal sie w: ', Stop - Start, ' ms.');
  Readln;
end.
0

Wielkie dzięki, właśnie o to mi chodziło. Teraz rzeczywiście nie wałkuje tych 2048 liczb 100 razy. Jeszcze raz dzięki za pomoc.

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