Warunek zakonczenia nieskonczonej rekurencji

Warunek zakonczenia nieskonczonej rekurencji
J2
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 9 lat
  • Postów:17
0

Witam,

staram sie napisac program, ktory zwraca najkrotsza droge krola z podanego pola szachownicy do jego pola srodkowego dla szachownicy 7x7 (jego pole srodkowe to bedzie (3,3) ).

Mam taki kod:

Kopiuj
const int N=7;
int dx[] = {1,0,1,-1,-1,0,-1,1};
int dy[] = {1,1,0,-1,0,-1,1,-1};


bool czyWolne(int w, int k, int i) // funkcja sprawdza czy nie wyszlismy poza szachownice
{
    if ( (w + dx[i] < N) and (w + dx[i] >=0) and (k + dy[i] < N) and (k + dy[i] >=0) )return true;
    else return false;

}
int przejdz(int w, int k, int odleglosc, int mini) // (wiersz z ktorego startuje krol, kolumna, obecna liczba ruchow, najmniejsza obecna liczba ruchow ) 
{
    if (odleglosc >= mini) { return mini; } // jesli liczba krokow do srodka jest wieksza od najmniejszej obecnej drogi to zakoncz instancje 

    if ( (w == 3) and (k == 3) ) // doszlismy do srodka, sprawdzamy czy nasza droga jest obecnie najkrotsza 
    {
        if (odleglosc < mini)
        {
            mini = odleglosc;

        }
        return mini;
    }
    else
    {
        for (int i=0; i<8; i++)
        {

            if (czyWolne(w, k, i) == true)
            {
                return przejdz(w + dx[i], k+ dy[i], odleglosc+1, mini); // wykonujemy ruchy z tablicy ruchow, zwiekszamy licznik ruchow
            }
        }

    }  


} 

Bylbym bardzo wdzieczny za wskazanie jak taka rekurencja mialaby wygladac. Mam chyba problem z operowaniem rekurencja, ktora jest nieskonczona i przerwanie jej w odpowiednim momencie.

Pozdrawiam

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Czy musisz to zrobić za pomocą rekurencji?


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
J2
Nie musze, zrobilem to itereacyjnie. Bylo prosciej i lepiej bo bralem pod uwage polozenie poczatkowe i nie przechodzilem w ciemno wszystkich mozliwosci, ale chcialem wykonac ta implementacje w postaci rekurencyjnej dla treningu zeby zrozumiec mechanic rekurencji.
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

W takim razie musisz zaznaczyć pole jako zajęte po wejściu na niego i odznaczyć przy wycofaniu się.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
J2
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 9 lat
  • Postów:17
0

Rozumiem, tak tez myslalem tylko liczylem ze jest jakas prostsza droga.

Dzieki za pomoc!

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Jest kilka innych, nie wiem czy może być coś prostszego niż dodanie dwóch wierszy, ustawienie komórki na true po czym ustawienie komórki na false.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
J2
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 9 lat
  • Postów:17
0

Zmodyfikowalem ten kod w nastepujacy sposob:

Kopiuj
const int N=7;
int dx[] = {1,0,1,-1,-1,0,-1,1};
int dy[] = {1,1,0,-1,0,-1,1,-1};


bool czyWolne(int w, int k, int i, bool tab[N][N])
{
    if ( (w + dx[i] > N-1) or (w + dx[i] <0)  or (k + dy[i] > N-1) or (k + dy[i] < 0) )return false;
    if (tab[w+ dx[i]][k+dy[i]] == true) return false;
    else return true;

}

int przejdz(int w, int k, int odleglosc, int mini, bool tablica[N][N]) 
{
    bool tab[N][N];
    tab[N][N] = tablica[N][N];

    tab[w][k] = true;



    if ( tab[3][3] == true )
    {
        
        if (odleglosc < mini)
        {
            mini = odleglosc;

        }
        return mini;
    }
    else
    {
        for (int i=0; i<8; i++)
        {

            if (czyWolne(w , k, i, tab) == true)
            {
                return przejdz(w + dx[i], k+ dy[i], odleglosc+1, mini, tab);
            }
        }

        tab[w][k] = false;
        
    }



}

} 

