Pomoc przy napisaniu programu

0

Witam,
czy znalazłby się ktoś kto pomógłby mi z napisaniem tego programu, albo chociaż polecił jakiś kurs w którym są wyjaśniane dość dokładnie wskaźniki i stosy w języku Pascal.
Treśc:
Stos na wskaźnikach (wierzchołek ST typu PStos, PStos=^TStos;)
Dane:Liczba rzeczywista Operacje: a)Wkładanie na stos,zdejmowanie ze stosu; b)dodawanie,odejmowanie, mnożenie i dzielenie liczb z wierzchołka stosu: np function dodaj(a,b: Double): double. W programie głównym wykonać ciąg operacji z godnie z zasadą odwrotenj notacji polskiej."
Z góry dziękuje za odpowiedzi.

1

Odnośnie wskaźników oraz stosow - jest tego naprawdę dużo na 4programmers, więc obawiam się, że zamiast szukać, po prostu założyłeś nowy wątek, bo tak pewnie jest łatwiej :p

Ale żeby nie było, że nie pomagam, to poza poleceniem przejrzenia 4p (albo skorzystania z wyszukiwarki), dam jeszcze jakiś link - http://www.algorytm.org/klasyczne/stos.html oraz PowerPoint na ten temat - https://www.google.com/url?q=http://math.uni.lodz.pl/~kowalcr/AlgorytmyIStruktury/Wyklad10.pdf. W pierwszym linku masz mniej teorii, ale jest jakaś implementacja w Pascalu, natomiast drugi ma dużo teorii, ale za to przykłady są w C+.

Jak to przejrzysz oraz poczytasz we własnym zakresie, to dopytaj o konkretne problemy, postaramy się jakoś pomóc ;)

0

Problem w tym, że spędziłem dość dużo czasu nad tym zagadnieniem(materiały które podlinkowałeś widziałem)i teoretycznie wiem co to stos, na jakiej zasadzie działają wskaźniki, problem w tym że nie umiem tego przenieść na kod jeśli chodzi o pascala(myślę, że w innym języku poszło by mi łatwiej) do którego nie ma zbyt wiele materiałów które były by pomocne, a przynajmniej ja nie znalazłem kursów które by tłumaczyły dość dobrze sposób zapisu wskaźnika czy też stosu. Mam nadzieję, że zrozumiałeś o co mi chodzi.

1

No to może inaczej - jeśli dla Ciebie problemem (tak przynajmniej rozumiem to, co napisałeś) jest raczej sam język, to napisz proszę swoimi slowami/opisowo, jak byś chciał zrealizować ten program, jakie kroki wykonać, jaki masz pomysł na trzymanie danych itp. Będziemy po kolei się starali zamieniać/tłumaczyć te rzeczy na Pascala :)

A tak w ogóle to w czym piszesz? Jakiego środowiska używasz? Czy masz coś narzucone przez szkołę, czy sam mogłes wybrać?

0

Program musi być napisany w Lazarusie. Najpierw muszę zdefiniować stos(na początku myślałem czy nie wykorzystać tablicy dynamicznej ) korzystając z algorytmu podlinkowanego wyżej będzie to wyglądało chyba tak:

type PStos = ^TStos;  /PStos to wskaźnik wskazujacy na typ record(jeśli dobrze rozumiem) 
TStos = record /To nasza struktura danych typu record  zawierająca zmienna liczba typu integer i wskaznik wskazujacy nastepny element w stosie
        liczba: integer;
        wskaznik: PStos;
  end;

Mam nadzieje że dobrze to zrozumiałem i rozpisałem.
Teraz potrzeba funkcji które będą dodawać lub zdejmować liczby na stosie.

1

Na razie jest OK :) Masz zaprojektowaną strukturę oraz typ wskaźnikowy do niej.

Jedna uwaga - komentarze mają dwa ukośniki - czyli //, jeden to trochę za mało ;)

Co do Lazarusa - słuszny wybór. Bałem się, że walczysz z jakimś zabytkiem w stylu DOS'owego Turbo Pascala. Czy piszesz to w ramach aplikacji konsolowej, czy okienkowej?

