Jakie jest sens stosowania flagi w algorytmie wyszukiwania liniowego

Jakie jest sens stosowania flagi w algorytmie wyszukiwania liniowego
J1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 12
0

Mam taki oto program z funkcją algorytmu wyszukiwania liniowego elementu tablicy:

Kopiuj
#include <iostream>

using namespace std;

// Prototyp funkcji
int linearSearch(const int[], int, int);

int main()
{
    const int SIZE = 5;
    int tests[SIZE] = { 87, 75, 98, 100, 82 };
    int results;

    // Wyszukiwanie liczby 100 w tablicy
    results = linearSearch(tests, SIZE, 100);

    // Jeżeli funkcja linearSearch() zwróci wynik -1, oznacza to, że liczba 100 nie została znaleziona.
    if (results == -1)
        cout << "Nie uzyskales 100 punktow w zadnym tescie.\n";
    else
    {
        // Inny wynik funkcji jest indeksem pierwszego elementu tablicy
        // zawierającego liczbe 100
        cout << "Uzyskales 100 punktow w tescie nr ";
        cout << (results + 1) << "." << endl;
    }
    return 0;
}

// Funkcja linearSearch() przeszukująca liniowo tablicę liczb całkowitych.

int linearSearch(const int arr[], int size, int value)
{
    int index = 0;             // Indeks wykorzystywany do przeszukiwania tablicy
    int position = -1;        // Zmienna zawierająca pozycję wyszukiwanej liczby w tablicy
    bool found = false;   // Flaga informująca, czy liczba została znaleziona

    while (index < size && !found)
    {
        if (arr[index] == value)        // Jeżeli liczba została znaleziona to...
        {
            found = true;                  // ...ustaw flagę oraz...
            position = index;             // ...zapamiętaj indeks elementu.
        }
        index++;                             // Przejdź do następnego elementu.
    }
    return position;                      // Zwróć pozycję lub liczbę -1.
}

To jest przykład z książki i zastanawiam się, jaki jest sens tworzenia w funkcji linearSearch() zmiennej typu bool jako flagi, jeśli program działa identycznie bez niej. Czy ma to znaczenie w przypadku tworzenia bardziej rozbudowanych programów? Czy może autor zastosował flagę bo po prostu ma taki styl pisania kodu?
Czy ktoś ma jakiś pomysł?

stivens
  • Rejestracja: dni
  • Ostatnio: dni
3

Nie chce mi sie czytac programu, bo nawet go nie wkleiles poprawnie (brak formatowania), ale strzelam, ze chodzi o tzw. short circuit

MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1106
3
Jacky12 napisał(a):

To jest przykład z książki i zastanawiam się, jaki jest sens tworzenia w funkcji linearSearch() zmiennej typu bool jako flagi, jeśli program działa identycznie bez niej.

Nie, program nie zadziała identycznie jak usuniesz zmienną found. Aby się o tym przekonać uruchom program pod debugerem i zobacz krok po kroku jakie instrukcje są wykonywane. Okaże się, że ustawienie flagi na true spowoduje zakończenie wykonywania pętli. Masz tam warunek while (index < size && !found) więc jeśli found == 1 cały warunek bez względu na pierwsze porównanie będzie fałszem. Zatem po znalezieniu szukanej wartości pętla od razu zakończy się.

Jest to optymalizacja. W małych ilościach danych nie będzie znaczącej różnicy, ale jak będziesz miał do przeszukania 1 000 000 wartości to możesz widzieć już zysk zatrzymując wyszukiwanie po pierwszym znalezionym elemencie.

SL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 999
3

Normalnie to sie robi return index. Takie flagi to typowe https://pl.wikipedia.org/wiki/Programowanie_strukturalne , gdzie dbasz o to, żeby return był w tylko jednym miejscu

J1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 12
0
Mr.YaHooo napisał(a):
Jacky12 napisał(a):

To jest przykład z książki i zastanawiam się, jaki jest sens tworzenia w funkcji linearSearch() zmiennej typu bool jako flagi, jeśli program działa identycznie bez niej.

Nie, program nie zadziała identycznie jak usuniesz zmienną found. Aby się o tym przekonać uruchom program pod debugerem i zobacz krok po kroku jakie instrukcje są wykonywane. Okaże się, że ustawienie flagi na true spowoduje zakończenie wykonywania pętli. Masz tam warunek while (index < size && !found) więc jeśli found == 1 cały warunek bez względu na pierwsze porównanie będzie fałszem. Zatem po znalezieniu szukanej wartości pętla od razu zakończy się.

Jest to optymalizacja. W małych ilościach danych nie będzie znaczącej różnicy, ale jak będziesz miał do przeszukania 1 000 000 wartości to możesz widzieć już zysk zatrzymując wyszukiwanie po pierwszym znalezionym elemencie.

Teraz wszystko stało się jasne :)
Dzięki wielkie i pozdrawiam serdecznie!

J1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 12
1
stivens napisał(a):

Nie chce mi sie czytac programu, bo nawet go nie wkleiles poprawnie (brak formatowania), ale strzelam, ze chodzi o tzw. short circuit

Zadbam o formatowanie i poczytam o short circuit. Dziękuję

