Minimum add to make parentheses string consisting of '{', '}', '[', ']', '(', ')' valid - string

This problem is an addition to the familiar stack question(https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/) where we have to return the minimum number of additions to make the parentheses string valid. But that question consists of only '(' and ')'. What will happen if we extend that question to other types of parentheses like '[', ']', '{', '}'. I just came across this in a discussion among my friends and need help on how to approach.
For example: [[[{{}]]){)}) -> [[[{{}}]]] (){()}()
in this case answer is 5 additions to make it valid.
I couldn't come up with a proper approach. 2 approaches I considered are:
Similar to normal question, we push the opening types '(', '{', '[' to the stack as we browse through the string and if we find closing type ')', '}', ']' we check the top of the stack, if they both compliment each other, we pop and continue else we increment the counter and continue without popping out. After traversing the string, we output the answer as sum of counter and stack's size. In this approach the above example will not work as that extra '{' will break the approach.
Another approach is similar to above ie. we push the opening type of parentheses and if we find a closing type and if the stack's top compliment it, we pop and continue with the string, else we will pop out till we get a matching string and for every pop we increment the counter. After traversing the string, the total value is sum of counter and stack's size. But that will not work for cases like {{{{]}}}} where the character ']' will pop out everything and it will increase the answer.
I was also thinking of combining these, more like a Dynamic Programming where we will take the maximum of either seeing the top most value or seeing till we get a match in the stack or if stack becomes empty. But I am not sure on whether these 2 are the only cases to consider.

Explanation
We will process our input string character by character and update certain information about brackets encountered so far. For each bracket type, create a stack that keeps positions of uncompensated opening brackets. Basically, it says how many closing brackets of the current type are needed to make the string valid at the time of checking.
For each bracket of the input, do one of the following:
If the bracket is an opening one (any type), just add its position to the corresponding stack.
Otherwise, it's a closing bracket. If there are no opening brackets in the stack, just increment the resulting sum - unbalanced closing bracket can be compensated right away.
Finally, it's a closing bracket and there are opening brackets in the stack of the current type. So, add the number of all unbalanced brackets of the other types that are located between the last opening bracket of the same type and the current bracket! Don't forget to remove the matching elements from the stacks.
At the end, add a remaining size of each stack to the resulting sum because there may still be unbalanced opening brackets of each type.
Code
I created a simple solution in C++, but it can be easily converted to any other language if needed:
#include <iostream>
#include <stack>
#include <unordered_map>
bool isOpeningBracket(char bracket) {
return bracket == '(' || bracket == '[' || bracket == '{';
}
int main() {
std::string line;
std::cin >> line;
std::unordered_map<char, char> closingToOpeningBracket = {
{')', '('},
{']', '['},
{'}', '{'}
};
std::unordered_map<char, std::unique_ptr<std::stack<uint64_t>>> bracketsMap;
bracketsMap['{'] = std::make_unique<std::stack<uint64_t>>();
bracketsMap['['] = std::make_unique<std::stack<uint64_t>>();
bracketsMap['('] = std::make_unique<std::stack<uint64_t>>();
uint64_t addOperations = 0;
for(auto i = 0; i < line.size(); i++) {
auto bracket = line[i];
bool isOpening = isOpeningBracket(bracket);
auto key = bracket;
if (!isOpening) {
key = closingToOpeningBracket[bracket];
}
auto &bracketStack = bracketsMap[key];
if (isOpening) {
bracketStack->push(i);
} else if (!bracketStack->empty()) {
auto openingBracketPosition = bracketStack->top();
bracketStack->pop();
for (auto & [key, value] : bracketsMap) {
while (!value->empty() && value->top() > openingBracketPosition) {
addOperations++;
value->pop();
}
}
} else {
addOperations++;
}
}
for (auto & [key, value] : bracketsMap) {
addOperations += value->size();
}
std::cout << addOperations << "\n";
return 0;
}
Time and Space Complexity
The time and space complexity of this solution is O(n).

