25.07.2017 Views

Intro-CSharp-Book-v2015

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

374 Въведение в програмирането със C#<br />

- Нека текущата позиция в лабиринта е (row, col). В началото тръгваме<br />

от стартовата позиция (0,0).<br />

- Ако текущата позиция e търсената позиция (N-1, M-1), то сме<br />

намерили път и трябва да го отпечатаме.<br />

- Ако текущата позиция е непроходима, връщаме се назад (нямаме<br />

право да стъпваме в нея).<br />

- Ако текущата позиция е вече посетена, връщаме се назад (нямаме<br />

право да стъпваме втори път в нея).<br />

- В противен случай търсим път в четирите възможни посоки. Търсим<br />

рекурсивно (със същия алгоритъм) път към изхода на лабиринта като<br />

опитваме да ходим във всички възможни посоки:<br />

o Опитваме наляво: позиция (row, col-1).<br />

o Опитваме нагоре: позиция (row-1, col).<br />

o Опитваме надясно: позиция (row, col+1).<br />

o Опитваме надолу: позиция (row+1, col).<br />

За да стигнем до този алгоритъм, разсъждаваме рекурсивно. Имаме<br />

задачата "търсене на път от дадена позиция до изхода". Тя може да се сведе<br />

до 4 подзадачи:<br />

- търсене на път от позицията вляво от текущата до изхода;<br />

- търсене на път от позицията нагоре от текущата до изхода;<br />

- търсене на път от позицията вдясно от текущата до изхода;<br />

- търсене на път от позицията надолу от текущата до изхода.<br />

Ако от всяка възможна позиция, до която достигнем, проверим четирите<br />

възможни посоки и не се въртим в кръг (избягваме преминаване през<br />

позиция, на която вече сме били), би трябвало рано или късно да намерим<br />

изхода (ако съществува път към него).<br />

Този път рекурсията не е толкова проста, както при предните задачи. На<br />

всяка стъпка трябва да проверим дали не сме стигнали изхода и дали не<br />

стъпваме в забранена позиция, след това трябва да отбележим позицията<br />

като посетена и да извикаме рекурсивното търсене на път в четирите<br />

посоки. След връщане от рекурсивните извиквания, трябва да отбележим<br />

обратно като непосетена позицията, от която се оттегляме. Такова<br />

обхождане е известно в информатиката като търсене с връщане назад<br />

(backtracking).<br />

Пътища в лабиринт – имплементация<br />

За реализацията на алгоритъма ще ни е необходимо представяне на<br />

лабиринта. Ще ползваме двумерен масив от символи, като в него ще<br />

означим със символа ' ' (интервал) проходимите позиции, с 'e' изхода от<br />

лабиринта и с '*' непроходимите полета. Стартовата позиция ще означим

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!