Łańcuchy w C

0

Łańcuchy w C są pomyślane jako tablice znakowe
Nie wiem czy to dobry pomysł bo trzeba znać z góry liczbę znaków w łańcuchu
Funkcje takie jak scanf nie działają dobrze na łańcuchach
a fgets wymaga podania liczby znaków w łańcuchu
Według mnie wygodniej byłoby traktować łańcuch jako listę znaków
Ciekawe jak funkcje do obsługi takiego łańcucha by wyglądały
Z drugiej strony reprezentacja listowa wymagałaby dołączenia do każdego znaku
wskaźnika co wiąże się z poświęceniem pamięci

Jaka waszym zdaniem byłaby najlepsza reprezentacja łańcucha
i jak ją zrealizować

4

próbowałeś przejść na C++? std::string powinien załatwić Twoje problemy.
Jeśli przez łańcuch masz na myśli listę jedno lub dwukierunkową to stringi stały by się dużo wolniejsze - lepiej zaalować więcej pamięci na Twój tekst i zaalokować znowu jak zaczyna Ci brakować (tak robi std::vector i prawdopodobnie też std::string)

0

Myślałem o tym że traktowanie łańcuchów jako list spowodowałoby że pewne operacje na łańcuchach stałyby się wolniejsze
@krwq a mógłbyś podać przykład jakiegoś działającego kodu z kilkukrotną alokacją pamięci, ciekaw jestem jak takie podejście by zadziałało
Czy to nie wiązałoby się z kilkukrotnym kopiowaniem łańcucha a skoro tak to nie wiem czy byłoby to szybsze niż na liście

0

Z tą listą to słaby pomysł ze względu na właśnie konieczność przechowywania wskaźnika do każdego znaku oraz ze względu na to, że np. nie dostaniesz się do dowolnego znaku w takim string w takim samym czasie tak jak to jest z tablicą char.

0

W takim razie opracuj szybszy i wygodniejszy sposób obsługi łańcuchów znaków i przedstaw Komisji Standaryzacyjnej.
Co do alokowania pamięci i kopiowania starego w nowe, to napisz alokator, który będzie rozsądnie dobieral rozmiar, aby alokacje nie były zbyt częste. Na pewno będzie szybciej niż lista.

6

Nie wiem skąd pomysł, że trzeba znać z góry liczbę znaków. Przecież tablicę możesz realokować. Standardowo też alokuje się po prostu zawsze więcej, żeby łańcuch można było rozszerzać zanim potrzebna będzie realokacja. Lista ma przewagę jeżeli chodzi o dodawanie rzeczy w różne miejsca, ale chyba najczęstsze operacje na łańcuchach są jednak oparte o taką czy inną iterację (wypisywanie, wyszukiwanie), a w tym lista jest słaba.

Do ogromnych ciągów znaków lepiej natomiast nadaje się struktura rope: https://en.wikipedia.org/wiki/Rope_(data_structure).

0

Realokować tablicę ?
Jakiś przykład jak to miałoby działać ?

@Endrju jak wyglądałoby wczytywanie linii z pliku do łańcucha
Wczytywanie łańcucha (rozumianego jako tablica znakowa) ze standardowego wejścia i tak będziemy musieli wczytywać kawałkami
i jeśli nie będziemy kontrolować liczby wprowadzonych znaków to się nam nie wczyta cały kawałek a to może być uciążliwe

0

http://www.cplusplus.com/reference/cstdlib/malloc/

Realokować tablicę ?
Jakiś przykład jak to miałoby działać ?

http://www.cplusplus.com/reference/cstdlib/realloc/

0

Jak tak patrze na obrazki to ta struktura jest podobna do drzewa

0

@nowy121105 - jeśli nie planujesz parsowania jakiś olbrzymich stringów to walczysz o zaoszczędzenie mikrosekund - takie optymalizacje wykonuje się tylko jeśli są naprawdę konieczne. Jeśli uda Ci się wymyślić coś o mikrosekundę szybszego niż string to prawdopodobnie posypie się jak będziesz potrzebował nowej funkcj i na końcu i tak string okaże się szybszy. Załóż że są ludzie mądrzejsi od Ciebie w niektórych kwestiach i spędzili nad tym więcej czasu niż Ty i po prostu używaj ich rozwiązań póki nie masz z nimi problemów. Jak zaczniesz się tak rozdrabniać to zaraz zaczniesz pisać swój kompilator C++ od zera.

jeśli chodzi o kilkukrotne alokowanie to odpowiedź to: tak - będziesz kilkakrotnie alokował. Z tym, że algorytmy w bibliotece standardowej zrobią to mniej razy niż myślisz i dodatkowo możesz je wspomóc funkcją reserve jeśli z grubsza znasz rozmiar. Doczytaj i nie wymyślaj koła na nowo.

0

Nie możesz użyć listy stringów? wtedy możesz łączyć dowolną liczbę łańcuchów w jeden duży, w dodatku to już istnieje,
I wystarczy tylko klase iteratora listy stringów napisać i możesz korzystać ze wszystkich dostępnych algorytmów iteracyjnych.

W dodatku jest to <ort>bardziej optymalne</ort> niż każdą literę trzymać jako następny element listy.

0

Może najpierw powiedz, co konkretnie ma robić ten program, wtedy dopiero można się zastanawiać jakie rozwiązanie ma największy sens

0

Na razie chciałbym wczytać plik do pamięci i wykonać na nim kilka operacji
takich jak na przykład sortowanie linii

Przypuśćmy że mamy dwa pliki i chcemy wypisać linie które znajdują się w pierwszym pliku ale nie znajdują się w drugim
przy założeniu że każdy z plików czytamy tylko raz

0

W C? Sortowanie linii? To pewnie chcesz listę/tablicę dynamicznie alokowanych c-stringów, bo przy sortowaniu pozamieniasz sobie kilka wskaźników i nie będzie trzeba kopiować samych danych. (Możesz też użyć BST, jeśli chcesz się pobawić/pouczyć) Jeżeli te pliki są większe niż pamięć RAM to musisz zrobić oczywiście coś sprytniejszego. ;)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.