Just Think Greedily, for every closing tag there must be an opening tag if it is not so then we have to add an opening bracket.
So we can find the minimum add by iterating over the string and keeping the count of opening brackets. So when we encounter an opening bracket we increase our count variable and when we encounter a closing bracket we decrease our count variable if we have some positive count otherwise if the count is zero it means that we have to add an opening bracket here. Below is the code for this greedy approach. Time Complexity O(n) and Space Complexity O(1).
int minAddToMakeValid(string s) {
int cnt1 = 0 , cnt2 = 0, cnt3 = 0, ans = 0;
for(char ch : s){
if(ch == '(')cnt1++;
else if(ch == ')'){
if(cnt1==0)ans++;
else cnt1--;
}
if(ch == '{')cnt2++;
else if(ch == '}'){
if(cnt2==0)ans++;
else cnt2--;
}
if(ch == '[')cnt3++;
else if(ch == ']'){
if(cnt3==0)ans++;
else cnt3--;
}
}
return ans + cnt1 + cnt2 + cnt3;
}

You can do this in O(n^3) time (for any number of bracket types) with dynamic programming. This is not a lower bound on the runtime, but it appears that a greedy approach doesn't work for this problem.
First, it's helpful to realize that the 'minimum additions to balance' is the same as the 'minimum deletions to balance' for any bracket string, since the deletion framework is easier to work with. To see why this is true, consider a minimum set of additions: for every bracket that is now matched but was unmatched before, we could have also deleted that bracket, and vice versa.
The idea is to compute all possible bracket pairs: create a list of all indices [i, j], 0 <= i < j < n, where s[i] and s[j] are an open and closed bracket pair of the same type. Then, we find the maximum number of intervals [i, j] we can have, such that any two intervals are either nested or disjoint. This is exactly the requirements to be balanced, and, if you're curious, means that we're looking for the maximum size trivially perfect subgraph of the intersection graph formed by our intervals.
There are O(n^2) intervals, so any modification of this approach has an O(n^2) lower bound. We sort these intervals (by start, then by end if tied), and use dynamic programming (DP) to find the maximum number of nested or disjoint intervals we can have.
Our DP equation has 3 parameters: left, right, and min_index. [left, right] is an inclusive range of indices of s we are allowed to use, and min_index is the smallest index (in our interval list) interval we are allowed to use. If we know the leftmost interval that we can feasibly use, say, [start, end], the answer will come from either using or not using this interval. If we don't use it, we get dp(left, right, min_index+1). If we do use the interval, we add the maximum number of intervals we can nest inside (start, end), plus the maximum number of intervals starting strictly after end. This is 1 + dp(start+1, end-1, min_index+1) + dp(end+1, right, min_index+1).
For a fuller definition:
dp(left, right, min_index) :=
maximum number of intervals from interval_list[min_index:]
that are contained in [left, right] and all pairwise nested or disjoint.
Also, let
first_index := max(smallest index of an interval starting at or after left,
min_index)
so that interval_list[first_index] = (first_start, first_end).
dp(left, right, min_index) = 0 if (left > right or first_index >= length(interval_list)),
max(dp(left, right, first_index+1),
1
+ dp(first_start+1, first_end-1, first_index+1)
+ dp(first_end+1, right, first_index+1))
otherwise.
Here's a Python implementation of the algorithm:
def balance_multi_string(s: str) -> int:
"""Given a multi-paren string s, return minimum deletions to balance
it. 'Balanced' means all parentheses are matched, and
all pairs from different types are either nested or disjoint
Runs in O(n^3) time.
"""
open_brackets = {'{', '[', '('}
closed_brackets = {'}', ']', ')'}
bracket_partners = {'{': '}', '[': ']', '(': ')',
'}': '{', ']': '[', ')': '('}
n = len(s)
bracket_type_to_open_locations = collections.defaultdict(list)
intervals = []
for i, x in enumerate(s):
if x in closed_brackets:
for j in bracket_type_to_open_locations[bracket_partners[x]]:
intervals.append((j, i))
else:
bracket_type_to_open_locations[x].append(i)
if len(intervals) == 0:
return n
intervals.sort()
num_intervals = len(intervals)
#functools.lru_cache(None)
def point_to_first_interval_strictly_after(point: int) -> int:
"""Given a point, return index of first interval starting
strictly after, or num_intervals if there is none."""
if point > intervals[-1][0]:
return num_intervals
if point < intervals[0][0]:
return 0
return bisect.bisect_right(intervals, (point, n + 2))
#functools.lru_cache(None)
def dp(left: int, right: int, min_index: int) -> int:
"""Given inclusive range [left,right], and minimum interval index,
return the maximum number of intervals we can add
within this range so that all added intervals
are either nested or disjoint."""
if left >= right or min_index >= num_intervals:
return 0
starting_idx = max(point_to_first_interval_strictly_after(left - 1), min_index)
if starting_idx == num_intervals or intervals[starting_idx][0] >= right:
return 0
first_start, first_end = intervals[starting_idx]
best_answer = dp(first_start, right, starting_idx + 1) # Without first interval
if first_end <= right: # If we include the first interval
best_answer = max(best_answer,
1
+ dp(first_start + 1, first_end - 1, starting_idx + 1)
+ dp(first_end + 1, right, starting_idx + 1))
return best_answer
return n - 2 * dp(0, n - 1, 0)
Examples:
( [ ( [ ) } ] --> 3
} ( } [ ) [ { } --> 4
} ( } } ) ] ) { --> 6
{ ) { ) { [ } } --> 4
) ] } { } [ ( { --> 6
] ) } } ( [ } { --> 8

Related

find the number of ways you can form a string on size N, given an unlimited number of 0s and 1s

The below question was asked in the atlassian company online test ,I don't have test cases , this is the below question I took from this link
find the number of ways you can form a string on size N, given an unlimited number of 0s and 1s. But
you cannot have D number of consecutive 0s and T number of consecutive 1s. N, D, T were given as inputs,
Please help me on this problem,any approach how to proceed with it
My approach for the above question is simply I applied recursion and tried for all possiblity and then I memoized it using hash map
But it seems to me there must be some combinatoric approach that can do this question in less time and space? for debugging purposes I am also printing the strings generated during recursion, if there is flaw in my approach please do tell me
#include <bits/stdc++.h>
using namespace std;
unordered_map<string,int>dp;
int recurse(int d,int t,int n,int oldd,int oldt,string s)
{
if(d<=0)
return 0;
if(t<=0)
return 0;
cout<<s<<"\n";
if(n==0&&d>0&&t>0)
return 1;
string h=to_string(d)+" "+to_string(t)+" "+to_string(n);
if(dp.find(h)!=dp.end())
return dp[h];
int ans=0;
ans+=recurse(d-1,oldt,n-1,oldd,oldt,s+'0')+recurse(oldd,t-1,n-1,oldd,oldt,s+'1');
return dp[h]=ans;
}
int main()
{
int n,d,t;
cin>>n>>d>>t;
dp.clear();
cout<<recurse(d,t,n,d,t,"")<<"\n";
return 0;
}
You are right, instead of generating strings, it is worth to consider combinatoric approach using dynamic programming (a kind of).
"Good" sequence of length K might end with 1..D-1 zeros or 1..T-1 of ones.
To make a good sequence of length K+1, you can add zero to all sequences except for D-1, and get 2..D-1 zeros for the first kind of precursors and 1 zero for the second kind
Similarly you can add one to all sequences of the first kind, and to all sequences of the second kind except for T-1, and get 1 one for the first kind of precursors and 2..T-1 ones for the second kind
Make two tables
Zeros[N][D] and Ones[N][T]
Fill the first row with zero counts, except for Zeros[1][1] = 1, Ones[1][1] = 1
Fill row by row using the rules above.
Zeros[K][1] = Sum(Ones[K-1][C=1..T-1])
for C in 2..D-1:
Zeros[K][C] = Zeros[K-1][C-1]
Ones[K][1] = Sum(Zeros[K-1][C=1..T-1])
for C in 2..T-1:
Ones[K][C] = Ones[K-1][C-1]
Result is sum of the last row in both tables.
Also note that you really need only two active rows of the table, so you can optimize size to Zeros[2][D] after debugging.
This can be solved using dynamic programming. I'll give a recursive solution to the same. It'll be similar to generating a binary string.
States will be:
i: The ith character that we need to insert to the string.
cnt: The number of consecutive characters before i
bit: The character which was repeated cnt times before i. Value of bit will be either 0 or 1.
Base case will: Return 1, when we reach n since we are starting from 0 and ending at n-1.
Define the size of dp array accordingly. The time complexity will be 2 x N x max(D,T)
#include<bits/stdc++.h>
using namespace std;
int dp[1000][1000][2];
int n, d, t;
int count(int i, int cnt, int bit) {
if (i == n) {
return 1;
}
int &ans = dp[i][cnt][bit];
if (ans != -1) return ans;
ans = 0;
if (bit == 0) {
ans += count(i+1, 1, 1);
if (cnt != d - 1) {
ans += count(i+1, cnt + 1, 0);
}
} else {
// bit == 1
ans += count(i+1, 1, 0);
if (cnt != t-1) {
ans += count(i+1, cnt + 1, 1);
}
}
return ans;
}
signed main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> d >> t;
memset(dp, -1, sizeof dp);
cout << count(0, 0, 0);
return 0;
}

Counter for two binary strings C++

I am trying to count two binary numbers from string. The maximum number of counting digits have to be 253. Short numbers works, but when I add there some longer numbers, the output is wrong. The example of bad result is "10100101010000111111" with "000011010110000101100010010011101010001101011100000000111000000000001000100101101111101000111001000101011010010111000110".
#include <iostream>
#include <stdlib.h>
using namespace std;
bool isBinary(string b1,string b2);
int main()
{
string b1,b2;
long binary1,binary2;
int i = 0, remainder = 0, sum[254];
cout<<"Get two binary numbers:"<<endl;
cin>>b1>>b2;
binary1=atol(b1.c_str());
binary2=atol(b2.c_str());
if(isBinary(b1,b2)==true){
while (binary1 != 0 || binary2 != 0){
sum[i++] =(binary1 % 10 + binary2 % 10 + remainder) % 2;
remainder =(binary1 % 10 + binary2 % 10 + remainder) / 2;
binary1 = binary1 / 10;
binary2 = binary2 / 10;
}
if (remainder != 0){
sum[i++] = remainder;
}
--i;
cout<<"Result: ";
while (i >= 0){
cout<<sum[i--];
}
cout<<endl;
}else cout<<"Wrong input"<<endl;
return 0;
}
bool isBinary(string b1,string b2){
bool rozhodnuti1,rozhodnuti2;
for (int i = 0; i < b1.length();i++) {
if (b1[i]!='0' && b1[i]!='1') {
rozhodnuti1=false;
break;
}else rozhodnuti1=true;
}
for (int k = 0; k < b2.length();k++) {
if (b2[k]!='0' && b2[k]!='1') {
rozhodnuti2=false;
break;
}else rozhodnuti2=true;
}
if(rozhodnuti1==false || rozhodnuti2==false){ return false;}
else{ return true;}
}
One of the problems might be here: sum[i++]
This expression, as it is, first returns the value of i and then increases it by one.
Did you do it on purporse?
Change it to ++i.
It'd help if you could also post the "bad" output, so that we can try to move backward through the code starting from it.
EDIT 2015-11-7_17:10
Just to be sure everything was correct, I've added a cout to check what binary1 and binary2 contain after you assing them the result of the atol function: they contain the integer numbers 547284487 and 18333230, which obviously dont represent the correct binary-to-integer transposition of the two 01 strings you presented in your post.
Probably they somehow exceed the capacity of atol.
Also, the result of your "math" operations bring to an even stranger result, which is 6011111101, which obviously doesnt make any sense.
What do you mean, exactly, when you say you want to count these two numbers? Maybe you want to make a sum? I guess that's it.
But then, again, what you got there is two signed integer numbers and not two binaries, which means those %10 and %2 operations are (probably) misused.
EDIT 2015-11-07_17:20
I've tried to use your program with small binary strings and it actually works; with small binary strings.
It's a fact(?), at this point, that atol cant handle numerical strings that long.
My suggestion: use char arrays instead of strings and replace 0 and 1 characters with numerical values (if (bin1[i]){bin1[i]=1;}else{bin1[i]=0}) with which you'll be able to perform all the math operations you want (you've already written a working sum function, after all).
Once done with the math, you can just convert the char array back to actual characters for 0 and 1 and cout it on the screen.
EDIT 2015-11-07_17:30
Tested atol on my own: it correctly converts only strings that are up to 10 characters long.
Anything beyond the 10th character makes the function go crazy.