Odnośnie "dodawania i zdejmowania liczb" - sprawdź, jak w podanym linku jest to rozwiązane. Walczą tam wprawdzie ze stosem przechowujący nazwiska, a Ty chcesz liczby - ale zasada jest taka sama. Ewentualnie napisz, czego konkretnie nie rozumiesz.

Poza tym możesz skorzystać z Pastebin (link na górze 4P) i wkleić cały kod, który już napisałeś (a nie jedynie deklarację samego typu) - w ten sposób będziemy mogli sobie zrobić Ctrl+C i Ctrl+V u siebie i mieć ten sam kod, co Ty. Ułatwia to pracę.

1

Aplikacja konsolowa, tak jak napisałeś wzorowałem się na podanym linku.Tutaj link do pastebin'a https://4programmers.net/Pastebin/10374 opisałem to jak to rozumie mniej więcej. Kompilator kompiluje, jednak teraz trzeba napisać wyświetlenie stosu i sprawdzenie czy to działa. Wyświetlenie trzeba zrobić w procedurze a w instrukcji głównej zrobi się switcha z elementami dodaj/usuń/wyświetl.

1

Teraz nie mogę za wiele Ci napisać, ale postaram się pod wieczór.
Do tego czasu mam propozycję - zajmij się obsługą interakcji z użytkownikiem, czyli wyborem akcji do wykonania, wczytywaniem liczb itp. Na razie to będzie tylko taki szkielet, więc np. po wybraniu przez użytkownika opcji "wprowadź liczbę" wywołaj jedynie funkcję "wczytaj_liczbe", która będzie pusta. Analogicznie z wyborem operacji do wykonania oraz innych rzeczy, które aplikacja ma robić. Ten sposób ma też taki plus dla Ciebie, że sam sobie poukładasz pewne rzeczy w głowie oraz zastanowisz się nad tym, co dokładnie ma program robić, jakie operacje wykonywać itp. Jak będziesz miał szkielet, to zajmiemy się wypełnianiem treści procedur.

Jedyna rzecz, którą możesz już zrobić "porządnie" i ostatecznie, to obsługa zakończenia działania aplikacji. Jeśli wiesz, jak zrobić sterowanie aplikacją oraz jak ją zakończyć, gdy użytkownik będzie chciał, to nie czytaj dalej i zrób "po swojemu" - jeśli się uda, to będziesz miał większą radość :D

Postaraj się zrobić to wszystko o czym napisałem i do zobaczenia wieczorem.

*.
*.
*.
*.
*.
*.
*.
*.
*.
*.
*.
*.

Jednak czytasz dalej :D

