Wstęp do programowania / Ćwiczenia 6: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Daria (dyskusja | edycje)
3 zadania
Daria (dyskusja | edycje)
Zadanie 4
Linia 266: Linia 266:
   
   
'''Zadanie'''
'''Zadanie'''
Dana jest tablica A typu array[1..N] of integer, N > 0. Sprawdź czy jest w niej element wystepujący więcej niż N/2 razy i jeśli tak wskaż go.
Dana jest tablica A typu array[1..N] of integer, N > 0. Sprawdź czyjest w niej element wystepujący więcej niż N/2 razy i jeśli tak wskażgo.


'''Program'''
'''Program'''
Linia 365: Linia 365:
wartośc w <> kand. Jeśli tak przypuścimy to niezależnie od ile, w musiałaby być liderem w ogonie, co jest sprzeczne z niezmiennikiem. a więc jedynym kandydatem an lidera jest rzeczywiście kand.
wartośc w <> kand. Jeśli tak przypuścimy to niezależnie od ile, w musiałaby być liderem w ogonie, co jest sprzeczne z niezmiennikiem. a więc jedynym kandydatem an lidera jest rzeczywiście kand.


</div>
</div>
== Zadanie 4 (BinPower)==
Udowodnij częściową poprawność dla podanego poniżej zadania i jego rozwiązania.
'''Zadanie'''
Dla zadanych x,n > 0 wyznacz x<sup>n</sup> (oczywiscie bez exp i ln).
'''Program'''
'''function''' BinPower(x,n:integer):integer;
// Dla x,n > 0 wyznaczamy x do potęgi n
'''var''' z,y,i: integer;
'''begin'''
  z:=1;
  y:=x;
  i:=n;
  '''while''' i > 0 '''do''' '''begin'''
    '''if''' (i mod 2 = 1) '''then''' z:=z*y;
    y:=y*y;
    i:=i div 2;
  '''end''';
  BinPower:=z;