Asymmetric Levenshtein distance

Given two bit strings, x and y, with x longer than y, I'd like to compute a kind of asymmetric variant of the Levensthein distance between them. Starting with x, I'd like to know the minimum number of deletions and substitutions it takes to turn x into y.
Can I just use the usual Levensthein distance for this, or do I need I need to modify the algorithm somehow? In other words, with the usual set of edits of deletion, substitution, and addition, is it ever beneficial to delete more than the difference in lengths between the two strings and then add some bits back? I suspect the answer is no, but I'm not sure. If I'm wrong, and I do need to modify the definition of Levenshtein distance to disallow deletions, how do I do so?
Finally, I would expect intuitively that I'd get the same distance if I started with y (the shorter string) and only allowed additions and substitutions. Is this right? I've got a sense for what these answers are, I just can't prove them.
If i understand you correctly, I think the answer is yes, the Levenshtein edit distance could be different than an algorithm that only allows deletions and substitutions to the larger string. Because of this, you would need to modify, or create a different algorithm to get your limited version.
Consider the two strings "ABCD" and "ACDEF". The Levenshtein distance is 3 (ABCD->ACD->ACDE->ACDEF). If we start with the longer string, and limit ourselves to deletions and substitutions we must use 4 edits (1 deletion and 3 substitutions. The reason is that strings where deletions are applied to the smaller string to efficiently get to the larger string can't be achieved when starting with the longer string, because it does not have the complimentary insertion operation (since you're disallowing that).
Your last paragraph is true. If the path from shorter to longer uses only insertions and substitutions, then any allowed path can simply be reversed from the longer to the shorter. Substitutions are the same regardless of direction, but the inserts when going from small to large become deletions when reversed.
I haven't tested this thoroughly, but this modification shows the direction I would take, and appears to work with the values I've tested with it. It's written in c#, and follows the psuedo code in the wikipedia entry for Levenshtein distance. There are obvious optimizations that can be made, but I refrained from doing that so it was more obvious what changes I've made from the standard algorithm. An important observation is that (using your constraints) if the strings are the same length, then substitution is the only operation allowed.
static int LevenshteinDistance(string s, string t) {
int i, j;
int m = s.Length;
int n = t.Length;
// for all i and j, d[i,j] will hold the Levenshtein distance between
// the first i characters of s and the first j characters of t;
// note that d has (m+1)*(n+1) values
var d = new int[m + 1, n + 1];
// set each element to zero
// c# creates array already initialized to zero
// source prefixes can be transformed into empty string by
// dropping all characters
for (i = 0; i <= m; i++) d[i, 0] = i;
// target prefixes can be reached from empty source prefix
// by inserting every character
for (j = 0; j <= n; j++) d[0, j] = j;
for (j = 1; j <= n; j++) {
for (i = 1; i <= m; i++) {
if (s[i - 1] == t[j - 1])
d[i, j] = d[i - 1, j - 1]; // no operation required
else {
int del = d[i - 1, j] + 1; // a deletion
int ins = d[i, j - 1] + 1; // an insertion
int sub = d[i - 1, j - 1] + 1; // a substitution
// the next two lines are the modification I've made
//int insDel = (i < j) ? ins : del;
//d[i, j] = (i == j) ? sub : Math.Min(insDel, sub);
// the following 8 lines are a clearer version of the above 2 lines
if (i == j) {
d[i, j] = sub;
} else {
int insDel;
if (i < j) insDel = ins; else insDel = del;
// assign the smaller of insDel or sub
d[i, j] = Math.Min(insDel, sub);
}
}
}
}
return d[m, n];
}