W takim razie ja bym pętlę obsługującą interakcje z użytkownikiem zrobił mniej-więcej w następujący sposób (podaję sposób realizacji, a nie gotowy kod):

  1. najpierw deklarujesz zmienną globalną typu boolean. Ja ją nazwałem koniec. Dajesz jej jakąś wartość początkową - np. False.
  2. w głównym bloku aplikacji (odpowiednik void main z C, w Twoim Pastebin trzy ostatnie linie - między begin a end z kropką) dajesz pętlę typu while, której warunkiem zakończenia jest zmieniona wartość zmiennej koniec
  3. podczas wczytywania poleceń od użytkownika sprawdzasz, czy nie chce on zakończyć aplikacji (przykładowo - "1-dodaj liczbę, 2-zsumuj liczby, 3-zakończ aplikację". W chwili wciśnięcia przez użytkownika liczby 3 zmieniasz wartość zmiennej koniec na stan odwrotny
  4. pętla while z pkt.2 w chwili zmiany wartości zmiennej koniec kończy swoje działanie, a co za tym idzie (zakładając, że nie ma po niej żadnych innych poleceń) cała aplikacja się kończy.
0

Dodawanie i wyświetlanie działa wyśmienicie(zastanawiam się czy nie dodać jakiś indeksów przy wyświetlanych liczbach), problem mam z usuwaniem ze stosu nie rozumiem jakie parametry mam dostarczyć do tej procedury. https://4programmers.net/Pastebin/10375

1

Niestety, nie działa wyśmienicie, a jedynie jako-tako (swoją droga, mogłeś wrzucić ten kod za pierwszym razem, nie musiałbym się produkować w poprzednim poście :P ).

Po pierwsze - wpisz sobie "d" a potem "34rs" albo cokolwiek innego, co nie jest liczbą. Program się wychrzania. Przydałoby się zrobić jakieś sprawdzanie wprowadzonych wartości.
Po drugie - lista opcji wyświetla się tylko raz, podczas pracy może ona przewinąć się za ekran.
Po trzecie - po dodaniu wartości nie dostaję żadnej informacji, po prostu wciskam Enter i widzę nic. Jakaś informacja dla użytkownika by się przydała.
Po czwarte - ja bym za każdym razem po wykonaniu czynności przez użytkownika czyścił ekran, wyświetlał potwierdzenie zrobienia danej czynności i ponawiał wypisanie listy dostępnych opcji
Po piąte - nie wiem, ile liczb planujesz przechowywać, ale jeśli 10 lub więcej, to może lepiej je wymienić w poziomie a nie pionowo, bo ich wyświetlenie może zajmować zbyt wiele miejsca.
Po szóste - TAK, ponumerowanie wpisanych liczb ułatwi przeglądanie
Po siódme - do kroku opisanego pod nr czwartym, dodał jeszcze informację w stylu "obecnie jest wprowadzonych X liczb"
Po ósme - wybierając jakąś literę/polecenie nieistniejące w menu nic się nie dzieje. Dobrze by było dodać informację w stylu "wybrano nieprawidłowe polecenie".

0

Patrząc na twoje rady poprawiłem trochę kod i wygląda on następująco https://4programmers.net/Pastebin/10380 , pierwszego kroku nie zrobiłem ponieważ nie mam pomysłu(myślałem nad sprawdzaniem kodu ascii wprowadzanej zmiennej ale to ograniczało by się tylko do licz od 0 do 9, szkoda że nie ma czegoś takiego jak typeof w js ), co do wypisywania zostawię w pionie lepiej to obrazuje działanie stosu. Teraz myślę nad podpunktem b)> b)dodawanie,odejmowanie, mnożenie i dzielenie liczb z wierzchołka stosu: np function dodaj(a,b: Double): double. W programie głównym wykonać ciąg operacji z godnie z zasadą odwrotenj notacji polskie np obliczanie wyrażeń c:=a+(bc);d:=(a+b)/(c-d);d=a(b-c). Zakładam że trzeba pobrać dwa najwyższe elementy ze stosu(można też sprawdzić czy na stosie jest więcej niż 1 element ) i je dodać.Co do notacji nie mam pojęcia jak to zrealizować. Co do poprzedniej sytuacji porostu zły timing z tym wklejeniem kodu :)
P.S da się jakoś aktualizować poprzedniego PasteBina ?

1

Odnośnie sprawdzania, czy wprowadzona wartość jest liczbą - najprościej będzie wczytać ją nie jako integer, tylko jako string, a następnie spróbować przekonwertować na integer.

Możesz to zrobić w sposób "tradycyjny" - korzystając z Val, albo chociażby przez STRTOINT. Do poczytania w temacie konwersji - Konwersja liczb na string i vice versa LUB StrToInt LUB Konwersja typów.

W zakresie notacji - czy wiesz, jak ona działa, ale nie masz wizji, jak to zaprogramować, czy za bardzo nie kojarzysz w ogóle tego hasła?

Co do innych kwestii to teraz nic nie napisze, bo jednak nie mam dostępu do kompa, siedzę na telefonie, więc kiepsko mi się przegląda kod. Do tematu wrócimy trochę później ;)

0