J1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 12
0
slsy napisał(a):

Normalnie to sie robi return index. Takie flagi to typowe https://pl.wikipedia.org/wiki/Programowanie_strukturalne , gdzie dbasz o to, żeby return był w tylko jednym miejscu

Dzięki, poczytam.

enedil
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1028
1

Sprawdź sobie działanie wersji z flagą i bez na podstawie

Kopiuj
{ 87, 75, 87, 100, 82 }

i się przekonasz, że w sumie to nie jest ten sam program (nawet pomijając optymalizacje).

several
  • Rejestracja: dni
  • Ostatnio: dni
4

Co to za książka? Kod taki sobie, i nie chodzi tylko o wskazaną funkcję.

CZ
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2505
2

@Jacky12 weź nie czytaj tej ksiazki, bo gosc robi dziwnego while zamiast zwyklego prostego fora. Nie mowiac o przestarzalych koncepcjach typu "paradygmat strukturalny" o ktorym ktos tam wspomniał. Jak sam zauważyłeś:

To jest przykład z książki i zastanawiam się, jaki jest sens tworzenia w funkcji linearSearch() zmiennej typu bool jako flagi, jeśli program działa identycznie bez niej

Tylko to utrudnia programowanie.

MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1106
2
Czitels napisał(a):

@Jacky12 weź nie czytaj tej ksiazki, bo gosc robi dziwnego while zamiast zwyklego prostego fora. Nie mowiac o przestarzalych koncepcjach typu "paradygmat strukturalny" o ktorym ktos tam wspomniał. Jak sam zauważyłeś:

Akurat faktycznie książka jest zapewne napisana przez starego programistę. Jednak nie wpychałbym na siłę tutaj jakichś paradygmatów. Ot, po prostu 30 lat temu programowało się właśnie w ten sposób, że dawało się flagi, bardzo często jako zmienne globalne i tym sposobem robiło się sterowanie przepływem w programie. Pewnie mu tak zostało i dla niego jest to naturalne, jednak nie ma w tym nic głębszego. Faktem jest, że robi się z tego niezła kaszana jak się zasiada do czytania takiego kodu. Z drugiej strony jeśli ktoś planuje pracować w C/C++ powinien umieć czytać i poruszać się w takim kodzie, bo dużo systemów C++ to systemy legacy gdzie widuje się nieraz ciekawsze rzeczy :D

Jednak nie ma się co spierać o to co lepsze czy while czy for. Obie pętle są dla mnie tak samo czytelne, chociaż sam preferuję for.

Czitels napisał(a):

Tylko to utrudnia programowanie.

A kto powiedział, że programowanie jest łatwe? :D Często tam gdzie jest C/C++ nie będzie łatwo bo:

  1. mamy do czynienia z codebasem który zaczął być pisany 30 lat temu
  2. liczy się wydajność. Więc z czytelnością kodu nie raz będzie ciężko
MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
5

Ten kod wskazuje, że autor książki, albo nie jest profesjonalistą, albo najlepszym razie, osoba ta nie potrafi się uwolnić od złych wzorców nauczania C++.
Ludzie uczą się przez rozpoznawanie wzorców, ego nauczanie złych wzorców od samego początku, będzie uczniowi ciążyć w przyszłości.

Dla mnie takimi syngamiami są:

  • using namespace std;
  • int linearSearch(const int[], int, int); prototyp funkcji w stylu kiepskiego C. Od C++20 powinno być: std::size_t linearSearch(std::span<const int>, int);, a we wcześniejszych wersjach standardów C++ początkującemu napisałbym: std::size_t linearSearch(const std::vector<int>&, int);
  • sama zawartość: linearSearch wygląda jakby pisał ją uzdolniony uczeń podstawówki albo przeciętny licealista. Zależnie od standardu C++ jaki ma promować książka, dałby rózne wersje tego kodu. Np:
Kopiuj
// C++20
constexpr std::size NotFound = -1;

std::size_t linearSearch(std::span<const int> r, int value)
{
    size_t i = 0;
    for (auto& x : r) {
        if (x == value) return i;
        i++;
    }
    return NotFound;
}
Kopiuj
// C++03
const std::size NotFound = -1;

std::size_t linearSearch(const std::vector<int>& v, int value)
{
    for (std::size_t i = 0; i < v.size(); ++i) {
        if (v[i] == value) {
            return i;
        }
    }
    return NotFound;
}

albo wersja z iteratorami - zależnie od fazy zaawansowania.

Miang
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1778
2

cóż, ja bym nie jechała po autorze książki bo być może był to przykład dla początkujących którzy już poznali instrukcje while{} ale jeszcze nie było mowy o break
myślicie że łatwo jest stworzyć przykład dostosowany do poziomu odbiorcy?
początkujący się pyta, odpowiadacie wrzucając mu wygenerowany przez jakiś LLM przykład gdzie połowy instrukcji nie zna, a jak poda to jako rozwiązanie zadania na studiach to się nieźle wygłupi jeśli tylko prowadzący będzie chciał być choć trochę dociekliwy i zapytać "co robi ta instrukcja"
już kiedyś o tym pisałam Ktoś podał założenia, ale walić to , przecież wiem lepiej

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.