Przy pierwszym wywolaniu przekazuje do funkcji tablice wypelniona falsami, potem wewnatrz kazdej funkcji jest tworzona kopia na ktorej dalej operuje funkcja. W przypadku skonczonej mozliwosci ruchow przechodzi calego fora i zaznacza element tablicy na false.

Nie dziala to jak powinno i nie widze na razie luki w moim rozumowaniu.

J2
Chyba mozna to zrobic bez tworzenia kopii tablicy w kazdym wywolaniu funkcji, chyba ostatnia instrukcja falsowania na razie nic nie robi tak naprawde.
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0
  1. W ten sposób tablicy nie skopiujesz teraz kopiujesz jeden element na dodatek znajdujący się poza tablicą.
  2. Nie twórz kopi tablicy, tylko przy wejściu zaznaczaj, przy wyjściu odznaczaj.
  3. ==true WTF?
  4. Zrób tablicę większą bool tab[N+2][N+2] zaznacz krawędzie jako true wtedy zamiast czyWolne(...) piszesz tab[w][k]
  5. Przenieś tą czy wolne do środka przejdz

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
J2
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 9 lat
  • Postów:17
0

Mam problem z ostatnim punktem, przenioslem sprawdzanie na poczatek, a potem wykonuje dopiero ruch:

Kopiuj
const int N=7;
int dx[] = {1,0,1,-1,-1,0,-1,1};
int dy[] = {1,1,0,-1,0,-1,1,-1};

bool czyWolne(int w, int k, bool tab[N+2][N+2])
{
        if(tab[w][k]) return false;
        else return true;

}
int przejdz(int w, int k, int odleglosc, int mini, bool tab[N+2][N+2])
{
    if (czyWolne(w , k, tab))
        tab[w][k] = true;

    if (tab[3][3])
    {
        if (odleglosc < mini)
        {
            mini = odleglosc;

        }
        return mini;
    }
    else
    {
        for (int i=0; i<8; i++)
        {
            return przejdz(w + dx[i], k+ dy[i], odleglosc+1, mini, tab);
        }
        tab[w][k] = false;
    }
}

 

Niestety prowadzi to do przepelnienia stosu.

J2
A co do sprawdzania warunku () == true to tak po prostu mi zostalo po jakims kursie gdzie wymagano tego dla wiekszej swiadomosci tego co sie robi.
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
2

To naprawdę straszne, nie stosuj żadnych rad bezmyślnie.

Kopiuj
unsigned przejdz(int y,int x,unsigned dist,unsigned mindist,bool tab[N+2][N+2])
  {
   if(tab[w][k]) return mindist;
   if(tab[3][3]) return dist;
   tab[w][k]=true;
   for(int dy=-1;dy<=1;++dy)
     {
      for(int dx=-1;dx<=1;++dx)
        {
         int tmp=przejdz(w+dx,k+dy,dist+1,mindist,tab);
         if(mindist>tmp) mindist=tmp;         
        }
     }
   tab[w][k]=false;
   return mindist;
  }

coś się zagalopowałem - zmienione;


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon
CN
  • Rejestracja:około 9 lat
  • Ostatnio:około 9 lat
  • Postów:2
0

hej, tez sie wlasnie ucze rekurencji i trafilem na ten temat. A czy to nie bedzie przypadkiem tak, ze tablica jest zawsze przekazywana przez referencję skutkiem czego kolejne wywolania beda miec szczatki poprzednich i beda sie wypelnialy az do wypelnienia calej tablicy nim przejda wszytkie możliwości? Ten ostatni kod nie dziala (przynajmniej mi), jezeli autor tematu przerobil to tak żeby dzialalo to prosze o wstawke

_13th_Dragon
przecież wycofujemy się przed powrotem: tab[w][k]=false;
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)