Dzięki za linki. Oto wersja ze sprawdzaniem czy wprowadzona zmienna jest liczbą :) https://4programmers.net/Pastebin/10385 zrobiłem mały edit bo wprowadzane liczby mają być rzeczywiste a nie całkowite. W związku z tym mam pytanie, czy da się wyświetlać te liczby bez tych wszystkich zer i notacji naukowej? Co do ONP poczytałem jak to wygląda i teraz zastanawiam się jak to ma być zrobione bo w zadaniu jest napisane "w programie głównym wykonać ciąg operacji", czyli rozumiem że mogę w funkcji głównej stworzyć oddzielny stos z wykorzystaniem tablicy i jakoś to zrobić?

0

Dodatkowo próbuję zrobić dodawanie liczb na stosie, jednak mam mały problem mianowicie po dodaniu dwóch szczytowych wartości znikają one ze stosu https://4programmers.net/Pastebin/10386. Czy mógłby ktoś wyjaśnić dlaczego tak się dzieje i co robię źle?

1

W zakresie zmiany sposobu wyświetlania liczb - najpierw zmień linię 51 na WriteLn('[',i,']',Pocz^.Liczba:40:20); . Wartości 40 oraz 20 są oczywiście do ustalenia wedle własnych preferencji. Więcej na temat formatowania masz pod adresem Write - a w szczególności fragment b). Liczby rzeczywiste: WriteLn(wyrazenie:liczba-cyfr:po-przecinku);.

Niestety, nadal nie mamy idealnie tego, co chcemy - więc kombinujemy dalej i zmieniamy linię 51 na postać WriteLn('[',i,']',format(floattostr(Pocz^.Liczba), [])); . Tym razem posiłkujemy się funkcją format - http://wiki.freepascal.org/Format_function lub https://lazarus-ccr.sourceforge.io/docs/rtl/sysutils/format.html.

Po czynnościach, które zakończyłeś readln dodałbym jakąś informację, ze czeka na wciśnięcie Entera (czyli np. nie "dodano" jak jest obecnie, ale "dodano. Wciśnij enter żeby konturować").

Zamiast pisać c:=c+1; daj lepiej inc(c); - wygląda bardziej fachowo/hackersko :D

W zakresie wykonywania operacji na liczbach - nie do końca rozumiem, co chcemy osiągnąć. Czy masz jakieś konkretne operacje, które masz wykonać, czy sobie sam jakieś wymyślisz i masz je zaprogramować? W pierwszym poście napisałeś b)dodawanie,odejmowanie, mnożenie i dzielenie liczb z wierzchołka stosu: np function dodaj(a,b: Double): double., parę postów niżej bliczanie wyrażeń c:=a+(bc);d:=(a+b)/(c-d);d=a(b-c). Czy to są Twoje propozycje działań, czy masz je gdzieś określone? Rozumiem, że zmienne a, b, c itp. są po prostu kolejnymi liczbami pobieranymi ze stosu - zgadza się?

Nie wiem, czy można jakoś aktualizować PasteBin'a, ale zawsze można zrobić nowego ;) Tylko zwróć uwagę na to, że tworząc wpis musisz określić jego czas życia. Żeby nam za chwilę coś nie poznikało ;)

W temacie znikania liczb ze stosu podczas działania na nich - zanim przejdziemy dalej, ustalmy jak się program ma zachowywać. Przykładowo - mamy na stosie liczby 4 i 5. Wydajemy polecenie, żeby je dodać. Program je pobiera ze stosu....i co dalej? Czy one zostają tam, gdzie były, ale jako kolejna zostaje dodana dziewiątka? A może te dwie liczby powinny zniknąć, a na ich miejsce powinna wskoczyć właśnie 9-tka?

0

Treść zadania
"Stos na wskaźnikach (wierzchołek ST typu PStos, PStos=^TStos;)
Dane:Liczba rzeczywista Operacje: a)Wkładanie na stos,zdejmowanie ze stosu; b)dodawanie,odejmowanie, mnożenie i dzielenie liczb z wierzchołka stosu: np function dodaj(a,b: Double): double. W programie głównym wykonać ciąg operacji z godnie z zasadą odwrotenj notacji polskiej. Np obliczanie wyrażeń c:=a+(bc);d:=(a+b)/(c-d);d=a(b-c)."
Sam nie za bardzo rozumiem jak to ma wyglądać. Wydaje mi się że funkcje mają po prostu działać na elementach stosu i wyświetlać wynik a odwrotna notacja jest oddzielnie.
Dodatkowa zastanawiam się po co z powrotem konwertować liczbę na stringa przy wyświetlaniu.

