Aleksander Timofiejew
Transkrypt
Aleksander Timofiejew
Ćwiczenie laboratoryjne „Oprogramowanie i badanie stosu” Tematy ćwiczenia realizacja stosu dla tablicowej i listowej reprezentacji, operacje na stosie. 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 ćwiczenia i nazwisko studenta. Pliki ze sprawozdaniem są przekazywane do archiwum grupy. a) Stos przy tablicowej reprezentacji Zadanie Zadanie polega na oprogramowaniu stosu liczb dla tablicowej reprezentacji. Program musi wyświetlać zawartość stosu oraz wartość elementu na wierzchu stosu, przyjmować i odkładać na stos nowy element, zdejmować element ze stosu, komunikować o przepełnieniu stosu i o tym, że stos jest pusty. Opracowanie zadania (tekst programu) Testowanie Wypróbować zdejmowanie elementu ze stosu i otrzymać komunikat, że stos jest pusty. Wprowadzić i położyć na stos elementy danych (liczby lub litery) sprawdzając poprawność odkładania i przemieszczenia wskaźnika stosu. Zdejmować ze stosu elementów danych (liczby lub litery) sprawdzając poprawność wyprowadzenia i przemieszczenia wskaźnika stosu. Wprowadzać do stosu elementy danych (liczby lub litery) do otrzymania komunikatu o przepełnieniu stosu. Do sprawozdania dołączyć ( z r z u t e k r a n u a p l i k a c j i ) . Warianty dla struktury bazowej "tablica" Wariant 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Typ elementu liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba Rozmiar 10 10 20 20 30 30 40 40 15 15 25 25 35 35 5 5 Indeks od od od od od od od od od od od od od od od od -1 0 0 –1 -1 0 0 –1 -1 0 0 –1 -1 0 0 –1 Wariant 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 Typ elementu litera litera litera litera litera litera litera litera litera litera litera litera litera litera litera litera Rozmiar Indeks 10 10 20 20 30 30 40 40 15 15 25 25 35 35 5 5 od -1 od 0 od 0 od –1 od -1 od 0 od 0 od –1 od -1 od 0 od 0 od –1 od -1 od 0 od 0 od –1 Wskazówki 1) Środowisko Wejść do środowiska Microsoft Visual Studio 2015. Wybrać punkt menu „File / New / Project...”, zaznaczyć rodzaj aplikacji „CLR” w „Templates / Visual C++” i wybrać "CLR Empty Project", dalej na dole okna w polu "Name" wprowadzić nazwę projektu, na przykład „Pr1”, a za pomocą przycisku "Browse" w polu "Location" wyznaczyć folder projektu. Nacisnąć przycisk "OK". W menu projektu wybrać "PROJECT / Properties". W oknie "Property Pages" wpisać do opcji "Configuration Properties / Linker / Advanced / Entry Point" nazwę "main"; W opcji "Property Pages / Configuration Properties / Linker / Debugging / Generate Debug Info" ustawić "Optimize for debugging (/DEBUG)"; Nacisnąć przyciski "Zastosuj" i "OK". W podoknie "Solution Explorer" nacisnąć prawym przyciskiem myszy na nazwę projektu, wybrać punkt menu "Add / New Item...", wybrać "UI / Windows Form" i nacisnąć "Add". Do pliku "MyForm.cpp" dodać tekst z głównym podprogramem "main": using namespace System; using namespace System::Windows::Forms; [STAThreadAttribute] int main(cli::array<System::String^>^ args) { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); Application::Run(gcnew Pr::MyForm()); } gdzie "Pr" to nazwa projektu. Opracowanie graficznej części aplikacji Dodać do formularza obiekty graficzne: - obiekt typu ListBox do wyświetlenia zawartości stosu i elementu na wierzchu stosu, - do wprowadzenia nowego elementu przycisk "Dodaj" i okienko NumericUpDown dla elementu typu "Liczba" albo TextBox dla elementu typu "Litera", - obiekt typu StatusBar do komunikowania o przepełnieniu stosu oraz o tym, że stos jest pusty (jeżeli w Toolbox nie ma komponentu StatusBar, to należy dodać ten komponent przez punkt menu Tools/Choose Toolbox Items), - do zdejmowania elementu ze stosu przycisk "Zdejmij" i okienko NumericUpDown dla elementu typu "Liczba" albo TextBox dla elementu typu "Litera". Do pokazywania zawartości stosu oraz elementu na wierzchu stosu jest wygodnie korzystać z obiektu typu ListBox. Wierzchowi stosu może odpowiadać zaznaczony wiersz ListBox’a. Aby zaznaczać pojedynczy wiersz w obiekcie typu ListBox należy ustawić właściwość SelectionMode na "One". Właściwość SelectedIndex ListBox'a służy do wyboru wierszu do zaznaczenia. Przykładowo: listBox1->SelectedIndex=-1 //brak zaznaczonego wierszu listBox1->SelectedIndex=2 //zaznaczony jest wiersz 3 z indeksem 2 (indeksy od 0) Należy zadeklarować jako globalne na początku pliku z klasą formularza tablicę - stos, indeks elementu na wierzchu stosu oraz rozmiar stosu. W przypadku danej - liczby należy zdefiniować tablicę z elementami typu int: const int RS=10; //rozmiar stosu int stos[RS]; // stos int js=-1; // indeks stosu //lub int js=0; // indeks stosu W przypadku danej - litery należy zdefiniować tablicę z elementami typu wchar_t. const int RS=10; //rozmiar stosu wchar_t stos[RS]; // stos int js=-1; // indeks stosu //lub int js=0; // indeks stosu Obiekt typu NumericUpDown ma właściwość Value typu System::Decimal. Aby odczytać wprowadzoną liczbę należy zastosować instrukcję: int dana=(int)numericUpDown1->Value; Aby zapisać liczbę należy zastosować instrukcję: textBox1->Text=dana.ToString(); Obiekt typu TextBox ma właściwość Text typu String^. Aby odczytać wprowadzoną (pierwszą) literę należy zastosować instrukcję: wchar_t dana=textBox1->Text[0]; Aby zapisać literę należy zastosować instrukcję: textBox1->Text=dana.ToString(); Bazowe operacje na stosie powinny być realizowane ze sprawdzaniem, czy jest stos pusty oraz czy jest stos zapełniony. Do wyświetlenia tekstów komunikatów można dodać do formularza obiekt typu „StatusBar”. Wyświetlenie komunikatu w obiekcie typu StatusBar: statusBar1->Text = "..."; Inny sposób wyświetlenia tekstów komunikatów - wykorzystanie statycznej metody Show() klasy MessageBox: System::Windows::Forms::MessageBox::Show( "tekst komunikatu", "Komunikat", MessageBoxButtons::OK, MessageBoxIcon::Exclamation ); Warunek "czy jest stos pusty" sprawdzamy następująco: if (js<0) // lub if (js==0) { // komunikat "Stos jest pusty" } else { // instrukcje zdejmowania elementu ze stosu } Warunek "czy jest stos zapełniony" sprawdzamy następująco: if (js>=RS-1) //lub if (js>=RS) { // komunikat "Stos jest zapełniony" } else { // instrukcje odkładania elementu na stos } Po wykonaniu operacji nad stosem należy przenieść zawartość tablicy do ListBox'a: listBox1->Items->Clear(); for (int i=0;i<=js;i++) listBox1->Items->Add(stos[i]); listBox1->SelectedIndex = js; Operacje przy początkowej wartości indeksu stosu równej -1 W przypadku początkowej wartości indeksu stosu równej -1 w celu dodawania do stosu nowego elementu korzystamy z dwóch instrukcji: 1) zwiększenie indeksu stosu o jeden, 2) zapisywanie do tablicy stosu nowego elementu według indeksu stosu. W przypadku początkowej wartości indeksu stosu równej -1 zdejmowanie elementu wykonujemy za dwa kroki: 1) odczyt z tablicy stosu elementu według indeksu stosu, 2) zmniejszenie indeksu stosu o jeden. Operacje przy początkowej wartości indeksu stosu równej 0 W przypadku początkowej wartości indeksu stosu równej 0 w celu dodawania do stosu nowego elementu korzystamy z dwóch instrukcji: 1) zapisywanie do tablicy stosu nowego elementu według indeksu stosu, 2) zwiększenie indeksu stosu o jeden. W przypadku początkowej wartości indeksu stosu równej 0 element jest zdejmowany w dwa kroki: 1) zmniejszenie indeksu stosu o jeden, 2) odczyt z tablicy stosu elementu według indeksu stosu. b) Stos przy listowej reprezentacji Zadanie Zadanie polega na oprogramowaniu stosu z elementami - liczbami lub elementami - literami dla listowej reprezentacji. Program musi wyświetlać zawartość stosu oraz wartość elementu na wierzchu stosu, przyjmować i odkładać na stos nowy element, zdejmować element ze stosu, komunikować o tym, że stos jest pusty. Opracowanie zadania (tekst programu) Testowanie Wypróbować zdejmowanie elementu ze stosu i otrzymać komunikat, że stos jest pusty. Wprowadzić i położyć na stos elementy danych sprawdzając poprawność odkładania. Zdejmować ze stosu elementy danych sprawdzając poprawność wyprowadzenia. Wyprowadzać elementy danych do otrzymania komunikatu o tym, ze stos jest pusty. Do sprawozdania dołączyć ( z r z u t e k r a n u a p l i k a c j i ) . Warianty dla struktury bazowej "lista" Wariant 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Typ elementu liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba liczba Miejsce dodawania koniec początek koniec początek koniec początek koniec początek koniec początek koniec początek koniec początek koniec początek Rozmiar Wariant 10 10 20 20 30 30 40 40 15 15 25 25 35 35 5 5 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 Typ elementu litera litera litera litera litera litera litera litera litera litera litera litera litera litera litera litera Miejsce dodawania koniec początek koniec początek koniec początek koniec początek koniec początek koniec początek koniec początek koniec początek Rozmiar 10 10 20 20 30 30 40 40 15 15 25 25 35 35 5 5 Wskazówki Opracowanie graficznej części aplikacji Dodać do formularza obiekty graficzne: - do wyświetlenia zawartości stosu i elementu na wierzchu stosu, - do wprowadzenia nowego elementu przycisk "Dodaj" i okienko NumericUpDown dla elementu typu "Liczba" albo TextBox dla elementu typu "Litera", - obiekt typu StatusBar do komunikowania o tym, że stos jest pusty (jeżeli w Toolbox nie ma komponentu StatusBar, to należy dodać ten komponent przez punkt menu Tools/Choose Toolbox Items), - do zdejmowania elementu ze stosu przycisk "Zdejmij" i okienko NumericUpDown dla elementu typu "Liczba" alboTextBox dla elementu typu "Litera". Do wyświetlenia zawartości stosu oraz elementu na wierzchu stosu jest wygodnie korzystać z obiektu typu ListBox. Wierzchowi stosu może odpowiadać zaznaczony pierwszy wiersz ListBox’a. Aby zaznaczać pojedynczy wiersz w obiekcie typu ListBox należy ustawić właściwość SelectionMode na "One". Właściwość SelectedIndex ListBox'a służy do wyboru wierszu do zaznaczenia. Przykładowo: listBox1->SelectedIndex=-1; //brak zaznaczonego wierszu listBox1->SelectedIndex=0; //zaznaczony jest wiersz 1 z indeksem 0 (indeksy od 0) Strukturę elementu stosu oraz wskaźnik na pierwszy element należy deklarować jako globalne na początku pliku z klasą formularza, na przykład: struct s_elem { int value; //wchar_t litera; s_elem* nast; s_elem(int newvalue,s_elem *pnast) { this->value=newvalue; this->nast=pnast; } }; s_elem* pstos=0; W przypadku danej - litery należy zdefiniować pole danych typu wchar_t. Obiekt typu TextBox ma właściwość Text typu String^. Aby odczytać liczbę należy zastosować instrukcję: int dana=System::Int32::Parse(textBox1->Text); Aby zapisać liczbę należy zastosować instrukcję: textBox1->Text=dana.ToString(); Aby odczytać literę należy zastosować instrukcję: wchar_t dana=textBox1->Text[0]; Aby zapisać literę należy zastosować instrukcję: textBox1->Text=dana.ToString(); Obiekt listBox2 typu ListBox przeznaczmy do wyświetlenia zawartości stosu, którego elementy będą rozproszone w elementach listy. Bazowe operacje na stosie powinny być realizowane ze sprawdzaniem, czy jest stos pusty. Do wyświetlenia tekstów komunikatów można dodać do formularza obiekt typu „StatusBar”. Wyświetlenie komunikatu w obiekcie typu StatusBar: StatusBar1->Text = "tekst komunikatu"; Inny sposób wyświetlenia tekstów komunikatów - wykorzystanie statycznej metody Show() klasy MessageBox: System::Windows::Forms::MessageBox::Show( "tekst komunikatu", "Komunikat", MessageBoxButtons::OK, MessageBoxIcon::Exclamation ); Warunek "czy jest stos pusty" sprawdzamy następująco: if (pstos==0) { ////// komunikat "Stos jest pusty" } else { ////// instrukcje zdejmowania elementu ze stosu } Po wykonaniu operacji nad stosem należy przenieść zawartość tablicy do ListBox'a: listBox2->Items->Clear(); if (pstos!=0) { s_elem *pt=pstos; while (pt!=NULL) { listBox2->Items->Add(pt->value); pt=pt->nast; } } Oprogramowanie operacji bazowych Wariant "Miejsce dodawania - początek listy" Odkładanie elementu na stos jest równoważnie dodawaniu elementu na początku listy: pstos=new s_elem(liczba,pstos); Zdejmowanie elementu ze stosu jest równoważnie odejmowaniu elementu z początku listy: if (pstos==0) { System::Windows::Forms::MessageBox::Show( "Stos jest pusty", "Komunikat",MessageBoxButtons::OK, MessageBoxIcon::Exclamation ); } else { int liczba=pstos->value; pstos=pstos->nast; } Wariant "Miejsce dodawania - koniec listy" Odkładanie elementu na stos jest równoważnie dodawaniu elementu na końcu listy: Algorytm operacji dodawania elementu na końcu listy niecyklicznej jednokierunkowej jest następujący: Krok 1. Alokować element listy. Krok 2. Kopiować do nowego elementu dodawane dane, a pole wskaźnika na następny element ustawić na zero. Krok 3. Znaleźć ostatni element listy metodą szukania od początku elementu z zerowym wskaźnikiem na następny element. Krok 4. W znalezionym elemencie pole wskaźnika na następny element ustawić równym wartości wskaźnika na nowy element. Ten algorytm jest realizowany w niżej przytoczonym fragmencie. s_elem *pnew=new s_elem(nowaDana, 0);/*krok 1 (alokacja), krok 2 (kopiowanie danych oraz ustawienie wskaźnika-znacznika końca listy) */ if (pstos==0) pstos=pnew; else { s_elem *pt=pstos; while (pt->nast!=NULL) pt=pt->nast; //krok 3 (szukanie końca listy) pt->nast=pnew; //krok 4 (łączenie z listą) } Zdejmowanie elementu ze stosu jest równoważnie odejmowaniu elementu na końcu listy: if (pstos==0) { System::Windows::Forms::MessageBox::Show( "Stos jest pusty", "Komunikat",MessageBoxButtons::OK, MessageBoxIcon::Exclamation ); } else { s_elem *pt=pstos; s_elem *pprev=0;//wskazuje na element, który wskazuje na aktualny element while (pt->nast!=0) { pprev=pt; pt=pt->nast; //szukanie końca listy } if (pprev==0) pstos=0; else pprev->nast=0; if (pt!=0) delete pt; }