Finding minimum moves required for making 2 strings equal

This is a question from one of the online coding challenge (which has completed).
I just need some logic for this as to how to approach.
Problem Statement:
We have two strings A and B with the same super set of characters. We need to change these strings to obtain two equal strings. In each move we can perform one of the following operations:
1. swap two consecutive characters of a string
2. swap the first and the last characters of a string
A move can be performed on either string.
What is the minimum number of moves that we need in order to obtain two equal strings?
Input Format and Constraints:
The first and the second line of the input contains two strings A and B. It is guaranteed that the superset their characters are equal.
1 <= length(A) = length(B) <= 2000
All the input characters are between 'a' and 'z'
Output Format:
Print the minimum number of moves to the only line of the output
Sample input:
aab
baa
Sample output:
1
Explanation:
Swap the first and last character of the string aab to convert it to baa. The two strings are now equal.
EDIT : Here is my first try, but I'm getting wrong output. Can someone guide me what is wrong in my approach.
int minStringMoves(char* a, char* b) {
int length, pos, i, j, moves=0;
char *ptr;
length = strlen(a);
for(i=0;i<length;i++) {
// Find the first occurrence of b[i] in a
ptr = strchr(a,b[i]);
pos = ptr - a;
// If its the last element, swap with the first
if(i==0 && pos == length-1) {
swap(&a[0], &a[length-1]);
moves++;
}
// Else swap from current index till pos
else {
for(j=pos;j>i;j--) {
swap(&a[j],&a[j-1]);
moves++;
}
}
// If equal, break
if(strcmp(a,b) == 0)
break;
}
return moves;
}
Take a look at this example:
aaaaaaaaab
abaaaaaaaa
Your solution: 8
aaaaaaaaab -> aaaaaaaaba -> aaaaaaabaa -> aaaaaabaaa -> aaaaabaaaa ->
aaaabaaaaa -> aaabaaaaaa -> aabaaaaaaa -> abaaaaaaaa
Proper solution: 2
aaaaaaaaab -> baaaaaaaaa -> abaaaaaaaa
You should check if swapping in the other direction would give you better result.
But sometimes you will also ruin the previous part of the string. eg:
caaaaaaaab
cbaaaaaaaa
caaaaaaaab -> baaaaaaaac -> abaaaaaaac
You need another swap here to put back the 'c' to the first place.
The proper algorithm is probably even more complex, but you can see now what's wrong in your solution.
The A* algorithm might work for this problem.
The initial node will be the original string.
The goal node will be the target string.
Each child of a node will be all possible transformations of that string.
The current cost g(x) is simply the number of transformations thus far.
The heuristic h(x) is half the number of characters in the wrong position.
Since h(x) is admissible (because a single transformation can't put more than 2 characters in their correct positions), the path to the target string will give the least number of transformations possible.
However, an elementary implementation will likely be too slow. Calculating all possible transformations of a string would be rather expensive.
Note that there's a lot of similarity between a node's siblings (its parent's children) and its children. So you may be able to just calculate all transformations of the original string and, from there, simply copy and recalculate data involving changed characters.
You can use dynamic programming. Go over all swap possibilities while storing all the intermediate results along with the minimal number of steps that took you to get there. Actually, you are going to calculate the minimum number of steps for every possible target string that can be obtained by applying given rules for a number times. Once you calculate it all, you can print the minimum number of steps, which is needed to take you to the target string. Here's the sample code in JavaScript, and its usage for "aab" and "baa" examples:
function swap(str, i, j) {
var s = str.split("");
s[i] = str[j];
s[j] = str[i];
return s.join("");
}
function calcMinimumSteps(current, stepsCount)
{
if (typeof(memory[current]) !== "undefined") {
if (memory[current] > stepsCount) {
memory[current] = stepsCount;
} else if (memory[current] < stepsCount) {
stepsCount = memory[current];
}
} else {
memory[current] = stepsCount;
calcMinimumSteps(swap(current, 0, current.length-1), stepsCount+1);
for (var i = 0; i < current.length - 1; ++i) {
calcMinimumSteps(swap(current, i, i + 1), stepsCount+1);
}
}
}
var memory = {};
calcMinimumSteps("aab", 0);
alert("Minimum steps count: " + memory["baa"]);
Here is the ruby logic for this problem, copy this code in to rb file and execute.
str1 = "education" #Sample first string
str2 = "cnatdeiou" #Sample second string
moves_count = 0
no_swap = 0
count = str1.length - 1
def ends_swap(str1,str2)
str2 = swap_strings(str2,str2.length-1,0)
return str2
end
def swap_strings(str2,cp,np)
current_string = str2[cp]
new_string = str2[np]
str2[cp] = new_string
str2[np] = current_string
return str2
end
def consecutive_swap(str,current_position, target_position)
counter=0
diff = current_position > target_position ? -1 : 1
while current_position!=target_position
new_position = current_position + diff
str = swap_strings(str,current_position,new_position)
# p "-------"
# p "CP: #{current_position} NP: #{new_position} TP: #{target_position} String: #{str}"
current_position+=diff
counter+=1
end
return counter,str
end
while(str1 != str2 && count!=0)
counter = 1
if str1[-1]==str2[0]
# p "cross match"
str2 = ends_swap(str1,str2)
else
# p "No match for #{str2}-- Count: #{count}, TC: #{str1[count]}, CP: #{str2.index(str1[count])}"
str = str2[0..count]
cp = str.rindex(str1[count])
tp = count
counter, str2 = consecutive_swap(str2,cp,tp)
count-=1
end
moves_count+=counter
# p "Step: #{moves_count}"
# p str2
end
p "Total moves: #{moves_count}"
Please feel free to suggest any improvements in this code.
Try this code. Hope this will help you.
public class TwoStringIdentical {
static int lcs(String str1, String str2, int m, int n) {
int L[][] = new int[m + 1][n + 1];
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if (str1.charAt(i - 1) == str2.charAt(j - 1))
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]);
}
}
return L[m][n];
}
static void printMinTransformation(String str1, String str2) {
int m = str1.length();
int n = str2.length();
int len = lcs(str1, str2, m, n);
System.out.println((m - len)+(n - len));
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str1 = scan.nextLine();
String str2 = scan.nextLine();
printMinTransformation("asdfg", "sdfg");
}
}

