Examples of tasks solving on recursion in the C++ programming language
Contents
- 1. Calculating the area of a triangle
- 2. Calculate the value of the square of the number based on the dependence
- 3. Combinatorial problem
- 4. The parser for the concept of “identifier”
- 5. Ackermann function value
- 6. The parser for the notion of “simple expression”
- 7. Parser for the concept of “sum”
- 8. Conversion from one number system to another
- 9. Tasks for repetition
- Related topics
Search other websites:
1. Calculating the area of a triangle
Task. A triangle of size m×n is given, where m, n are integers and m>0, n>0. Develop a recursive function that calculates the area of a triangle based on the dependency:
Decision. If the dependency is known, then the implementation of the function presents no particular problems. The recursive process will be stopped when the condition n = m = 1 is fulfilled.
The program code of the S() function is as follows:
int S(int n, int m) { if ((n==1)&&(m==1)) return 1; else if (n>1) return S(n-1, m)+m; else return S(n, m-1)+1; }
2. Calculate the value of the square of the number based on the dependence
Task. Calculate the value of the square of a positive integer n, if the dependence is known
n² = (n-1)² + 2·(n-1) + 1
From this dependence we get the recursion formula:
Decision.
// обчислення квадрату числа int f(int n) { if (n==1) return 1; else return f(n-1)+2*n-1; }
Using the function in another program code
int k; k = f(9); // k = 81
3. Combinatorial problem
Task. Calculate the number of combinations of n different elements for m. The number of combinations is determined by the dependence
Decision.
// number of combinations of n by m int C(int n, int m) { if ((m==0)&&(n>0) || (m==n)&&(n>0)) return 1; else if ((m>n)&&(n>=0)) return 0; else return C(n-1,m-1) + C(n-1,m); }
Using the C() function in other program code
int k; k = C(6,4); // k = 15 k = C(4,3); // k = 4
4. The parser for the concept of “identifier”
Task. Develop a recursive function that implements the parser for the concept ‘identifier’. As is known, in the C++ programming language, the identifier obeys the following rules:
- the first character of the identifier is necessarily the letter of the Latin alphabet;
- second, third, etc. the symbol identifier can be a letter or a number.
The general identifier formula is as follows:
here
- identifier – an identifier;
- letter – some letter of the Latin alphabet (from ‘a’ to ‘z’ or from ‘A’ to ‘Z’);
- digit – digit from ‘0’ to ‘9’.
Decision. In this case, a recursive function is implemented with the name IsIdentifier().Since the function analyzes the concept of “identifier”, the result of returning from a function is a value of type bool. If the function returns true, then the identifier name is correct in accordance with the condition of the task. If the function returns false, then there is an error in the identifier name.
The input parameter of the recursive function IsIdentifier() is a string of type string. This line contains the identifier name. The condition for the end of the recursive process is the achievement of the first character of the identifier.
The text of the IsIdentifier () method is as follows
// method that determines if the identifier name is correct bool IsIdentifier(string s, unsigned int pos) { if (pos==0) // if the first character { char c; c = s[pos]; // check whether the first symbol is a letter if ((c>='a')&&(c<='z') || (c>='A')&&(c<='Z')) return IsIdentifier(s,pos+1); // go to check next symbol else return false; } else if (pos<s.length()) // if not the last symbol { char c = s[pos]; // check if a symbol is a letter or a number if ((c>='a')&&(c<='z') || (c>='A')&&(c<='Z') || (c>='0')&&(c<='9')) return IsIdentifier(s,pos+1); else return false; } else return true; }
Using the IsIdentifier() function in other program code
bool b; b = IsIdentifier("Aa13209", 0); // b = true b = IsIdentifier("5A", 0); // b = false
5. Ackermann function value
Task. Calculate the value of the Ackermann function for two non-negative integers n and m, where
Decision. If dependencies are known, the implementation of the function is not a difficult task. In accordance with the condition of the task, the function gets two parameters. These are non-negative integers n and m. The function also returns a non-negative integer.
For large values of n and m, a stack overflow may occur, since the Ackermann function is twice recursive: one of the arguments to the function is the same recursive function.
The implementation of the function is as follows:
// Ackermann function unsigned int A(unsigned int n, unsigned int m) { if (n==0) return m+1; else if ((n!=0) && (m==0)) return A(n-1,1); else return A(n-1,A(n,m-1)); }
Using the function for small values of n and m:
unsigned int res; res = A(1,2); // res = 4 res = A(0,1); // res = 2 res = A(0,0); // res = 1 res = A(2,2); // res = 7
6. The parser for the notion of “simple expression”
Task. Create a program that implements the parser for the concept of “expression”
here
- Expression – a simple expression;
- simple_identifier – a simple identifier;
- letter – Latin letter from ‘a’ to ‘z’ or from ‘A’ to ‘Z’;
- operation – operation sign ‘+’, ‘–’ or ‘*’.
Decision. To solve this problem, you need to implement three functions:
- the IsIdentifier() function, which determines whether a simple identifier is a letter;
- the function IsOperation(), which determines whether there is an operation syntactically correct in accordance with the task;
- the recursive function IsExpression(), which determines whether a simple expression is syntactically correct in accordance with the task.
The recursive function IsExpression() receives 3 parameters:
- string s, which is analyzed;
- the position pos of the current symbol in the string s;
- an IsOp flag that indicates whether the previous symbol was an operation sign.
The implementations of the functions IsIdentifier(), IsOperation() and IsExpression() are as follows:
// an identifier bool IsIdentifier(char c) { // check if is symbol c a letter if ((c>='a')&&(c<='z') || (c>='A')&&(c<='Z')) return true; else return false; } // operation sign bool IsOperation(char c) { if ((c=='-') || (c=='+') || (c=='*')) return true; else return false; } // Recursive function-analyzer of expression bool IsExpression(string s, unsigned int pos, bool IsOp) { char c; c = s[pos]; if (pos==0) // first symbol { if (IsIdentifier(c)) // check if a first symbol is a letter return IsExpression(s, pos+1, false); else return false; } else if (pos<s.length()-1) // not the first character (second, third, etc.) and not the last { if (IsIdentifier(c)) // if the identifier, analyze the next symbol return IsExpression(s,pos+1,false); else { if (IsOperation(c) && !IsOp) // after the operation should be a simple expression return IsExpression(s,pos+1,true); // indicate at the next level that there was an operation else return false; } } else // otherwise, process the last symbol { if (IsOperation(c)) // if the last symbol is an operation, then the expression is wrong return false; else return IsIdentifier(c); // check if there is last character an identifier } }
Demonstration of using IsExpression() in another method:
bool b; b = IsExpression("a+b",0,false); // b = true b = IsExpression("+a+b",0,false); // b = false b = IsExpression("Adsdl-Bdslf-FDF",0,false); // b = true b = IsExpression("a+-b-c",0,false); // b = false b = IsExpression("a+b;",0,false); // b = false b = IsExpression("alsd+bsldk-",0,false); // b = false b = IsExpression("AbcDEf",0,false); // b = true
Using a similar pattern, you can create several recursive functions that will analyze complex expressions or their fragments. It is important for each function to determine the correct dependencies (algorithm).
7. Parser for the concept of “sum”
Task. Create a program that implements the parser for the concept of “sum”
here
- Sum – a function that analyzes the total amount;
- Integer – a function that analyzes an integer;
- Digit – a function that analyzes a digit;
- Operation – a function that implements the sign of the operation. The sign of the operation can be ‘+’ or ‘–’.
The expression in braces { } can be repeated except for the operation.
Decision. Using this example as a sample, you can develop your own analyzers of complex expressions. The representation of each complex expression can be broken apart. For each part, its own recursive function can be developed.
To solve this problem, 4 functions have been developed:
- the IsSignOp() function, which determines whether is a character c with an operation sign. The character c is passed to the function as an input parameter. The function returns true or false;
- the function IsDigit(), which determines whether is an input symbol c with an integer. The symbol c is a function parameter;
- the recursive function IsInteger(), which analyzes the entire expression. Function receives 3 parameters. The first parameter is the analyzed string. The second parameter pos is the position of the current symbol in the analyzed string s. The third, auxiliary parameter IsOp indicates whether the previous character was an operation sign. The third parameter IsOp is necessary to avoid repeating two characters of operations, for example, “++”;
- the IsSum() function, which calls the recursive IsInteger() function. The IsSum() function performs a simple redirection to the execution of the IsInteger() function.
The implementation of the functions is as follows:
// parser for the concept of "sum" // operation sign bool IsSignOp(char c) { if ((c=='+') || (c=='-')) return true; else return false; } // digit bool IsDigit(char c) { if ((c>='0') && (c<='9')) return true; else return false; } // the recursive function IsInteger (), implements the check of the whole expression, // pos - current character position from string s, which is analyzed // IsOp=true, if the previous character at the top level was a sign of the operation bool IsInteger(string s, int pos, bool IsOp) { char c; c = s[pos]; // get a character to process if (pos==0) // beginning of expression { // the first can be an integer if (IsDigit(c)) return IsInteger(s, pos+1, false); else return false; } else if (pos<s.length()-1) { if (IsDigit(c)) return IsInteger(s, pos+1, false); else { // if not number if (IsSignOp(c)) // is the symbol c an operation sign? { // if the sign of the operation, then see the previous character in the variable IsOp if (!IsOp) return IsInteger(s,pos+1,true); // if the previous character is not an operation sign, then proceed next else return false; // if the previous character is an operation sign, then there is an error: two operation characters cannot be near } else return false; // if not a number or an operation sign, then an error occurs in the expression - an invalid character is present } } else // end of expression return IsDigit(c); // the last character of the expression must be a number (digit) } // the IsSum() function that calls the recursive IsInteger() function bool IsSum(string s) { // invoke the recursive function IsInteger() return IsInteger(s,0,false); }
Using the IsSum() function in another method
bool b; b = IsSum("253+23"); // b = true b = IsSum("2345w-18"); // b = false b = IsSum("750-450+200"); // b = true b = IsSum("-200"); // b = false b = IsSum("2019"); // b = true b = IsSum("210+-5"); // b = false b = IsSum("300-"); // b = false
8. Conversion from one number system to another
Task. Develop a recursive conversion function from decimal to binary.
Decision. The conversion algorithm is classic. It is necessary to divide the input parameter num by 2 as long as num>2. For each division, you need to select the remainder using the expression num%2. The % operation is intended to highlight the remainder of the division of two numbers.
The function Convert10to2() receives two arguments:
- an argument of an unsigned integer type with a parameter named num. This is the given number in decimal notation.
- temporary argument that serves to memorize the current result in binary calculus.
The result of the function is an inverse (reversible) string to the string res. Because, when dividing, the resulting value is formed in the reverse order.
The function has the following implementation:
// conversion of a natural number from the 10th number system to the binary string Convert10to2(unsigned int num, string res) { if (num<2) { if (num==0) res.append("0"); else res.append("1"); // reversing of the res string and returning the result string res2=""; for (int i=res.length()-1; i>=0; i--) res2.push_back(res[i]); return res2; } else { if (num%2 == 0) res.append("0"); else res.append("1"); return Convert10to2((unsigned int)num/2, res); // go to the next step } }
Using a function in another method
string result; string s=""; result = Convert10to2(255,s); // res = 11111111 result = Convert10to2(83,s); // res = 1010011 result = Convert10to2(23,s); // res = 10111 result = Convert10to2(0,s); // res = 0
9. Tasks for repetition
Task 1. Develop a recursive Min() function to calculate the minimum value in array A, which contains n double numbers (n>0).
The solution can be found here.
Task 2. Develop a recursive function ConvertAny() for converting a number from a calculus system with basis m to a calculus system with basis n. The function should receive the following parameters:
- the number num, which needs to be converted from the calculus system m to the calculus system n;
- unsigned integer number m specifying the denomination of the calculus system with the base m (2<m≤9);
- unsigned integer number n specifying the denomination of the calculus system with the base n (2<n≤9);
The function must return a string of type string, which is the result.
The solution can be found here.
Task 3. Develop a recursive function that determines whether a given positive integer N is prime number. A prime number is the number N> 1 which has no other divisors except 1 and itself.
The solution can be found here.