'''end''';
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie''' 
<div class="mw-collapsible-content" style="display:none">
Zacznijmy od niezmiennika pętli oznaczanego przez N(z,y,i):
x<sup>n</sup>=z*y<sup>i</sup> &and; i&ge; 0
Poniżej znajduje się program wraz z anotacjami i dowody, że anotacje wraz z kodem który otaczają są poprawnymi trójkami Hoare'a.
    // x,n > 0
1: z:=1; y:=x; i:=n;
    // N(z,y,i)
2: '''while''' i > 0 '''do''' '''begin'''
      // N(z,y,i) &and; i > 0
3:  '''if''' (i mod 2 = 1) '''then''' z:=z*y;
      // N(z,y*y,i div 2)
4:  y:=y*y;
      i:=i div 2;
      // N(z,y,i)
5: '''end''';
    // z= x<sup>n</sup>
'''1''' Korzystając z reguły na przypisanie. Mamy pokazać, że N(1,x,n). Ponieważ n>0 to n&ge; 0
'''2''' Będziemy pokazywać, że N(z,y,i) jest niezmiennikiem pętli.
'''3''' Choć mamy instrukcję '''if''' bez '''else''' musimy pokazać dwie implikacje
N(z,y,i) &and; i>0 &and; i mod 2 = 1 &rArr; N(z*y, y*y, i div 2)
N(z,y,i) &and; i>0 &and; i mod 2 = 0 &rArr; N(z, y*y, i div 2)
Dla pierwszej z nich zauważmy, ze jeśli i mod 2 = 1 to i=2*(i div 2) +1. Wtedy  z*y<sup>i</sup>= (z*y) * (y*y)<sup>(i div 2)</sup>. Oczywiście jeśli i > 0 to i div 2 &ge; 0.
Dla drugiej, mamy  i=2*(i div 2). Wtedy  z*y<sup>i</sup>= z * (y*y)<sup>(i div 2)</sup>. Podobnie jeśli i > 0 to i div 2 &ge; 0.
'''4''' Jest to dwa razy użyta reguła na przypisanie.
'''5''' Po wyjściu z pętli mamy  N(z,y,i) &and; i &le; 0. Ponieważ i &ge; 0  z niezmiennika, to i=0. A więc  x<sup>n</sup>=z.
</div>
</div>
</div>
</div>

Wersja z 16:58, 24 lip 2006

Zadanie 1 (Flaga trójkolorowa)

Udowodnij częściową poprawność podanego poniżej rozwiązania zadania o fladze trójkolorowej.

Zadanie Dana jest tablica A typu array[1..N] of integer (N > 0). Należy tak poprzestawiać w niej elementy, żeby najpierw były elementy ujemne, potem równe zero, a na końcu dodatnie.

Program

program FlagaTrójkolorowa(N:integer; A:array[1..N] of integer);
var m,r,w,pom : integer;
begin
  m:=1; r:=1; w:=N;
  while r <= w do 
    if A[r]=0 then r:=r+1			//przedłużamy segment liczb dodatnich	
    else 
      if A[r]<0 then begin			
        pom:=A[r]; A[r]:=A[m]; A[m]:=pom;	//zamieniamy wartości w A[r] i A[m], po zamianie A[r]=0 i A[m] < 0  
        m:=m+1;					//więc zwiększamy oba indeksy r i m
        r:=r+1;
      end
      else begin
        pom:=A[r]; A[r]:=A[w]; A[w]:=pom;	//zamieniamy wartości w A[r] i A[w]
        w:=w-1;					//po zamianie A[w]>0,  ale o A[r] nic nie wiemy
      end;			     
end.

Rozwiązanie

Całkowita poprawność

Zadanie 2 (Segment o danej sumie)

Udowodnij częściową poprawność dla podanego poniżej zadania i jego rozwiązania.

Zadanie Tablica A typu array[1..N] of integer, N >0, zawiera tylko liczby dodatnie. Napisz program który dla danego W typu integer, takiego że W > 0, sprawdza czy w A istnieje segment o sumie W (czyli czy istnieją l, p takie, że W=A[l]+...+A[p1]).

Program

program SegmentODanejSumie2(N,W:integer; A:array[1..N] of integer);
//Tablica A zawiera tylko liczby dodatnie
var l,p,suma: integer;
    znalezione: boolean;
begin
  l:=1; p:=1;
  suma:=0;
  while (suma <> W) and (p <= N) do
    if suma < W then begin		//jeśli suma jest za mała to przesuwamy prawy koniec segmentu
      suma:=suma+A[p];
      p:=p+1;
    end
    else begin			//jeśli za duża to przesuwamy lewy koniec segmentu
      suma:= suma-A[l];
      l:=l-1;
    end;
  while (suma > W) do begin  
    suma:= suma-A[l];
    l:=l-1;
  end;
  znalezione:=(suma=W);
end.

Rozwiązanie

Całkowita poprawność

Zadanie 3 (Głosowanie większościowe)

Udowodnij częściową poprawność dla podanego poniżej zadania i jego rozwiązania.

Zadanie Dana jest tablica A typu array[1..N] of integer, N > 0. Sprawdź czyjest w niej element wystepujący więcej niż N/2 razy i jeśli tak wskażgo.

Program

program Głosowanie2(N,W:integer; A:array[1..N] of integer);
var ile,i,kand,lider: integer;
begin
  kand:=A[1];		//szukamy kandydata na lidera
  ile := 1;
  i:=2;
  while i <= N do begin	
    if A[i]=kand then begin
      ile:=ile+1;
      i:=i+1;
    end
    else
      if ile > 0 then begin
        ile:=ile-1;
        i:=i+1;
      end
      else begin
        kand:=A[i];
        ile:=1;
        i:=i+1;
      end;
  end;
  ile:=0;		//sprawdzamy czy kandydat jest liderem
  for i:=1 to do 
    if A[i]=kand then ile:=ile+1; 
  if (ile >= (N div 2 + 1) then begin 
    lider:=kand;
    write('Liderem jest: ', kand);
  end 
  else 
    lider:=0;
end.

Rozwiązanie

Zadanie 4 (BinPower)

Udowodnij częściową poprawność dla podanego poniżej zadania i jego rozwiązania.

Zadanie Dla zadanych x,n > 0 wyznacz xn (oczywiscie bez exp i ln).

Program

function BinPower(x,n:integer):integer;
// Dla x,n > 0 wyznaczamy x do potęgi n 
var z,y,i: integer;
begin
  z:=1;
  y:=x;
  i:=n;
  while i > 0 do begin
    if (i mod 2 = 1) then z:=z*y;
    y:=y*y;
    i:=i div 2;
  end;
  BinPower:=z;
end;

Rozwiązanie