String Matching: Matching words with or without spaces

I want to find a way by which I can map "b m w" to "bmw" and "ali baba" to "alibaba" in both the following examples.
"b m w shops" and "bmw"
I need to determine whether I can write "b m w" as "bmw"
I thought of this approach:
remove spaces from the original string. This gives "bmwshops". And now find the Largest common substring in "bmwshop" and "bmw".
Second example:
"ali baba and 40 thieves" and "alibaba and 40 thieves"
The above approach does not work in this case.
Is there any standard algorithm that could be used?
It sounds like you're asking this question: "How do I determine if string A can be made equal to string B by removing (some) spaces?".
What you can do is iterate over both strings, advancing within both whenever they have the same character, otherwise advancing along the first when it has a space, and returning false otherwise. Like this:
static bool IsEqualToAfterRemovingSpacesFromOne(this string a, string b) {
return a.IsEqualToAfterRemovingSpacesFromFirst(b)
|| b.IsEqualToAfterRemovingSpacesFromFirst(a);
}
static bool IsEqualToAfterRemovingSpacesFromFirst(this string a, string b) {
var i = 0;
var j = 0;
while (i < a.Length && j < b.Length) {
if (a[i] == b[j]) {
i += 1
j += 1
} else if (a[i] == ' ') {
i += 1;
} else {
return false;
}
}
return i == a.Length && j == b.Length;
}
The above is just an ever-so-slightly modified string comparison. If you want to extend this to 'largest common substring', then take a largest common substring algorithm and do the same sort of thing: whenever you would have failed due to a space in the first string, just skip past it.
Did you look at Suffix Array - http://en.wikipedia.org/wiki/Suffix_array
or Here from Jon Bentley - Programming Pearl
Note : you have to write code to handle spaces.

Resources