• Nie Znaleziono Wyników

Ćwiczenie laboratoryjne Algorytm sortowania przez scalanie

N/A
N/A
Protected

Academic year: 2022

Share "Ćwiczenie laboratoryjne Algorytm sortowania przez scalanie"

Copied!
8
0
0

Pełen tekst

(1)

Ćwiczenie laboratoryjne

„Algorytm sortowania przez scalanie”

Sprawozdanie

Na każdym zajęciu laboratoryjnym sporządza się za pomocą edytora Word sprawozdanie.

Bazowa zawartość sprawozdania musi być przygotowana w domu przed ćwiczeniem (sprawozdanie do ćwiczenia pierwszego jest przygotowywane w czasie ćwiczenia).

W czasie ćwiczenia do sprawozdania są dodawane wyniki testowania.

Treść sprawozdania:

strona tytułowa,

spis treści sporządzony za pomocą Word'a,

dla każdego zadania rozdziały "Zadanie ", "Opracowanie zadania" (rozdział z tekstem programu i komentarzami),

"Testowanie" (rozdział z opisem danych wejściowych i wynikami testowania, w tym zrzuty aktywnego okna).

Wzorzec strony tytułowej znajduje się w pliku Strona_tytulowa_niestac_AiSD.doc.

Nazwa (bez polskich liter, żeby można było archiwizować) pliku ze sprawozdaniem musi zawierać skrót "AiSD_", numer grupy, numer ćwiczenia i nazwisko studenta.

Pliki ze sprawozdaniem są przekazywane do archiwum grupy.

Sortowanie przez scalanie Zadanie

Zadanie polega na oprogramowaniu algorytmu sortowania przez scalanie.

Jest to bazowy algorytm przy sortowaniu danych w plikach.

Sortować dane według wariantu z tabeli wariantów.

Wygenerować do pliku 100000 pseudolosowych danych, posortować, zmierzyć i wyświetlić czas sortowania.

Opracowanie zadania

( t e k s t p r o g r a m u )

Testowanie

Sprawdzić swój program na 10 danych.

Zmierzyć czas sortowania 100000 danych.

( p r z e d s t a w i ć z r z u t o k n a i f r a g m e n t y p l i k ó w )

Tabela wariantów Np Typ

danej Zakres danych Na początku tablicy N

p Typ

danej Zakres danych Na początku tablicy 1 liczba 0 .. 99 najmniejszy 17 liczba 0 .. 99 największy 2 liczba -99 .. 99 najmniejszy 18 liczba -99 .. 99 największy 3 liczba 100 .. 199 najmniejszy 19 liczba 100 .. 199 największy 4 liczba -199 .. +199 najmniejszy 20 liczba -199 .. +199 największy 5 liczba 200 .. 299 najmniejszy 21 liczba 200 .. 299 największy 6 liczba -299 ..299 najmniejszy 22 liczba -299 ..299 największy 7 liczba 300 .. 399 najmniejszy 23 liczba 300 .. 399 największy 8 liczba -399 .. +399 najmniejszy 24 liczba -399 .. +399 największy 9 litera A .. G najmniejszy 25 litera A .. G największy 10 litera D .. J najmniejszy 26 litera D .. J największy 11 litera G .. M najmniejszy 27 litera G .. M największy 12 litera J .. P najmniejszy 28 litera J .. P największy 13 litera M .. S najmniejszy 29 litera M .. S największy 14 litera P .. V najmniejszy 30 litera P .. V największy 15 litera S .. Y najmniejszy 31 litera S .. Y największy 16 litera T .. Z najmniejszy 32 litera T .. Z największy

(2)

Wskazówki

Opracowanie graficznej części aplikacji Nadać formularzowi nagłówek

„Sortowanie przez scalanie. Autor ... ”.

Wprowadzić do formularza obiekty graficzne do inicjalizacji sortowania (klawisz sterujący).

Programowanie operacji

W procedurach sortowania są potrzebne następujące pliki nagłówkowe:

#include <string.h>

#include <stdio.h>

#include <io.h>

#include <direct.h>

#include <stdlib.h>

#include <time.h>

#include <vcclr.h>

#include <assert.h>

Znaki (litery) muszą być typu int.

Generować i zapisywać znak za pomocą instrukcji:

int znak='A'+(rand()*('Z'-'A'))/RAND_MAX;

sprintf(buf,"%c\n",znak);

fputs(buf,pf0); //zapisywanie bufora

Sortowanie przez scalanie w plikach można realizować w strukturze, która ma nazwę struktury

"trzech plików":

|-<--<--<--<--<---<--<--|

| ->(plik 2)->|

v / (plik 0)-->-->-(plik 1)-->-

^ \ | ->(plik 3)->|

|-<--<--<--<--<---<--<--|

faza scalania faza rozdzielania

Przed sortowaniem dane są przepisywane z pliku 0 (źródłowego) do pliku 1. Po sortowaniu plik 1 występuje jako plik wynikowy.

Proces sortowania zawiera etap (fazę) rozdzielania pliku 1 na dwa pliki 2 i 3 oraz etap (fazę) scalania plików 2 i 3 w plik 1.

Na etapie rozdzielania plik 1 jest dzielony na części rozmiarem rg (od wartości 1), które są zapisywane kolejno do plików 2 i 3. Po scalaniu plików rozmiar posortowanej części jest równy 2*rg, i dlatego w następnym etapie rozdzielania wartość rg zwiększa się o dwa razy.

Proces sortowania będzie zakończony, gdy przed rozdzielaniem wartość rg będzie większa lub równa rozmiarowi pliku 1.

Przytoczona niżej procedura sortuje przez scalanie dane liczbowe.

(3)

Procedura scalania danych liczbowych

//--- Implementacja algorytmu sortowania przez scalanie danych liczbowych void SortScalanie(int nn,FILE* pf1,FILE* pf2,FILE* pf3)

