Poszukiwanie liniowe wśród liczb naturalnych Wiele problemów, dotyczących liczb naturalnych, można rozwiązać idąc w góręodzera(lubczasemodinnejliczby)isprawdzając,czyjuż. Przykład: (zadane reszty z dzielenia) MDanesąliczbyp>q 0orazs>r 0;pissąwzględniepierwsze, czyli nie mają wspólnych dzielników większych niż 1. Znaleźć najmniejszą liczbęn>0,która 1.wdzieleniuprzezpdajeresztęq, 2.wdzieleniuprzezsdajeresztęr. Niech n przebiega po kolei wszystkie liczby postaci 0 p+q,1 p+q,2 p+q,... (war.1),ażnatrafinataką,któraspełniawar.2. Wykład 3. POSZUKIWANIE I TABLICE, str. 2 Poszukiwanie liniowe wśród liczb naturalnych /*p>q 0&s>r 0*/ n=q; /*n%p=q*/ while(n%s!=r) { n=n+p; /*n%p=q &n%s=r*/ p q s r n 16 11 9 7 11 27 43 p%k wjęzykuc:resztazdzieleniapprzezk To jest szczególny przypadek chińskiego twierdzenia o resztach
Poszukiwanie liniowe wśród liczb naturalnych Przykład: (liczby pierwsze) MDanejestn 1.Znaleźćnajmniejsząliczbępierwsząwiększąniżn. Liczba p jest pierwsza, jeśli nie dzieli się przez żadną liczbę k spełniającą 2 k<p. Niech p oznacza zawsze kandydata na poszukiwaną liczbę pierwszą; zaczniemyodp=n+1ibędziemysprawdzaćjejpodzielnośćprzezliczbyk od2dop 1. Jeśliznajdziemydzielnikk,tozwiększymykandydatapo1izaczniemy sprawdzanie znowu od 2. Jeślidojdziemyzkdop 1ipodrodzenienatrafimynadzielnikp, to p jest liczbą pierwszą. Wykład 3. POSZUKIWANIE I TABLICE, str. 4 Poszukiwanie liniowe wśród liczb naturalnych /*n 1*/ p=n+1; k=2; /*p>n 1&k p pniedzielisięprzezi [2..k 1]*/ while(k<p) { if(p%k==0) { /*pjestzłymkandydatem*/ p=p+1; k=2; else/* trzeba sprawdzać dalej*/ k=k+1; /*p>n 1& pniedzielisięprzezi [2..p 1]*/ p%k wc:resztazdzieleniapprzezk n p k 8 9 2 3 10 2 11 2 3 4 5 6 7 8 9 10 11
Tablice czyli zmienne indeksowane W językach programowania występują tablice zmienne indeksowane reprezentujące skończone ciągi liczbowe. Indeksami są dowolne wyrażenie całkowite,wprogramieujmujesięjewnawiasy kwadratowe, np. zamiasta i piszemya[i], zamiasta 2 i 1 piszemya[2*i-1]. a: a 0 = 15 a 1 = 0 a 2 = 24 a 3 = 66 a 4 = 0 a: 0 15 1 0 2-24 3 66 4 0 W C indeksowanie tablicy biegnie zawsze od zera; t.zn. tablica n-elementowa a zawiera elementy a[0],a[1],a[2],...,a[n-1] Element a[n] nie istnieje. Wykład 3. POSZUKIWANIE I TABLICE, str. 6 Tablice czyli zmienne indeksowane Typowy program z tablicami w C: nagłówek deklaracje { wejście(w pętli) obliczenie { wyjście(w pętli) main() { int i, a[100]; for(i=0; i<100; i=i+1) scanf("%i",&a[i]);......... for(i=0; i<100; i=i+1) printf("a[%i]==%i\n",i,a[i]);
Iteracja for i A i<b i B C i i+1 for(i=a;i<b;i=i+1)c iterację for można wyrazić przy pomocy while-a: i=a;while(i<b) {Ci=i+1; graniceaiborazzmiennasterującaiprawidłowo skonstruowanej iteracji nie powinny podlegać zmianie w ciele iteracji C; iteracja for nadaje się idealnie do przeglądania tablicy; ale nie tylko do tego. Wykład 3. POSZUKIWANIE I TABLICE, str. 8 Tablice czyli zmienne indeksowane Przykład: (odwracanie ciągu liczb) MŻebywczytaćciągnliczbinapisaćgoodkońca,trzebajegonwyrazów czasowo zapamiętać; można to zrobić na przykład w tablicy: for(i=0; i<n; i=i+1) scanf("%i",&a[i]); for(i=n-1;i>=0;i=i-1) printf("%i",a[i]); 0 11 wejście 1 2 3 2 16 4 wyjście 11 2 16 4 0 4 0 0 4 16 2 11
Tablice czyli zmienne indeksowane Przykład: (maksimum) MZnaleźć największą liczbę w ciągu N-elementowym, którego wszystkie wyrazysąnieujemne:a i 0dlai [0...N 1]. max=0; for(n=0; n<n; n=n+1) if(max<a[n])max=a[n]; Samodzielny program, wczytujący liczby do tablicy, obliczający maksimum i drukujący, nie ma wiele sensu. Liczyć maksimum można w locie, niczego nie zapamiętując w tablicy. Jednak powyższy fragment programu, liczący maksimum tablicy, można wykorzystać jako fragment większej całości. Sortowanie Wykład 3. POSZUKIWANIE I TABLICE, str. 10 W tablicy a długości n zapisane są liczby. Należy je tak poprzestawiać, żeby a 0 a 1... a n 1. Sortowanietablicya[0..n 1]przezwybórmaksimum: 1.znaleźćtakiek [0..n 1],żea k jestmaksimumtablicya[0..n 1] 2.zamienića k za n 1 3.posortowaćkrótszątablicęa[0..n 2] for(i=n;i>=2;i=i-1) { znaleźćtakiek [0..i 1],że p [0..i 1] a p a k ; zamienića k za i 1 ;
Sortowanie 0 15 1 7 2 23 3 7 4 11 5 0 MAX OSTATNI i=6 for(i=n;i>=2;i=i-1) { znaleźćtakiek [0..i 1], że p [0..i 1] a p a k ; zamienića k za i 1 ; Sortowanie Wykład 3. POSZUKIWANIE I TABLICE, str. 12 0 7 1 7 2 0 3 11 4 15 5 23 i=1 for(i=n;i>=2;i=i-1) { znaleźćtakiek [0..i 1], że p [0..i 1] a p a k ; zamienića k za i 1 ; Jakznajdowaćtakiek,żebya k byłomaksymalne? tojużwiemy. Jak zamieniać?
Sortowanie Jak zamieniać a[k] z a[i-1]? a[k] a[i-1] Przypisanie: a[k]=a[i-1]; ŹLE! Sortowanie Wykład 3. POSZUKIWANIE I TABLICE, str. 14 Jak zamieniać a[k] z a[i-1]? a[k] 2 a[i-1] 1 3 pomocnicza Trzy kroki: 1 pomocnicza=a[k]; 2 a[k]=a[i-1]; 3 a[i-1] = pomocnicza;
Sortowanie for(i=n;i>=2;i=i-1) { k=0; for(j=1; j<i; j=j+1) if(a[k]<a[j]) k=j; x=a[k]; a[k]=a[i-1]; a[i-1]=x; znajdowanie maksimum zamiana Ile zamian? W każdym obiegu zewnętrznej pętli: jedna. Więcrazem:n 1. Ile porównań elementów tablicy? Wkażdymi-tymobieguzewnętrznejpętli:i 1. n Więc razem: (i 1)= n(n 1) = n2 2 2 n 2 i=2 Sortowanie Wykład 3. POSZUKIWANIE I TABLICE, str. 16 Istnieje wiele różnych algorytmów sortowania tablicy, różniących się: czasem działania w zależności od długości tablicy(w sortowaniu przez maksimum:okołon 2 ), zajętością dodatkowej pamięci(w sortowaniu przez maksimum: w miejscu), długością zamian(sortowanie przez maksimum: n 1), możliwościami zrównoleglenia działań przy użyciu większej liczby procesorów, itp. ISTNIEJĄ ZNACZNIE SZYBSZE ALGORYTMY SORTOWANIA
Niebezpieczeństwa związane z tablicami Wyjście indeksu poza zakres Znaleźćpierwszezerowtablicya[0..n-1]: i=0; while(a[i]!=0&&i<n) i=i+1; i=0; while(i<n&&a[i]!=0) i=i+1; jeśliwa[0..n-1]niemawcalezera,topętlapolewejniezatrzyma się na czas i sięgnie po nieistniejący element a[n]. WCmożnatemuzapobiecprzezodwrócenie koniunkcji, jak w pętli po prawej.koniunkcjawcniejestsymetryczna, najpierw liczy się lewy argument. Winnychjęzykachbywaróżnie... & błąd fałsz prawda błąd błąd błąd błąd fałsz fałsz fałsz fałsz prawda błąd fałsz prawda Wykład 3. POSZUKIWANIE I TABLICE, str. 18 Niebezpieczeństwa związane z tablicami Niepewna tożsamość zmiennych Tablicaa[0..n-1].Czyteinstrukcje zerują jej wszystkie pola? for(i=0; i<n; i=i+2) a[i]=0; for(i=n-1; i>=0; i=i-2) a[i]=0; Jeśli n jest parzyste, tak. Jeśli n jest nieparzyste, nie. Różne zmienne mogą w programie wyglądać tak samo; np. a[i] oznacza różne zmienne, zależnie od wartości i. Ta sama zmienna może w różnych miejscach programu wyglądać różnie; np.a[i+1]ia[j-1]totasamazmienna,jeślij=i+2.
Poszukiwanie liniowe Załóżmy,żetablicaa[0..n 1]jestwypełnionaliczbami;imamydaną liczbęx.wyszukaćxwtablicya;t.zn. znaleźćtakiep,żea[p]=x,lub upewnićsię,żetakiepnieistnieje(czylixniewystępujewtablicya). #define FALSE 0 #define TRUE 1... //n 0 znal=false; p=0; //0 p n& ( ) // (znal&a[p]=x) ( znal&wa[0..p 1]niemax) while(!znal&& p<n) if(a[p] == x) znal=true; else p=p+1; //(znal&a[p]=x) ( znal&wa[0..n 1]niemax) Metody łapania lwa na pustyni Wykład 3. POSZUKIWANIE I TABLICE, str. 20 Fizyczna: Przesypać całą pustynię przez sito. To, co przeleci,topiasek;to,cozostaniewsicie,tolew. Matematyczna: Zamknąć się w klatce; następnie dokonać inwersji przestrzeni względem klatki: my znajdziemysięnazewnątrzalewwklatce.uwaga! niestaćwśrodkuklatki,boprzyinwersjito miejsce przechodzi na punkt w nieskończoności. Informatyczna: Podzielić pustynię na pół; połowę, w której jest lew, znowu na pół; ćwiartkę, wktórejjestlew,napół... Takpostępować,ażrozpatrywanyfragment pustyni zmaleje do rozmiaru podstawy klatki. Na tym fragmencie pustyni postawić klatkę.
Poszukiwanie binarne Zadanie:policzyćb= 5 10zdokładnościądo0.1(czyli b 5 10 <0.1). a=1jestzamałe,bo1 5 =1 10;c=2jestzaduże,bo10<32=2 5. a 5 10<c 5 abc 1.000 1.125 1.250 1.375 1.500 1.625 1.750 1.875 2.000 a b= a+c 2 c b 5 b 5 10 1.000 2.000 1.500 7.594 TAK 1.500 2.000 1.750 16.413 NIE 1.500 1.750 1.625 11.331 NIE 1.500 1.625 1.563 9.313 TAK 1.563 1.625 1.594 10.283 NIE Poszukiwanie binarne Wykład 3. POSZUKIWANIE I TABLICE, str. 22 Zadanie: n>0iε>0 policzyćb= 5 nzdokładnościądoε(czyli b 5 n <ε). a=0;b=n/2;c=n; //a 5 n<c 5 &b= a+b 2 while(c-a>=ε) { if(b 5 <=n) a=b; else c=b; b=(a+c)/2;
Poszukiwanie binarne Załóżmy,żetablicaa[0..n 1]jestwypełnionaliczbamiiuporządkowana; imamydanąliczbęx.wyszukaćxwtablicya. //n>0 if(x < a[0]) znal=false; else { //n>0&a[0] x<a[n]=+ p=0;q=n; //0 p<q n&a[p] x<a[q] while(q-p>1) { r=(p+q)/2; if(x<a[r]) q=r; else p=r; //a[p] x<a[p+1] if(x == a[p]) znal=true; else znal=false; //(znal&a[p]=x) ( znal&wa[0..n 1]niemax)