Problem z sortowaniem - brak pomyslu na uzycie selection sort

Mam problem z moja baza, na projekt z informatyki. Wszystko działa bez zarzutu mimo dziwnie pisanego kodu - jestem laikiem w programowaniu. I teraz pozostało mi dodac sortowanie przez wybór według nazwy, ceny i ilosci. Własnie w tym potrzebna mi pomoc gdyz juz od kilkunastu godzin nie mam na to pomysłu.
Zamieszczam cały kod i z gory dziekuję za pomoc

      https://pastebin.com/Fqh7A4Hy wrzucam tutaj dla wygody

Kod wklej na np. wklej.org lub pastebina bo w tej formie ciężko to przejrzeć. Ewentualnie wstaw kod tutaj, ale zgodnie ze składną markdown której używa edytor forum: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code

Na tą chwilę to mogę powiedzieć byś nie załączał bibliotek w takiej formie
#include <string.h>
lecz w takiej
#include <string>
Dlaczego? Opisane jest to ładnie w Why doesn’t iostream have a .h extension?: https://www.learncpp.com/cpp-tutorial/19-header-files/

Możesz użyć gotowych funkcji z bibliotek czy musisz sam napisać sortowanie?

Masz to napisać w C czy w C++? Jak w C to rada odnośnie dołączania bibliotek z pierwszego postu jest nie ważna.

struct wpis{
  char *nazwa;
  char *cena;
  char *ilosc;
  struct wpis *next;
}baza;

Właściwości struktury powinny mieć odpowiednie typy, dla ilosc i ceny c-string nie jest dobrym wyborem. Jak to zmienisz nie musisz to w tedy nie będziesz miał wskaźników i nie będziesz musiał dynamicznie rezerwować dla nich pamięci.
Używaj też bardziej opisowych nazw zmiennych bo t, r ,g ciężko się czyta.

W obecnej postaci wpis jest jednocześnie listą pojedynczo wiązaną (jednokierunkowa), dlatego ciężko trochę będzie zrobić tego sortowanie. Łatwiej będzie Ci się do tego zabrać jak to rozbijesz na dwie struktury:

struct wpis{
  char *nazwa;
  char *cena;
  char *ilosc;
};

struct lista{
  wpis *data;
  lista *next;
};