{// nn - rozmiar danych wejściowych i wynikowych

// pf1, pf2, pf3 – wskaźniki na struktury FILE już otwartych plików // plik pf1 występuje jako plik źródłowy i wynikowy

int rg=1; //rozmiar grupy liczb w plikach 2 i 3

int rozm1=0,rozm2=0,rozm3=0; //ilości liczb w plikach 1, 2 i 3 char *pch=NULL,*pch2=NULL,*pch3=NULL;

char buf[8],buf2[8],buf3[8];

rozm1=nn;

//----

while (rg<nn) {

//---rozdzielanie---

fseek(pf1,0,SEEK_SET); //ustawienie na początek fseek(pf2,0,SEEK_SET); //ustawienie na początek fseek(pf3,0,SEEK_SET); //ustawienie na początek rozm2=0;

rozm3=0;

bool kier=true; //true ~ kierunek "plik1 --> plik2"; false ~ kierunek "plik1 --> plik3"

for (int poz1=0;poz1<rozm1;poz1++) { //index w pliku 1

pch=fgets(buf,8,pf1);

if (pch!=NULL) {

if (kier) {

fputs(buf,pf2);

rozm2++;

} else {

fputs(buf,pf3);

rozm3++;

} }

else break; //break poz1

if ((poz1%rg)==(rg-1)) kier=!kier;

}

//---scalanie---

fseek(pf1,0,SEEK_SET); //ustawienie na początek fseek(pf2,0,SEEK_SET); //ustawienie na początek fseek(pf3,0,SEEK_SET); //ustawienie na początek rozm1=0;

int maxrozm23=(rozm2>=rozm3)? rozm2: rozm3;

for (int poz=0;poz<maxrozm23;poz+=rg) { //początek grupy w plikach 2 i 3

int i2=0,i3=0;

int liczba2=0,liczba3=0;

bool bPowtor=true; //znacznik powtórzenia bool bOdczyt2=true; //znacznik odczytu z pliku 2 bool bOdczyt3=true; //znacznik odczytu z pliku 3 while (bPowtor)

{

(4)

bool bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

bool bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

if (!bJest2 && !bJest3) break; //break "while (bPowtor)"

if (!bJest2 && bJest3) {//dane tylko w pliku 3

while (bJest3) {

pch3=fgets(buf3,8,pf3);

assert (pch3!=NULL);

fputs(buf3,pf1);

rozm1++;

i3++;

bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

}

break; //break "while (bPowtor)"

}

if (bJest2 && !bJest3) {//dane tylko w pliku 2

while (bJest2) {

pch2=fgets(buf2,8,pf2);

assert (pch2!=NULL);

fputs(buf2,pf1);

rozm1++;

i2++;

bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

}

break; //break "while (bPowtor)"

} //---

if (bOdczyt2 && bJest2) {//odczyt z pliku 2

pch2=fgets(buf2,8,pf2);

assert(pch2!=NULL);

sscanf(buf2,"%6d",&liczba2);

bOdczyt2=false; //zakaz nowego odczytu }

if (bOdczyt3 && bJest3) {//odczyt z pliku 3

pch3=fgets(buf3,8,pf3);

assert (pch3!=NULL);

sscanf(buf3,"%6d",&liczba3);

bOdczyt3=false; //zakaz nowego odczytu }

//---

if (liczba2<=liczba3) {

fputs(buf2,pf1);//zapisywanie daną z pliku 2 rozm1++;

i2++;

bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

if (!bJest2)

{//dane tylko w pliku 3 while (bJest3) {

fputs(buf3,pf1);//zapisywanie daną z pliku 3

(5)

rozm1++;

i3++;

bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

if (bJest3) {

pch3=fgets(buf3,8,pf3);

assert(pch3!=NULL);

} }

break; //break "while (bPowtor)"

} else

bOdczyt2=true;

} else

{//liczba2>liczba3

fputs(buf3,pf1);//zapisywanie daną z pliku 3 rozm1++;

i3++;

bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

if (!bJest3)

{//dane tylko w pliku 2 while (bJest2) {

fputs(buf2,pf1);//zapisywanie daną z pliku 2 rozm1++;

i2++;

bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

if (bJest2) {

pch2=fgets(buf2,8,pf2);

assert(pch2!=NULL);

} }

break; //break "while (bPowtor)"

} else

bOdczyt3=true;

}

bPowtor=(i2<rg && (poz+i2)<rozm2) || (i3<rg && (poz+i3)<rozm3);

}//while (bPowtor) }// poz

//--- rg+=rg; // rg=rg*2 }//while (rg<nn) }

Przytoczona niżej procedura sortuje przez scalanie dane znakowe.

(6)

Procedura scalania danych znakowych

//--- Implementacja algorytmu sortowania przez scalanie danych znakowych void SortScalanie(int nn,FILE* pf1,FILE* pf2,FILE* pf3)

{// rozmiar nn dla danych wejściowych i wynikowych

// pf1, pf2, pf3 – wskaźniki na struktury FILE już otwartych plików // plik pf1 występuje jako plik źródłowy i wynikowy

int rg=1; //rozmiar grupy znaków w plikach 2 i 3

int rozm1=0,rozm2=0,rozm3=0; //ilości znaków w plikach 1, 2 i 3 char *pch=NULL,*pch2=NULL,*pch3=NULL;

char buf[8],buf2[8],buf3[8];

rozm1=nn;

//----

while (rg<nn) {

//---rozdzielanie---

fseek(pf1,0,SEEK_SET); //ustawienie na początek fseek(pf2,0,SEEK_SET); //ustawienie na początek fseek(pf3,0,SEEK_SET); //ustawienie na początek rozm2=0;

rozm3=0;

bool kier=true; //true ~ kierunek "plik1 --> plik2"; false ~ kierunek "plik1 --> plik3"

for (int poz1=0;poz1<rozm1;poz1++) { //indeks w pliku 1

pch=fgets(buf,8,pf1);

if (pch!=NULL) {

if (kier) {

fputs(buf,pf2);

rozm2++;

} else {

fputs(buf,pf3);

rozm3++;

} }

else break; //break poz1

if ((poz1%rg)==(rg-1)) kier=!kier;

}

//---scalanie---

fseek(pf1,0,SEEK_SET); //ustawienie na początek fseek(pf2,0,SEEK_SET); //ustawienie na początek fseek(pf3,0,SEEK_SET); //ustawienie na początek rozm1=0;

int maxrozm23=(rozm2>=rozm3)? rozm2: rozm3;

for (int poz=0;poz<maxrozm23;poz+=rg) { //początek grupy w plikach 2 i 3

int i2=0,i3=0;

int znak2=0,znak3=0;

bool bPowtor=true; //znacznik powtórzenia bool bOdczyt2=true; //znacznik odczytu z pliku 2 bool bOdczyt3=true; //znacznik odczytu z pliku 3 while (bPowtor)

{

(7)

bool bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

bool bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

if (!bJest2 && !bJest3) break; //break "while (bPowtor)"

if (!bJest2 && bJest3) {//dane tylko w pliku 3

while (bJest3) {

pch3=fgets(buf3,8,pf3);

assert (pch3!=NULL);

fputs(buf3,pf1);

rozm1++;

i3++;

bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

}

break; //break "while (bPowtor)"

}

if (bJest2 && !bJest3) {//dane tylko w pliku 2

while (bJest2) {

pch2=fgets(buf2,8,pf2);

assert (pch2!=NULL);

fputs(buf2,pf1);

rozm1++;

i2++;

bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

}

break; //break "while (bPowtor)"

} //---

if (bOdczyt2 && bJest2) {//odczyt z pliku 2

pch2=fgets(buf2,8,pf2);

assert(pch2!=NULL);

sscanf(buf2,"%c",&znak2);

bOdczyt2=false; //zakaz nowego odczytu }

if (bOdczyt3 && bJest3) {//odczyt z pliku 3

pch3=fgets(buf3,8,pf3);

assert (pch3!=NULL);

sscanf(buf3,"%c",&znak3);

bOdczyt3=false; //zakaz nowego odczytu }

//---

if (znak2<=znak3) {

fputs(buf2,pf1);//zapisywanie daną z pliku 2 rozm1++;

i2++;

bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

if (!bJest2)

{//dane tylko w pliku 3 while (bJest3) {

fputs(buf3,pf1);//zapisywanie daną z pliku 3

(8)

rozm1++;

i3++;

bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

if (bJest3) {

pch3=fgets(buf3,8,pf3);

assert(pch3!=NULL);

} }

break; //break "while (bPowtor)"

} else

bOdczyt2=true;

} else

{//znak2>znak3

fputs(buf3,pf1);//zapisywanie daną z pliku 3 rozm1++;

i3++;

bJest3=i3<rg && (poz+i3)<rozm3; //znacznik "jeszcze jest dana"

if (!bJest3)

{//dane tylko w pliku 2 while (bJest2) {

fputs(buf2,pf1);//zapisywanie daną z pliku 2 rozm1++;

i2++;

bJest2=i2<rg && (poz+i2)<rozm2; //znacznik "jeszcze jest dana"

if (bJest2) {

pch2=fgets(buf2,8,pf2);

assert(pch2!=NULL);

} }

break; //break "while (bPowtor)"

} else

bOdczyt3=true;

}

bPowtor=(i2<rg && (poz+i2)<rozm2) || (i3<rg && (poz+i3)<rozm3);

}//while (bPowtor) }// poz

//--- rg+=rg; // rg=rg*2 }//while (rg<nn) }

Cytaty

Powiązane dokumenty

a) Na podstawie porównania okruchów (szklanych, mineralnych itp) powiązać (wykluczyć) osobę ze zdarzeniem. b) Okruchy szkła przypisać do jednego z wymienionych

a) Podejrzewa się, Ŝe na przedstawionym dokumencie dopisano pewne fragmenty. b) Podejrzewa się, Ŝe przedstawiony dokument

Praca zbiorowa, Kalendarz Chemiczny, Część II Technologiczna, Tom I, PWT, Warszawa 1955.. Kalinina, Chemiczna analiza

Porównać fragmenty materiałów, oznaczyć rodzaj podłoŜa, dokanać jego klasyfikacji.. Rutkowski, Metody badań w przemyśle celulozowo

W trakcie przeszukania mieszkania podejrzanego o wysyłanie anonimów, zabezpieczono róŜne materiały (kleje, fragmenty

Кроме значения ʻне работать, а отдыхать в понедельникʼ, как, например, в пословице Захотіла баба, понеділкувавши, трудодень мати (УНПП 1955,

12 Kraking katalityczny i analiza produktów naftowych Skrypt dostępny w czytelni i pokoju

Student z numerem indeksu 206591 zainspirował się twórczością kolegi na tyle silnie, że zapożyczył nawet numer indeksu na oddanym opracowaniu... Wyznaczanie