1

A czy masz możliwość dopytania nauczyciela/osoby, która dała Ci to zadanie, jak dokładnie ma się ten program zachowywać? Bo szczerze mówiąc też nie do końca rozumiem, czym są te literki w przykładowych funkcjach. Poza tym jest to tak napisane, jakby te podane zadania były jedynie przykładowymi - więc pytanie, czy masz sam stworzyć jakąś listę możliwych funkcji, czy może użytkownik ma je określać bezpośrednio podczas pracy programu?

A co do konwersji liczby na string podczas wyświetlania- ma to na celu jej odpowiednie sformatowanie, o ile pamiętam chciałeś to wyświetlić w jakiś bardziej "przyjazny" sposób. W obecnej postaci zamiast 213.00000000 masz 213 - czyli chyba jest OK? :P

0

Więc z tego co zrozumiałem funkcje dodaj/usuń... mają pobierać dwie liczby i wynik wrzucać na stos. W instrukcji głównej trzeba obliczyć wyrażenie zgodnie z odwrotna notacją polską używając tych funkcji(czyli zapwene pobieramy trzy liczby od użytkownika, wrzucamy je na stos i wywołujemy odpowiednio funkcje dodaj/usuń... i na końcu wyświetlamy wynik.

1

Czyli jednak musimy mieć dwa stosy - jeden z liczbami, a drugi z kolejką poleceń do wykonania.

Pytanie - czy masz określony sposób, w jaki mają się zachować liczby po wykonaniu na nich operacji? Przykładowo: na stosie mamy 3 i 5. Wykonujemy na nich operację "dodać", w wyniku czego mamy wynik 8. Czy następnie liczby, na których operowaliśmy są kasowane ze stosu (wtedy zostanie nam jeden element - 8), czy może wynik ma zostać dopisany na górze stosu, ale pozostawiając liczby, z których on wynika (w takim wariancie stos po wykonaniu operacji miałby postać 3, 5, 8).

Moim zdaniem jest to dość istotne pytanie.

0

W podanym przez ciebie przypadku na stosie zostanie 8. Co do drugiego stosu, myślę że nie będzie on potrzebny ponieważ w instrukcji głównej mamy wywoływać kroki po kolei dla wybranego prze zemnie przykładu np dla dla wyrażenia d:=a+(b*c) użytkownik podaje a,b,c , w programie wywołuje się funkcje DODDANIA NA STOS(b,c,a) następnie funkcje mnożenia (b,c) wynik wrzucamy na stos, następnie wywołujemy funkcje dodaj i wyświetlamy wynik. działania które mają się wykonać są z góry wybrane

1

Ja to zrozumiałem trochę inaczej - najpierw użytkownik wpisuje sobie ileś-tam liczb, następnie wprowadza ciąg będący działaniem do wykonania w stylu a+b-(c-a)*4+e). A następnie program sam przetwarza listę poleceń do wykonania i na końcu zwraca wynik.

0

Też tak to rozumiałem :) A tu okazało się że sprawa jest prostsza niż myślałem. Zaraz dokończę program i wkleję.

1

W sumie to patrząc na ten cały wątek - mam wrażenie, że dałbyś sobie sam radę, bez jakiejkolwiek pomocy.
Szkoda, że mało jest takich ludzi na forum - większość to leniwe głupki z postawą roszczeniową, którzy oczekują, że dostaną gotowca, samemu się nie angażując i nie męcząc :(

1

Program ma wyglądać tak https://4programmers.net/Pastebin/10417. Z tego miejsca chciałbym z góry tobie podziękować za pomoc i poświęcony czas. Twoje rady były bardzo dla mnie bardzo pomocne. Jeszcze raz dziękuje za wszystkie wpisy. Pozdrawiam.

0 użytkowników online, w tym zalogowanych: 0, gości: 0