Co do sortowania to największym problemem jest zrozumienie, a potem napisanie algorytmu sortowania. Jest ich kilka, najprostszy to bubble sort (https://pl.wikipedia.org/wiki/Sortowanie_bąbelkowe). Napisz czy masz narzucony algorytm sortowania, no i czy je rozumiesz. Napisz też jaki to poziom nauki to też lepiej uda się dobrać rozwiązanie - bez ewentualnego zwiększania trudności.

Jak zrozumiesz jak działa algorytm sortowania i rozbijesz sobie program na dwie struktury to niezależnie po jakiej wartości będziesz chciał sortować będzie się to robiło w ten sam sposób.

narzucone mam sortowanie przez wybieranie, z programowania jestem bardzo slaby ale jako sobie radze. Na razie sprobuje wykorzystac wasze rady i cos ruszyc. no i musi byc to napisane w c.

Chodzi o wybieranie względem, której właściwości (nazwa, cena, ilość) struktury ma zostać posortowana lista? Jeśli tak to jeszcze powinieneś mieć informacje jakim algorytmem powinieneś to sortować, ewentualnie czy możesz użyć jakiejś funkcji sortującej z standardowej biblioteki (np. qsort() - https://stackoverflow.com/questions/1787996/c-library-function-to-do-sort). Jeśli to jest do szkoły to raczej nie pozwala się na używanie gotowych funkcji po to by zrozumieć poszczególne algorytmy.

To jest algorytm :wink: Zobacz https://pl.wikipedia.org/wiki/Sortowanie_przez_wybieranie

:smiley: selection sort to znam, ale sortowanie przez wybieranie pierwszy raz słyszę (poważnie). Dlatego nie ogarnąłem.

W takim razie pytanie do autora czy rozumie algorytm selection sort, jak tak to mogę w punktach rozpisać jak to należałoby zrobić w przypadku jego zadania, ale zaimplementować będzie musiał sam. W końcu ma się czegoś przy tym zadaniu nauczyć, aczkolwiek kod który już napisałem jest całkiem w porządku.

Chociaż z drugiej strony patrząc na wikipedię już powinien dać sobie radę z dostosowaniem algorytmu do swoich potrzeb.

Tak, chodziło o selection sort. Ogolnie potrafie zastosowac to na zwyklych liczbach ale nie potrafie wymyslic jak wrzucic to do mojego kodu. Cale sortowanie ma sie odbywac 1.Wg nazwy, powinna byc tez mozliwosc posortowania po cenie lub ilosci.

W każdym przypadku algorytm będzie wyglądał w 98% tak samo, zmieni się tylko sposób porównywania 2 wartości, no i zmienią się wartości które porównujesz. Chyba umiesz porównać dwa inty, dwa double lub dwa c-stringi ze sobą.

Trudniejsze jest teraz tylko stworzenie dwóch pętli które będą dokonywały selekcji i wpisania elementu w dane miejsce. Zapewne umiesz to zrobić na tablicy o stałym rozmiarze, ale problem masz z listą.
Jeśli przerobisz program według wcześniejszej wskazówki to masz bardzo ułatwioną sprawę.
W takim przypadku gdy zamieniasz ze sobą dwa elementy to tak naprawdę zamieniasz wskaźniki w poszczególnych “kontenerach”/elementach/nodach listy. Tworzysz sobie pomocniczy wskaźnik na wpis i zamieniasz mniej więcej tak:

wpis * tmp = mniejszy->data;

mniejszy->data = wiekszy->data;
wiekszy->data = tmp;

Teraz czym jest mniejszy i większy. Może nie do końca dobrze dobrałem nazwy, ale najlepiej nadawały się do poprzedniego przykładu. Więc czym one są dokładnie wynika z działania algorytmu, mniejszy to tak naprawdę ta wartość z początku tablicy(listy) którą porównujesz z pozostałymi elementami tablicy(listy). Wartość kolejnych elementów jest tymczasowo w wyższym.

Problem z pętlami. W przypadku tablicy wystarczyło użyć pętli for. W przypadku listy będzie to nieco trudniejsze. Można nadal użyć pętli for, ale równie dobrze nada się tutaj pętla do-while. A właściwie to dwie :wink:.
Jak wyobrazisz sobie pętlę for z algorytmu sortującego tablice, to by dostosować ją do prac zmieniasz inicjalizację i oraz j. Zmienna i to będzie ta sama wartość która masz w poczatek, natomiast j to będzie początek->next. Warunek zakończenia pętli wewnętrznej (tej z j) to będzie po prostu elem_wew->next == null czyli pusty wskaźnik = koniec listy. Natomiast tej zewnętrznej (tej z i) jeśli brzydko by to zapisać to może być: elem_zew->next->next == null. Czyli sprawdzasz czy jesteś w przedostatnim elemencie, czyli czy kolejny element względem tego, nad którym obecnie pracujesz nie ma następnego elementu.

Wszystko to brzmi skomplikowanie - wiem, ale musisz się w to wgryźć i wczuć. Jakbyś miał pytania to pisz. Podrzuć tez kod co zrobisz, żeby łatwiej było podpowiedzieć Ci względem tego co robisz, a nie wywracać Twoją koncepcję do góry nogami.
Wiem już to zrobiłem, ale uważam, że w ten sposób bardzo ułatwisz sobie życie. Mam nadzieję, że już zmodyfikowałeś kod zgodnie z wcześniejszymi radami o wskaźnikach i dwóch strukturach.

Hmm gdy probuje rozbic to na dwie struktury to albo mam redeklaracje albo wyskakuje ze jest brak deklaracji np.wpis. Wszystko mi sie juz tak pomieszalo ze pewnie zostawie to tak jak jest i bede liczyl na 3… Na uczelni nikt tego nie wytlumaczyl i niestety podstawa podstaw tylko wychodzi ;x Ale dziekuje za obszerny opis i pomoc, moze w koncu cos wykombinuje jednak

Pokaż co masz i jakie lecą błędy :slight_smile:

Wywala ze "|21|error: expected specifier-qualifier-list before ‘wpis’| " i to tyczy sie wpisy ze struct lista…
struct wpis{
char *nazwa;
double *cena;
int *ilosc;
struct wpis *next;
}wpis;
struct baza{
char *nazwa;
double *cena;
int *ilosc;
}baza;

struct lista{
wpis *data;
lista *next;
};

Ogolnie pozmieniałem tez chary na dobule i int przy cenie i ilosc i dane wpisane do pamieci wyswietla dobrze ale po zapisaniu do pliku i ponownym otwaricu wszystko wariuje

EDIT to jednak udalo sie ogarnac, nwm skad ale w niektorych miejsach wpisalo mi %% zamiast % …

A gdyby zrobic tak ze zamiast z pliku txt, dane byłyby wpisane w kodzie? potem najwyzej zapisywac to do pliku. Mam kod od kolegi ale wlasnie dziala na zasadzie ze dane sa w kodzie i nigdzie ich nei zapisuje, a jest jedynie mozliwosc dopisania do pamieci nowego produktu

Sam zobacz czy ten kod jest poprawny? Masz najpierw strukturę o nazwie wpis, a potem tworzysz pierwszą zmienną tej struktury o tej samej nazwie. Kompilator potem nie wie czym jest wpis.

Co do problemów z plikiem. To jest to oczywiste, że je masz. Przecież w pliku trzymasz tekst, więc musisz go potem przy odczycie zamienić na odpowiednie typy.

Poza tym nie wiem czemu zostawiłeś wpis i dodałeś bazę, a potem wykorzystujesz i tak stary wpis. To nie ma sensu, zupełnie nie myślisz nad tym co robisz, mam wrażenie, że zmieniasz kod na pałę z nadzieję, że może się uda i zadziała.

czyli tak nprawde to struktury czego musze stworzyc oprosz “wpis” zakonczony “baza”

Potrzebujesz strukturę która będzie elementem listy. Oraz strukturę która trzyma dane. Element listy składa się ze wskaźnika do danych które przetrzymuje oraz z adresu następnego elementu listy.
Poczytaj o strukturze danych typu lista, bo to jest kluczowe do zrozumienia problemu.