I am trying to return the length of a common substring between two strings. I'm very well aware of the DP solution, however I want to be able to solve this recursively just for practice.
I have the solution to find the longest common subsequence...
def get_substring(str1, str2, i, j):
if i == 0 or j == 0:
return
elif str1[i-1] == str2[j-1]:
return 1 + get_substring(str1, str2, i-1, j-1)
else:
return max(get_substring(str1, str2, i, j-1), get_substring(str1, str2, j-1, i))
However, I need the longest common substring, not the longest common sequence of letters. I tried altering my code in a couple of ways, one being changing the base case to...
if i == 0 or j == 0 or str1[i-1] != str2[j-1]:
return 0
But that did not work, and neither did any of my other attempts.
For example, for the following strings...
X = "AGGTAB"
Y = "BAGGTXAYB"
print(get_substring(X, Y, len(X), len(Y)))
The longest substring is AGGT.
My recursive skills are not the greatest, so if anybody can help me out that would be very helpful.
package algo.dynamic;
public class LongestCommonSubstring {
public static void main(String[] args) {
String a = "AGGTAB";
String b = "BAGGTXAYB";
int maxLcs = lcs(a.toCharArray(), b.toCharArray(), a.length(), b.length(), 0);
System.out.println(maxLcs);
}
private static int lcs(char[] a, char[] b, int i, int j, int count) {
if (i == 0 || j == 0)
return count;
if (a[i - 1] == b[j - 1]) {
count = lcs(a, b, i - 1, j - 1, count + 1);
}
count = Math.max(count, Math.max(lcs(a, b, i, j - 1, 0), lcs(a, b, i - 1, j, 0)));
return count;
}
}
You need to recurse on each separately. Which is easier to do if you have multiple recursive functions.
def longest_common_substr_at_both_start (str1, str2):
if 0 == len(str1) or 0 == len(str2) or str1[0] != str2[0]:
return ''
else:
return str1[0] + longest_common_substr_at_both_start(str1[1:], str2[1:])
def longest_common_substr_at_first_start (str1, str2):
if 0 == len(str2):
return ''
else:
answer1 = longest_common_substr_at_both_start (str1, str2)
answer2 = longest_common_substr_at_first_start (str1, str2[1:])
return answer2 if len(answer1) < len(answer2) else answer1
def longest_common_substr (str1, str2):
if 0 == len(str1):
return ''
else:
answer1 = longest_common_substr_at_first_start (str1, str2)
answer2 = longest_common_substr(str1[1:], str2)
return answer2 if len(answer1) < len(answer2) else answer1
print(longest_common_substr("BAGGTXAYB","AGGTAB") )
I am so sorry. I didn't have time to convert this into a recursive function. This was relatively straight forward to compose. If Python had a fold function a recursive function would be greatly eased. 90% of recursive functions are primitive. That's why fold is so valuable.
I hope the logic in this can help with a recursive version.
(x,y)= "AGGTAB","BAGGTXAYB"
xrng= range(len(x)) # it is used twice
np=[(a+1,a+2) for a in xrng] # make pairs of list index values to use
allx = [ x[i:i+b] for (a,b) in np for i in xrng[:-a]] # make list of len>1 combinations
[ c for i in range(len(y)) for c in allx if c == y[i:i+len(c)]] # run, matching x & y
...producing this list from which to take the longest of the matches
['AG', 'AGG', 'AGGT', 'GG', 'GGT', 'GT']
I didn't realize getting the longest match from the list would be a little involved.
ls= ['AG', 'AGG', 'AGGT', 'GG', 'GGT', 'GT']
ml= max([len(x) for x in ls])
ls[[a for (a,b) in zip(range(len(ls)),[len(x) for x in ls]) if b == ml][0]]
"AGGT"
My professor gave this exercise to us in class and asked to exactly mimic the recursive calls with stacks. This is the recursive algorithm:
def algo(T, h):
ret = -1
s = 0
d = 0
if T != None:
if T.left != None:
s = algo(T.left, h + 1)
if T.right != None:
d = algo(T.right, h + 1)
if s == 0 and d == 0:
ret = h
else:
ret = s + d
return ret
This is my attempt at solving this exercise (I used two stacks, one for saving T and another one to save "s")
def algo_it(T, h):
ret = -1
s = 0
d = 0
curr = T
next = None
last = None
stack_T = Stack()
stack_S = Stack()
while curr != None or not stack_T.empty():
if curr != None:
# First time entering the function
ret = -1
s = 0
d = 0
if curr.left != None:
# Left recursive call
h = h + 1
next = curr.left
# Save current T because it will be popped when going up
# on recursion tree
stack_T.push(curr)
elif curr.right != None:
# Right recursive call
h = h + 1
next = curr.right
stack_T.push(curr)
else:
# Force going up on recursion tree
next = None
else:
# Coming up from recursion tree
curr = stack_T.top()
if last != curr.right and curr.right != None:
# We're here from the 1st recursive call (left)
# We have to go in right recursive call now
h = h + 1
next = curr.right
# We are returning from left, so ret = s = algo(T.left, h + 1)
s = ret
stack_S.push(s)
ret = -1
d = 0
else:
stack_T.pop()
if curr.right != None:
s = stack_S.pop()
d = ret
else:
s = ret
d = 0
if s == 0 and d == 0:
ret = h
else:
ret = s + d
last = curr
curr = next
return ret
The algorithm is failing because on stack_S.pop() I'm popping when stack is empty so I get runtime error. Am I close to get a solution?
I highly appreciate all of your help!
When you are mimicking the recursive call, you are only pushing on the stack that you know you are supposed to return to. But you aren't pushing the context to know which one to push the response to.
I would suggest that you do this problem in multiple steps.
Convert all of your function local variables (T, h, ret, s and d) into stacks outside of your recursive function, with explicit pop/push instead of declaring them, and expecting them to disappear when your function ends. (Hint: leave ret on the stack, and pop off of it as you manipulate stack_s or stack_d.) This may require creating a helper function for the very first recursive call.
Put labels in your function for where you first call it, and every place that you can return.
Convert to iterative as follows. Add a stack for the function calls. It will contain a label for where to be in the function. Instead of making a recursive call you change the top of the function stack to say where to return to in this call, and push a new one on to say start a new function, and then go to the next loop iteration. (The condition for exiting the loop is that the function stack is empty, and your answer will be the top of the ret stack.)
This is a somewhat lengthy but mechanical process. It should give you an appreciation for how much the computer just does for you normally. :-)
I've written a program to find shortest path in a N*N grid recursively.
def dfs(x,y,Map,p):
N = len(Map)
p += [[x,y]]
if Map[x][y] == 'E':
return p
for i in [[x-1,y],[x+1,y],[x,y-1],[x,y+1]]:
if N > i[0] >= 0 and N > i[1] >= 0 :
if (Map[i[0]][i[1]] == 'P' or Map[i[0]][i[1]] == 'E') and i not in p:
dfs(i[0], i[1], Map,p)
return []
When Map[x][y] = 'E' the recursion don't stop and return p. But it goes till the end. How to correct it and return the path(p).
By the looks of it, the code is prone to loop indefinitely. This is due to lack of checks whether you've entered a node before and moving in all (4) directions from a given node.
To solve it simply, add another array NxN of Boolean values answering the question: visited?. Then update the code to something along the lines:
def dfs(x,y,Map,visited,p):
visited[x,y] = true;
N = len(Map)
(...)
if (Map[i[0]][i[1]] == 'P' or Map[i[0]][i[1]] == 'E')
and i not in p
and visited[i[0], i[1]] == false:
dfs(i[0], i[1], Map,visited,p)
This relates to the Coursera Scala course so I want to directly ask you NOT to give me the answer to the problem, but rather to help me debug why something is happening, as a direct answer would violate the Coursera honor code.
I have the following code:
def balance(chars: List[Char]): Boolean = {
val x = 0
def loop(list: List[Char]): Boolean = {
println(list)
if (list.isEmpty) if(x == 0) true
else if (list.head == '(') pushToStack(list.tail)
else if (list.head == ')') if(x <= 0) false else decreaseStack(list.tail)
else loop(list.tail)
true
}
def pushToStack(myList: List[Char]) { x + 1; loop(myList)}
def decreaseStack(myList: List[Char]) { x - 1; loop(myList)}
loop(chars)
}
A simple explanation:
If the code sees a "(" then it adds 1 to a variable. If it sees a ")" then it first checks whether the variable is equal to or smaller than 0. If this is the case, it returns false. If the value is bigger than 0 then it simply decreases one from the variable.
I have tried running the following:
if(balance("This is surely bad :-( ) (".toList)) println("balanced") else println("not balanced");
Clearly this is not balanced, but my code is returning balanced.
Again: I am not asking for help in writing this program, but rather help in explained why the code is returning "balanced" when clearly the string is not balanced
--EDIT--
def balance(chars: List[Char]): Boolean = {
val temp = 0;
def loop(list: List[Char], number: Int): Boolean = {
println(list)
if (list.isEmpty) if(number == 0) true
else if (list.head == '(') loop(list.tail, number + 1)
else if (list.head == ')') if(number <= 0) false else loop(list.tail, number - 1)
else loop(list.tail,number)
true
}
loop(chars,0)
}
^^ Still prints out balanced
You are using an immutable x when you really want a mutable x.
Here, let me rewrite it for you in a tail recursive style to show you what you're actually doing:
#tailrec def loop(myList: List[Char], cur: Int = 0): Boolean = myList match{
case "(" :: xs =>
val tempINeverUse = cur+1
loop(xs, cur) //I passed in 0 without ever changing "cur"!
case ")" :: xs if cur < 0 => false //This is a bug, regardless if you fix the rest of it
case ")" :: xs =>
val tempINeverUse = cur-1
loop(xs, cur) //Passed in 0 again!
case x :: xs => loop(xs, cur)
case Nil => cur == 0 //Since I've never changed it, it will be 0.
}
You need to keep a context of parenthesis in comments or in quotes as well. You can use a counter to achieve that. If the counter is set for a comment or a double quote then ignore any parenthesis that comes your way. Reset the counter whenever you find a finishing comment or double quote
This is an interview question, for which I did not find any satisfactory answers on stackoverflow or outside. Problem statement:
Given an arithmetic expression, remove redundant parentheses. E.g.
((a*b)+c) should become a*b+c
I can think of an obvious way of converting the infix expression to post fix and converting it back to infix - but is there a better way to do this?
A pair of parentheses is necessary if and only if they enclose an unparenthesized expression of the form X % X % ... % X where X are either parenthesized expressions or atoms, and % are binary operators, and if at least one of the operators % has lower precedence than an operator attached directly to the parenthesized expression on either side of it; or if it is the whole expression. So e.g. in
q * (a * b * c * d) + c
the surrounding operators are {+, *} and the lowest precedence operator inside the parentheses is *, so the parentheses are unnecessary. On the other hand, in
q * (a * b + c * d) + c
there is a lower precedence operator + inside the parentheses than the surrounding operator *, so they are necessary. However, in
z * q + (a * b + c * d) + c
the parentheses are not necessary because the outer * is not attached to the parenthesized expression.
Why this is true is that if all the operators inside an expression (X % X % ... % X) have higher priority than a surrounding operator, then the inner operators are anyway calculated out first even if the parentheses are removed.
So, you can check any pair of matching parentheses directly for redundancy by this algorithm:
Let L be operator immediately left of the left parenthesis, or nil
Let R be operator immediately right of the right parenthesis, or nil
If L is nil and R is nil:
Redundant
Else:
Scan the unparenthesized operators between the parentheses
Let X be the lowest priority operator
If X has lower priority than L or R:
Not redundant
Else:
Redundant
You can iterate this, removing redundant pairs until all remaining pairs are non-redundant.
Example:
((a * b) + c * (e + f))
(Processing pairs from left to right):
((a * b) + c * (e + f)) L = nil R = nil --> Redundant
^ ^
(a * b) + c * (e + f) L = nil R = nil --> Redundant
^ ^ L = nil R = + X = * --> Redundant
a * b + c * (e + f) L = * R = nil X = + --> Not redundant
^ ^
Final result:
a * b + c * (e + f)
I just figured out an answer:
the premises are:
1. the expression has been tokenized
2. no syntax error
3. there are only binary operators
input:
list of the tokens, for example:
(, (, a, *, b, ), +, c, )
output:
set of the redundant parentheses pairs (the orders of the pairs are not important),
for example,
0, 8
1, 5
please be aware of that : the set is not unique, for instance, ((a+b))*c, we can remove outer parentheses or inner one, but the final expression is unique
the data structure:
a stack, each item records information in each parenthese pair
the struct is:
left_pa: records the position of the left parenthese
min_op: records the operator in the parentheses with minimum priority
left_op: records current operator
the algorithm
1.push one empty item in the stack
2.scan the token list
2.1 if the token is operand, ignore
2.2 if the token is operator, records the operator in the left_op,
if min_op is nil, set the min_op = this operator, if the min_op
is not nil, compare the min_op with this operator, set min_op as
one of the two operators with less priority
2.3 if the token is left parenthese, push one item in the stack,
with left_pa = position of the parenthese
2.4 if the token is right parenthese,
2.4.1 we have the pair of the parentheses(left_pa and the
right parenthese)
2.4.2 pop the item
2.4.3 pre-read next token, if it is an operator, set it
as right operator
2.4.4 compare min_op of the item with left_op and right operator
(if any of them exists), we can easily get to know if the pair
of the parentheses is redundant, and output it(if the min_op
< any of left_op and right operator, the parentheses are necessary,
if min_op = left_op, the parentheses are necessary, otherwise
redundant)
2.4.5 if there is no left_op and no right operator(which also means
min_op = nil) and the stack is not empty, set the min_op of top
item as the min_op of the popped-up item
examples
example one
((a*b)+c)
after scanning to b, we have stack:
index left_pa min_op left_op
0
1 0
2 1 * * <-stack top
now we meet the first ')'(at pos 5), we pop the item
left_pa = 1
min_op = *
left_op = *
and pre-read operator '+', since min_op priority '*' > '+', so the pair(1,5) is redundant, so output it.
then scan till we meet last ')', at the moment, we have stack
index left_pa min_op left_op
0
1 0 + +
we pop this item(since we meet ')' at pos 8), and pre-read next operator, since there is no operator and at index 0, there is no left_op, so output the pair(0, 8)
example two
a*(b+c)
when we meet the ')', the stack is like:
index left_pa min_op left_op
0 * *
1 2 + +
now, we pop the item at index = 1, compare the min_op '+' with the left_op '*' at index 0, we can find out the '(',')' are necessary
This solutions works if the expression is a valid. We need mapping of the operators to priority values.
a. Traverse from two ends of the array to figure out matching parenthesis from both ends.
Let the indexes be i and j respectively.
b. Now traverse from i to j and find out the lowest precedence operator which is not contained inside any parentheses.
c. Compare the priority of this operator with the operators to left of open parenthesis and right of closing parenthesis. If no such operator exists, treat its priority as -1. If the priority of the operator is higher than these two, remove the parenthesis at i and j.
d. Continue the steps a to c until i<=j.
Push one empty item in the stack
Scan the token list
2.1 if the token is operand, ignore.
2.2 if the token is operator, records the operator in the left_op,
if min_op is nil, set the min_op = this operator, if the min_op
is not nil, compare the min_op with this operator, set min_op as
one of the two operators with less priority.
2.3 if the token is left parenthese, push one item in the stack,
with left_pa = position of the parenthesis.
2.4 if the token is right parenthesis:
2.4.1 we have the pair of the parentheses(left_pa and the
right parenthesis)
2.4.2 pop the item
2.4.3 pre-read next token, if it is an operator, set it
as right operator
2.4.4 compare min_op of the item with left_op and right operator
(if any of them exists), we can easily get to know if the pair
of the parentheses is redundant, and output it(if the min_op
< any of left_op and right operator, the parentheses are necessary,
if min_op = left_op, the parentheses are necessary, otherwise
redundant)
2.4.5 if there is no left_op and no right operator(which also means
min_op = nil) and the stack is not empty, set the min_op of top
item as the min_op of the popped-up item
examples
The code below implements a straightforward solution. It is limited to +, -, *, and /, but it can be extended to handle other operators if needed.
#include <iostream>
#include <set>
#include <stack>
int loc;
std::string parser(std::string input, int _loc) {
std::set<char> support = {'+', '-', '*', '/'};
std::string expi;
std::set<char> op;
loc = _loc;
while (true) {
if (input[loc] == '(') {
expi += parser(input, loc + 1);
} else if (input[loc] == ')') {
if ((input[loc + 1] != '*') && (input[loc + 1] != '/')) {
return expi;
} else {
if ((op.find('+') == op.end()) && (op.find('-') == op.end())) {
return expi;
} else {
return '(' + expi + ')';
}
}
} else {
char temp = input[loc];
expi = expi + temp;
if (support.find(temp) != support.end()) {
op.insert(temp);
}
}
loc++;
if (loc >= input.size()) {
break;
}
}
return expi;
}
int main() {
std::string input("(((a)+((b*c)))+(d*(f*g)))");
std::cout << parser(input, 0);
return 0;
}
I coded it previously in https://calculation-test.211368e.repl.co/trim.html. This doesn't have some errors in other answers.
(6 / (-2454) ** (((234)))) + (-5435) --> 6 / (-2454) ** 234 + (-5435)
const format = expression => {
var change = [], result = expression.replace(/ /g, "").replace(/\*\*/g, "^"), _count;
function replace(index, string){result = result.slice(0, index) + string + result.slice(index + 1)}
function add(index, string){result = result.slice(0, index) + string + result.slice(index)}
for (var count = 0; count < result.length; count++){
if (result[count] == "-"){
if ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890)".includes(result[count - 1])){
change.push(count);
}else if (result[count - 1] != "("){
add(count, "(");
count++;
_count = count + 1;
while ("1234567890.".includes(result[_count])) _count++;
if (_count < result.length - 1){
add(_count, ")");
}else{
add(_count + 2, ")");
}
}
}
}
change = change.sort(function(a, b){return a - b});
const len = change.length;
for (var count = 0; count < len; count++){replace(change[0] + count * 2, " - "); change.shift()}
return result.replace(/\*/g, " * ").replace(/\^/g, " ** ").replace(/\//g, " / ").replace(/\+/g, " + ");
}
const trim = expression => {
var result = format(expression).replace(/ /g, "").replace(/\*\*/g, "^"), deleting = [];
const brackets = bracket_pairs(result);
function bracket_pairs(){
function findcbracket(str, pos){
const rExp = /\(|\)/g;
rExp.lastIndex = pos + 1;
var depth = 1;
while ((pos = rExp.exec(str))) if (!(depth += str[pos.index] == "(" ? 1 : -1 )) {return pos.index}
}
function occurences(searchStr, str){
var startIndex = 0, index, indices = [];
while ((index = str.indexOf(searchStr, startIndex)) > -1){
indices.push(index);
startIndex = index + 1;
}
return indices;
}
const obrackets = occurences("(", result);
var cbrackets = [];
for (var count = 0; count < obrackets.length; count++) cbrackets.push(findcbracket(result, obrackets[count]));
return obrackets.map((e, i) => [e, cbrackets[i]]);
}
function remove(deleting){
function _remove(index){result = result.slice(0, index) + result.slice(index + 1)}
const len = deleting.length;
var deleting = deleting.sort(function(a, b){return a - b});
for (var count = 0; count < len; count++){
_remove(deleting[0] - count);
deleting.shift()
}
}
function precedence(operator, position){
if (!"^/*-+".includes(operator)) return "^/*-+";
if (position == "l" || position == "w") return {"^": "^", "/": "^", "*": "^/*", "-": "^/*", "+": "^/*-+"}[operator];
if (position == "r") return {"^": "^", "/": "^/*", "*": "^/*", "-": "^/*-+", "+": "^/*-+"}[operator];
}
function strip_bracket(string){
var result = "", level = 0;
for (var count = 0; count < string.length; count++){
if (string.charAt(count) == "(") level++;
if (level == 0) result += string.charAt(count);
if (string.charAt(count) == ")") level--;
}
return result.replace(/\s{2,}/g, " ");
}
for (var count = 0; count < brackets.length; count++){
const pair = brackets[count];
if (result[pair[0] - 1] == "(" && result[pair[1] + 1] == ")"){
deleting.push(...pair);
}else{
const left = precedence(result[pair[0] - 1], "l"), right = precedence(result[pair[1] + 1], "r");
var contents = strip_bracket(result.slice(pair[0] + 1, pair[1])), within = "+";
for (var _count = 0; _count < contents.length; _count++) if (precedence(contents[_count], "w").length < precedence(within, "w").length) within = contents[_count];
if (/^[0-9]+$/g.test(contents) || contents == ""){
deleting.push(...pair);
continue;
}
if (left.includes(within) && right.includes(within)){
if (!isNaN(result.slice(pair[0] + 1, pair[1]))){
if (Number(result.slice(pair[0] + 1, pair[1])) >= 0 && !"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".includes(result[pair[0] - 1])) deleting.push(...pair);
}else if (!"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".includes(result[pair[0] - 1])) deleting.push(...pair);
}
}
}
remove(deleting);
result = format(result);
return result;
}
<input id="input">
<button onclick="document.getElementById('result').innerHTML = trim(document.getElementById('input').value)">Remove and format</button>
<div id="result"></div>
I think that you are looking for kind of algorithm as seen in the following photo.
This algorithm is "almost" ready, since a lot of bugs arise once the more complex it becomes, the more complicated it gets. The way I work on this thing, is 'build-and-write-code-on-the-fly', which means that for up to 4 parentheses, things are easy. But after the expression goes more complex, there are things that I cannot predict while writing down thoughts on paper. And there comes the compiler to tell me what to correct. It would not be a lie if I state that it is not me to have written the algorithm, but the (C#) compiler instead! So far, it took me 1400 lines. It is not that the commands were difficult to write. It was their arrangement that was a real puzzle. This program you are looking for, is characterized by a really high grade of complexity. Well, if you need any primary ideas, please let me know and I will reply. Thanx!
Algorithm