290 likes | 408 Views
COSC2007 Data Structures II. Chapter 5 Recursion as a Problem-Solving Technique. Topics. 8-Queen problem Languages Algebraic expressions Prefix & Postfix notation & conversion. Introduction. Backtracking:
E N D
COSC2007 Data Structures II Chapter 5Recursion as a Problem-Solving Technique
Topics • 8-Queen problem • Languages • Algebraic expressions • Prefix & Postfix notation & conversion
Introduction • Backtracking: • A problem-solving technique that involves guesses at a solution, backing up, in reverse order, when a dead-end is reached, and trying a new sequence of steps • Applications • 8-Queen problems • Tic-Tac-Toe
Eight-Queens Problem • Given: • 64 square that form 8 x 8 - rows x columns • A queen can attack any other piece within its row, column, or diagonal • Required: • Place eight queens on the chessboard so that no queen can attack any other queen
Eight-Queens Problem • Observations: • Each row or column contain exactly one queen • There are 4,426,165,368 ways to arrange 8 queens on the chessboard • Not all arrangements lead to correct solution • Wrong arrangements could be eliminated to reduce the number of solutions to the problem • 8! = 40,320 arrangements
Eight-Queens Problem • Solution Idea: • Start by placing a queen in the first square of column 1 and eliminate all the squares that this queen can attack • At column 5, all possibilities will be exhausted and you have to backtrack to search for another layout • When you consider the next column, you solve the same problem with one column less (Recursive step) • The solution combines recursion with backtracking
Eight-Queens Problem • How can we use recursion for solving this problem? • For placing a queen in a column, assuming that previous queens were placed correctly • If there are no columns to consider Finish – Base case • Place queen successfully in current column Proceed to next column, solving the same problem on fewer columns – recursive step • No queen can be placed in current column Backtrack • Base case: • Either we reach a solution to the problem with no columns left Success & finish • Or all previous queens will be under attack Failure & Backtrack
Eight-Queens Problem • Pseudocode PlaceQueens (in currColumn: integer) // Places queens in columns numbered Column through 8 if (currColumn > 8) Succes. Reached a solution // base case else { while (unconsidered squares exist in the currColumn & problem is unsolved) {determine the next square in column “currColumn” that is not under attack in earlier column if (such a square exists) { Place a queen in the square PlaceQuenns(currColumn + 1) // Try next column if ( no queen possible in currColumn+1) Remove queen from currColumn & consider next square in that column } // end if } // end while } // end if
Eight-Queens Problem • Implementation: • Classes: • QueenClass • Data members • board: • square • Indicates is the square has a queen or is empty
Eight-Queens Problem • Implementation: • Methods needed: • Public functions • ClearBoard: Sets all squares to empty • DisplayBoard: Displays the board • PlaceQueens: Places the queens in board’s columns & returns either success or failure • Private functions • SetQueen: Sets a given square to QUEEN • RemoveQueen: Sets a given square to EMPTY • IsUnderAttack: Checks if a given square is under attack • Index: Returns the array index corresponding to a row or column
Eight-Queens Problem: public class Queens { public static final int BOARD_SIZE = 8; // squares per row or column Public static final int EMPTY =0; //use to indicate an empty square Public static final int QUEEN=1; //indicate square contains a queen Private in board [][]; //chess board public Queens() { // Creates an empty square board. board = new int [BOARD_SIZE]{BOARD-SIZE]; } public void clearBoard() { } // Sets all squares to EMPTY. public void displayBoard() { } // Displays the board. public boolean placeQueens(int currColumn)
Eight-Queens Problem: // Calls: isUnderAttack, setQueen, removeQueen. { if (currColumn > BOARD_SIZE) return true; // base case else { boolean queenPlaced = false; int row = 1; // number of square in column while ( !queenPlaced && (row <= BOARD_SIZE) ) { // if square can be attacked if (isUnderAttack(row, currColumn)) ++row; // then consider next square in currColumn else // else place queen and consider next { // column setQueen(row, currColumn); queenPlaced = placeQueens(currColumn+1); // if no queen is possible in next column, if (!queenPlaced) { // backtrack: remove queen placed earlier // and try next square in column removeQueen(row, currColumn); ++row; } // end if } // end if } // end while return queenPlaced; } // end if } // end placeQueens
Eight-Queens Problem: Java Code private void setQueen(int row, int column) { } // Sets the square on the board in a given row and column to QUEEN. private void removeQueen(int row, int column) { } // Sets the square on the board in a given row and column to EMPTY. private boolean isUnderAttack(int row, int column) // Determines whether the square on the board at a given row and column is under // attack by any queens in the columns 1 through column-1. // Precondition: Each column between 1 and column-1 has a queen placed in a // square at a specific row. None of these queens can be attacked by any other queen. // Postcondition: If the designated square is under attack, returns true; // otherwise, returns false. private int index(int number) // Returns the array index that corresponds to // a row or column number. // Precondition: 1 <= number <= BOARD_SIZE. // Postcondition: Returns adjusted index value. } // end class Queens
Languages • Language: • A set of strings of symbols • Can be described using syntax rules • Examples: • Java program • program = { w : w is a syntactically correct java program} • Algebraic expressions • Algebraic Expression = { w : w is an algebraic expression }
Languages • Language recognizer: • A program (or machine) that accepts a sentence and determines whether the sentence belongs to the language • Recognition algorithm: • An algorithm that determines whether a given string belongs to a specific language, given the language grammar • If the grammar is recursive, we can write straightforward recursive recognition algorithms
Letter Letter Digit Languages • Example: Grammar for Java identifiers Java Ids = {w:w is a legal Java identifier} • Grammar < identifier > = < letter > | < identifier > < letter > | < identifier > < digit > < letter > = a | b | . . . | z | A | B | . . . | Z | _ < digit > = 0 | 1 | . . . | 9 • Syntax graph • Observations • The definition is recursive • Base case: • A letter ( length = 1) • We need to construct a recognition algorithm
Languages • Java Identifiers’ Recognition algorithm isId (in w: string): boolean // Returns true if w is a legal Java identifier; // otherwise returns false. if (w is of length 1 ) // base case if (w is a letter) return true else return false else if (the last character of w is a letter or a digit) return isId (w minus its last character) // Point X else return false
Palindromes • String that read the same from left-to-right as it does from right-to-left • Examples RADAR DEED • WOW ADA • Madam I’m Adam (without the blanks and quotes) • Language: Palindromes = { w : w reads the same from left to right as from right to left } • Grammar: <pal > = empty string | < ch > | a <pal > a | . . . | z <pal> z | A < pal > A | . . . | Z < pal > Z < ch > = a | b | . . . | z | A | B | . . . | Z • The definition is recursive • Base cases: • Empty string or one character • We need a recognition algorithm
Palindromes • Recognition algorithm isPal(in w: string) : boolean // Checks if a string w is a palindrome; // If palindrome, it returns true, false otherwise If (w is of length 0 or 1) return true // Base-case success else if (first and last characters are the same) return IsPal( w minus first and last characters) // Point A else return false // Base-case failure
An Bn Strings • Language: L = { w : w is of the form An Bn for some n 0 } • Grammar: < legal word > = empty string | A < legal word > B • The definition is recursive • Base case: • empty string
An Bn Strings • Recognition algorithm IsAnBn(in w: string): boolean // Checks if a string w is of the form An Bn; If (w is of length 0) return true // Base–case success else if (w begins with ‘A’ & ends with ‘B’) return IsAnBn( w minus first & last characters) // Point A else return false // Base–case failure
Algebraic Expressions • Algebraic expression • A fully or partially parenthesized infix arithmetic expression • Examples • A + ( B – C ) * D { partially parenthesized} • ( A + ( ( B – C ) * D )) {Fully parenthesized} • Solution • Find a way to get rid of the parentheses completely
Algebraic Expressions • Infix expression: • Binary operators appear between their operands • Prefix (Polish) expression: • Binary operators appear before their operands • Postfix (Reverse Polish) expression: • Binary operators appear after their operands • Examples: Infix Prefix Postfix a + b + a b a b + a + ( b * c ) + a * b c a b c * + (a + b) * c * + a b c a b + c *
Algebraic Expressions • Converting or evaluating partially parenthesized infix expression are complicated (discussed in chapter 6-Stacks) • Postfix & prefix expressions can be evaluated easily by the computer
Prefix Expressions • Language: L = { w : w is a prefix expression } • Grammar: < prefix > = <identifier> | < operator > < prefix1> < prefix2 > < operator > = + | - | * | / < identifier > = A | B | . . . | Z • Definition is recursive • Size of prefix1 & prefix2 is smaller than prefix, since they are subexpressions • Base case: • When an identifier is reached
Prefix Expressions • How to Determine if a Given Expression is a Prefix Expression: 1. Construct a recursive valued function End-Pre (S , First, Last ) that returns either the index of the end of the prefix expression beginning at S(First), or -1 , if no such expression exists in the given string 2. Use The previous function to determine whether a character string S is a prefix expression
Prefix Expressions • End-Pre Function: (Tracing: Fig 5.5, p.229) +EndPre(in First) // Finds the end of a prefix expression, if one exists. // Precondition: The substring of strExp from index first through // the end of the string contains no blank characters. // Postcondition: Returns the index of the last character in the // prefix expression that begins at index first of strExp. // If no such prefix expression exists, endPre should return –1. last = strExp.length –1 if ((First < 0) or (First > Last)) // string is empty return –1 ch = character at position first of strExp if (ch is an identifier) // index of last character in simple prefix expression return First else if (ch is an operator) { // find the end of the first prefix expression FirstEnd = endPre(First+1) // Point X // if the end of the first expression was found // find the end of the second prefix expresion if (FirstEnd > -1) return EndPre(firstEnd+1) // Point Y else return -1 } // end if else return -1
Prefix Expressions • IsPre Function • Uses End-Pre() to determine whether a string is a prefix or not IsPre(): boolean // Determines whether an expression i a prefix expression. // Precondition: The class has a data member strExp that // contains a string with no blank characters. // Postcondition: Returns true if the expression is in prefix form; // otherwise return false. lastChar = endpre(0) return (LastChar >= 0) and (LastChar == strExp.length()-1)
Prefix Expressions • EvaluatePrefix Function • E is the expression beginning at Index evaluatePrefix( in strExp: string) // Evaluates a prefix expression strExp // Precondition: strExp is a string containing a valid prefix expression // with no blanks // PostCondition: Returns the value of the prefix expression { Ch = first character of strExp Delete the first character from strExp if (Ch is an identifier) return value of the identifier // base case else if (Ch is an operator named op) { Operand1 =EvaluatePrefix(strExp) // Point A Operand2 = EvaluatePrefix(strRxp) // Point B return Operand1 op Operand2 } // end if