Napisać działający kod, w którym...:
Funkcja Szukanie przeszukuje łańcuch znaków w poszukiwaniu wystąpień zadanego tekstu. Implementacja tej funkcji ma być zrównoleglona: przeszukiwany tekst ma być podzielony na (rozłączne) części, i każda z nich ma być przeszukiwana przez niezależny wątek. Liczba powoływanych wątków przeszukujących niech będzie taka, jak w kodzie poniżej...
Liczby wystąpień wyznaczone przez każdy z wątków dadzą po zsumowaniu poszukiwaną liczbę wystąpień zadanego tekstu w badanym łańcuchu. Wartość ta ma być właśnie ostatecznie zwracana przez funkcję Szukanie.
Rozwiązanie ma się znaleźć w katalogu nazwanym od swojego nazwiska. Niech w katalogu tym będą również wszystkie dodatkowe, wykorzystywane moduły.
W rozwiązaniu warto/należy oprzeć się na poniższym kodzie (tzn. kod ten uzupełnić, i/lub zmodyfikować...) :
with Ada.Text_IO; use Ada.Text_IO; -- + ew. inne pomocne moduly ...??...
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; --do sqrt
procedure tresc is
type String_Ptr is access String;
function Szukanie(Dlugi_Tekst: in String_Ptr; Szukane_Slowo: in String)
return Integer is
--deklaracje zmiennych ...??...
task type Szukacz is
--obslugiwane komunikaty ...??...
end Szukacz;
type Szukacz_Ptr is access Szukacz;
T: String_Ptr renames Dlugi_Tekst; S: String renames Szukane_Slowo; --taki Adyzm...
task body Szukacz is
Do_Pom, Found: Integer := 0;
-- inne pomocne zmienne ...??...
begin
-- ...??...
loop --takie-tam przeszukiwanie string'a (mozna zrobic inaczej)
--ponizszy kod polega na zmiennych Od_I oraz Do_I
Do_Pom := Od_I + S'Length - 1;
if Do_Pom <= T'Last and then T(Od_I..Do_Pom) = S then
Found := Found + 1;
Od_I := Do_Pom;
else
Od_I := Od_I + 1;
end if;
exit when Od_I > Do_I;
end loop;
-- ...??...
end Szukacz;
--wyznaczenie, ile taskow bedzie rownolegle przeszukiwac tekst
Liczba_Taskow: Integer := Integer'Min(T'Length/(20*S'Length),
Integer(Float'Ceiling(sqrt(Float(T'Length)))));
Count: Integer;
-- inne pomocne zmienne ...??...
begin -- do funkcji szukanie
-- TRZEBA NAPISAC!!!
return Count;
end Szukanie;
The_Text : String_Ptr := new String(1..10000); -- Przeszukiwany_Tekst
begin
--"pozyskanie" tekstu, ktory nalezy przeszukac (moglby np. byc czytany z pliku)
The_Text.all := (others => '2');
for I in 1..7 loop
The_Text(The_Text'last*I/8..The_Text'last*I/8+7) := "poprawka";
end loop;
--wyswietlenie liczby znalezionych wyrazow (zawiera wolanie funkcji przeszukujacej tekst)
Put_Line("Znaleziono: " & Integer'Image(Szukanie(The_Text, "poprawka")));
end tresc;
with Ada.Text_IO;
use Ada.Text_IO; -- + ew. inne pomocne moduly ...??...
with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions; --do sqrt
procedure tresc is
type String_Ptr is access String;
function Szukanie (
Dlugi_Tekst : in String_Ptr;
Szukane_Slowo : in String)
return Integer is
--deklaracje zmiennych ...??...
task type Szukacz is
entry init (
sz_od : in integer;
sz_do : in integer);
entry dajwynik (
wynik : out integer);
end Szukacz;
type Szukacz_Ptr is access Szukacz;
T : String_Ptr renames Dlugi_Tekst;
S : String renames Szukane_Slowo; --taki Adyzm...
task body Szukacz is
Do_Pom,
Found : Integer := 0;
Od_I,
Do_I : Integer := 0;
-- inne pomocne zmienne ...??...
begin
accept init (
sz_od : in integer;
sz_do : in integer) do
Od_i := sz_od;
Do_i := sz_do;
end init;
-- ...??...
loop --takie-tam przeszukiwanie string'a (mozna zrobic inaczej)
--ponizszy kod polega na zmiennych Od_I oraz Do_I
Do_Pom := Od_I + S'Length - 1;
--Ada.Text_IO.PUt_Line(T(Od_i..Do_Pom));
if Do_Pom <= T'Last and then T(Od_I..Do_Pom) = S then
Found := Found + 1;
Od_I := Do_Pom;
else
Od_I := Od_I + 1;
end if;
exit when Od_I > Do_I;
end loop;
--Ada.Text_IO.Put_Line("Koniec");
accept dajwynik (
wynik : out integer) do
--Ada.Text_Io.put_line("Wynik" & Integer'Image(found));
wynik := found;
end dajwynik;
-- ...??...
end Szukacz;
--wyznaczenie, ile taskow bedzie rownolegle przeszukiwac tekst
Liczba_Taskow : Integer := Integer'Min (T'Length / (20 * S'Length), Integer (Float'Ceiling (sqrt (Float (T'Length)))));
Count : Integer := 0;
i,
j,
k : Integer := 0;
szukacze : array (1 .. liczba_taskow) of Szukacz_Ptr;
begin -- do funkcji szukanie
Ada.Text_IO.Put_Line("Liczba taskow = " & Integer'Image(Liczba_taskow));
for i in 1..liczba_taskow loop
szukacze(i) := new Szukacz; -- nowy watek
j := (i-1) * (T'Length/Liczba_taskow); -- poczatek przedzialu
k := (i) * (T'Length/Liczba_taskow); -- koniec przedzialu
if j = 0 then -- poczatek przedzialu nie może zaczynać się od 0
j := 1; -- tylko od 1
end if;
szukacze(i).init(j,k); -- rozpocznij szukanie
end loop;
Count := 0;
for i in 1..liczba_taskow loop -- zliczanie
szukacze(i).dajwynik(k);
Count := Count + k;
end loop;
return Count;
end Szukanie;
The_Text : String_Ptr :=
new String(1..10000); -- Przeszukiwany_Tekst
begin
--"pozyskanie" tekstu, ktory nalezy przeszukac (moglby np. byc czytany z pliku)
The_Text.all := (others => '2');
for I in 1..7 loop
The_Text(The_Text'Last/8*i..the_text'last/8*i+7) := "poprawka";
end loop;
--Ada.Text_IO.Put_Line(The_Text(1..10000));
--wyswietlenie liczby znalezionych wyrazow (zawiera wolanie funkcji przeszukujacej tekst)
Put_Line("Znaleziono: " & Integer'Image(Szukanie(The_Text, "poprawka")));
end tresc;
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; --do sqrt
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Sem83; Use Sem83;
procedure Tresc is
N: constant Integer := 10000; -- rozmiar bufora na tekst
---------------------------
function Szukanie(Dlugi_Tekst: in String; Szukane_Slowo: in String) return Integer is
task type Szukacz is
entry Init(Od_Ii : in Integer; Do_Ii: in Integer);
end Szukacz;
Sem: Semaphore;
type Szukacz_Ptr is access Szukacz;
T: String renames Dlugi_Tekst;
S: String renames Szukane_Slowo;
Count: Integer := 0;
task body Szukacz is
Do_Pom, Found: Integer := 0;
Od_I, Do_I: Integer;
begin
accept Init(Od_Ii : in Integer; Do_Ii: in Integer) do
Od_I := Od_Ii;
Do_I := Do_Ii;
end Init;
loop
Do_Pom := Od_I + S'Length - 1;
if Do_Pom <= T'Last and then T(Od_I..Do_Pom) = S then
Found := Found + 1;
Od_I := Do_Pom;
else
Od_I := Od_I + 1;
end if;
exit when Od_I > Do_I;
end loop;
Wait(Sem);
Count := Count + Found;
Signal(Sem);
end Szukacz;
Liczba_Taskow: Integer := Integer'Min(T'Length/(20*S'Length), Integer(Float'Ceiling(Sqrt(Float(T'Length)))));
type Memberarray is array(1..Liczba_Taskow) of Szukacz_Ptr;
Robole: Memberarray;
Tymczas_Start, Tymczas_End, Rozmiar_Ramki : Integer;
begin
Sem := Init(1);
for I in 1..Liczba_Taskow loop
Robole(I) := new Szukacz;
end loop;
Rozmiar_Ramki := N / Liczba_Taskow;
for I in 1..Liczba_Taskow loop
Tymczas_Start := Rozmiar_ramki*I-(Rozmiar_ramki-1);
Tymczas_End := Rozmiar_ramki*I;
Robole(I).Init(Tymczas_Start, Tymczas_End);
end loop;
delay(Duration(4)); -- oczekiwanie az szukacze zakoncza swoja prace
return Count;
end Szukanie;
-----------------------------------------
Plik : File_Type;
Litera : Character;
Nazwa : Unbounded_String;
Napis : String(1..N);
I : Integer := 1;
begin
Put("Czekaj! Cos sie dzieje...");
New_Line(3);
Nazwa := To_Unbounded_String ("plik.txt"); -- tutaj podaj nazwe pliku
Open (Plik, In_File, To_String (Nazwa)); -- otwieranie pliku
for I in Napis'range loop -- czyszczenie zmiennej (wypelnianie spacjami) ;)
Napis(I) := ' ';
end loop;
loop -- pobieranie danych do zmiennej
exit when End_Of_File(Plik);
Get (Plik, Litera);
Napis(I) := Litera;
I := I+1;
end loop;
Close(Plik); -- zamykanie pliku
Put_Line("Znaleziono: " & Integer'Image(Szukanie(Napis, "tresc"))); -- wypisanie komunikatu
end Tresc;
Sem83.ads
package Sem83 is
type Semaphore is private;
type Binary_Semaphore is private;
function Init(N: Integer) return Semaphore;
procedure Wait (S: Semaphore);
procedure Signal(S: Semaphore);
function Init(N: Integer) return Binary_Semaphore;
procedure Wait (S: Binary_Semaphore);
procedure Signal(S: Binary_Semaphore);
Bad_Semaphore_Initialization: exception;
private
task type Semaphore_Task is
entry Init(N: Integer; B: Boolean);
entry Wait;
entry Signal;
end Semaphore_Task;
type Semaphore is access Semaphore_Task;
type Binary_Semaphore is access Semaphore_Task;
end Sem83;
Sem83.adb
package body Sem83 is
task body Semaphore_Task is
Binary: Boolean;
V: Integer;
begin
accept Init(N: Integer; B: Boolean) do
Binary := B;
V := N;
end Init;
loop
select
accept Wait do
if V > 0 then V := V - 1;
else accept Signal;
end if;
end Wait;
or
accept Signal do
if not Binary or else V = 0 then
V := V + 1;
end if;
end Signal;
or
terminate;
end select;
end loop;
end Semaphore_Task;
function Init(N: Integer) return Semaphore is
S: Semaphore;
begin
if N < 0 then raise Bad_Semaphore_Initialization;
else
S := new Semaphore_Task;
S.Init(N, False);
return S;
end if;
end Init;
function Init(N: Integer) return Binary_Semaphore is
S: Binary_Semaphore;
begin
if (N < 0) or (N > 1) then raise Bad_Semaphore_Initialization;
else
S := new Semaphore_Task;
S.Init(N, True);
return S;
end if;
end Init;
procedure Wait(S: Semaphore) is
begin
S.Wait;
end Wait;
procedure Signal(S: Semaphore) is
begin
S.Signal;
end Signal;
procedure Wait(S: Binary_Semaphore) is
begin
S.Wait;
end Wait;
procedure Signal(S: Binary_Semaphore) is
begin
S.Signal;
end Signal;
with Ada.Text_IO; use Ada.Text_IO; -- + ew. inne pomocne moduly ...??...
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; --do sqrt
with display;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
procedure tresc is
type String_Ptr is access String;
function Szukanie(Dlugi_Tekst: in String_Ptr; Szukane_Slowo: in String)
return Integer is
--deklaracje zmiennych ...??...
task type Szukacz is
--obslugiwane komunikaty ...??...
entry Init(poczatek : in Integer; koniec : in Integer);
entry getCount(count : out Integer);
end Szukacz;
type Szukacz_Ptr is access Szukacz;
T: String_Ptr renames Dlugi_Tekst; S: String renames Szukane_Slowo; --taki Adyzm...
task body Szukacz is
Do_Pom, Found, Od_I, Do_I: Integer := 0;
-- inne pomocne zmienne ...??...
begin
accept Init(poczatek : in Integer; koniec : in Integer) do
Od_I := poczatek;
Do_I := koniec;
end Init;
-- ...??...
loop --takie-tam przeszukiwanie string'a (mozna zrobic inaczej)
--ponizszy kod polega na zmiennych Od_I oraz Do_I
Do_Pom := Od_I + S'Length - 1;
if Do_Pom <= T'Last and then T(Od_I..Do_Pom) = S then
Found := Found + 1;
Od_I := Do_Pom;
else
Od_I := Od_I + 1;
end if;
exit when Od_I > Do_I;
end loop;
accept getCount(count : out Integer) do
count := Found;
display.Screen.Write(To_Unbounded_String("znalazlem : "& Integer'Image(Found)));
end getCount;
-- ...??...
end Szukacz;
--wyznaczenie, ile taskow bedzie rownolegle przeszukiwac tekst
Liczba_Taskow: Integer := Integer'Min(T'Length/(20*S'Length),
Integer(Float'Ceiling(sqrt(Float(T'Length)))));
szukajki : array(1..Liczba_Taskow) of Szukacz_Ptr;
Count,i,p,k,paczka,tmp: Integer := 0;
-- inne pomocne zmienne ...??...
begin -- do funkcji szukanie
-- TRZEBA NAPISAC!!!
paczka := T'Length/Liczba_Taskow;
for i in 1..Liczba_Taskow loop
szukajki(i) := new Szukacz;
p := paczka * i;
k := paczka * (i+1);
if k > T'Length then
k := T'Length;
end if;
szukajki(i).Init(p,k);
end loop;
display.Screen.Write(To_Unbounded_String("Liczba Taskow : "& Integer'Image(Liczba_Taskow)));
display.Screen.Write(To_Unbounded_String("Dlugosc tekstu : "& Integer'Image(T'Length)));
for i in 1..Liczba_Taskow loop
tmp := 0;
szukajki(i).getCount(tmp);
count := count + tmp;
end loop;
return Count;
end Szukanie;
The_Text : String_Ptr := new String(1..10000); -- Przeszukiwany_Tekst
--Str : String(1..10);
--c : character;
--F : File_Type;
--i : Integer := 0;
begin
for I in 1..7 loop
The_Text(The_Text'last*I/8..The_Text'last*I/8+7) := "poprawka";
end loop;
--wyswietlenie liczby znalezionych wyrazow (zawiera wolanie funkcji przeszukujacej tekst)
Put_Line("Znaleziono: " & Integer'Image(Szukanie(The_Text, "poprawka")));
end tresc;