check whether a string C is an interleaving of A and B - java

Given three strings A, B and C. Write a function that checks whether C is an interleaving of A and B. C is said to be interleaving A and B, if it contains all characters of A and B and order of all characters in individual strings is preserved.
For example:
'hotdog' is an interleaving of 'hot' and 'dog' (easy)
'superb' is an interleaving of 'up' and 'serb'
'heartache' is an interleaving of 'ear' and 'ache'
'chat' is an interleaving of 'hat' and 'cat'
'cheaters' is not an interleaving of 'chat' and 'seer', because while it contains all the letters from each, the letters from 'seer' do not appear in order
I find some solutions in net but below is my approach can somebody tell me am i missing something or my algo will work? thanks.
My Algo:
Traverse through a and c. While traversal we calculate two things first: whether the char is present or not and save the index i.e. f where the char is found. And as soon as we find the char we should put some special char in that place, so that we will not consider this char further.
For the next char in a search in the c from the index where you have found the previous char i.e. f. if we don't find than return.
Same you do for b as well.
If after doing the above step if we find false than repeat for first b than a and return the result.
e.g.
a = xxy, b = xxz and c = xxzxxxy
start with a:
for x in a, c = 0xzxxxy (i am putting 0 as special char)
for x in a, start from the index 0 onwards(because we have found the previous char at 0)c = 00zxxxy.
for y in a, c = 00zxxx0
for x in b, c = 00z0xx0
for x in b, c = 00z00x0
for z in b, we could not find z after the index 4 which was the index where we found the previous char for b.
as starting with a returns false so we will start with b now.
So start with b:
for x in b, c = 0xzxxxy
for x in b, c = 00zxxxy
for z in b, c = 000xxxy
for x in a, c = 0000xxy
for x in a, c = 00000xy
for y in a, c = 00000x0
hence true i.e.c is the interleaved string of a and b.

Your solution represents a greedy algorithm with a slight modification, because it counts a character in C as belonging to A on the first pass (or to B on the second pass) as soon as it finds a match. This will break for the following strings:
A = xxyxxy
B = xxzxxz
C = xxzxxyxxyxxz
The firs pass that counts a matching character as a member of A will turn C into
00zxx0000xxz
The second pass that counts a matching character as a member of B will turn C into
00000yxxyxx0
Here is a simple Java implementation of a memoized solution:
private static boolean checkOverlap(String a, String b, String c) {
Boolean[][][] memoize = new Boolean[a.length()+1][b.length()+1][c.length()+1];
return checkOverlap(a, b, c, 0, 0, 0, memoize);
}
private static boolean checkOverlap(
String a
, String b
, String c
, int pa
, int pb
, int pc
, Boolean[][][] memoize
) {
Boolean res = memoize[pa][pb][pc];
if (res != null) {
return (boolean)res;
}
if (pa == a.length() && pb == b.length() && pc == c.length()) {
res = true;
} else if (pc == c.length()) {
res = false;
} else {
res = false;
if (pa != a.length() && c.charAt(pc) == a.charAt(pa) && checkOverlap(a, b, c, pa+1, pb, pc+1, memoize)) {
res = true;
} else if (pb != b.length() && c.charAt(pc) == b.charAt(pb) && checkOverlap(a, b, c, pa, pb+1, pc+1, memoize)) {
res = true;
}
}
return (memoize[pa][pb][pc] = res);
}
Demo on ideone.

First, I'd check that the length of A and the length of B summed equal the length of C.
Next, check if the first character of A is equal to the first character of C.
If not, check if the first character of B is equal to the first character of C.
Check the other characters starting with either A or B, depending on which of the two conditions above was true.
Here's a method that will do the test:
public boolean isInterleaved(String a, String b, String c) {
int aIndex = 0;
int bIndex = 0;
int cIndex = 0;
while (cIndex < c.length()) {
if (aIndex < a.length()) {
if (a.charAt(aIndex) != c.charAt(cIndex)) { return false; }
cIndex++;
aIndex++;
}
if (bIndex < b.length()) {
if (b.charAt(bIndex) != c.charAt(cIndex)) { return false; }
cIndex++;
bIndex++;
}
}
return true;
}
You would call this method at most twice. The calls would be either
if (isInterleaved(a, b, c))
or
if (isInterleaved(b, a, c))
If the first character of A and the first character of B are equal, check the other characters starting with the A or B string you didn't start with in the previous step.
This way, you save the complicated testing for the strings that can possibly satisfy the conditions.

def isinterleave(a, b, c):
la = len(a)
lb = len(b)
lc = len(c)
if la + lb != lc: return False
if la == lb == lc == 0: return True
if (la > 0 and lb >0 and a[0] == b[0] == c[0]):
return isinterleave(a[1:], b, c[1:]) or isinterleave(a, b[1:], c[1:])
if (la > 0 and a[0] == c[0]):
return isinterleave(a[1:], b, c[1:])
if (lb > 0 and b[0] == c[0]):
return isinterleave(a, b[1:], c[1:])
return False

Related

compare three different values and return true false accordingly? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a below code which takes three input parameters a, b and c and compare three different values and basis on that it returns true false..
public boolean compare(int a, int b, int c) {
int value = increment(a, c);
if (a < value && b < c || a < value && b > c && c < b) {
return true;
}
return false;
}
private int increment(int a, int c) {
int f = 0;
for (int i = 0; i < c; i++) {
f += a;
}
return f;
}
Any better way to write this?
You have an undefined method u in your code. Assuming u is a misspelling of increment, then this is the simplest you can get:
public boolean compare(int a, int b, int c) {
return c > 1 && b != c;
}
Your increment function returns the product of the two numbers (which means it has the wrong name). If value is increment(a, c), then value is a * c. If you compare a < a * c and are given that a and c are greater than 0, then since a*c equals a if c==1 and is greater than a if c>1, then a < a * c is equivalent to testing whether c > 1.
Looking at your condition, ((a < value && b < c) || (a < value && b > c && c < b)): This returns true if either of the expressions around || is true. But a < value has to be true in both cases. So we can extract it. So for the expression to be true, a < value has to be true, and then either of the remaining parts of the expressions has to be true, so the above is equivalent to
a < value && (b < c || (b > c && c < b))
and since b > c means the same thing as c < b we can eliminate the redundancy:
a < value && (b < c || b > c)
and testing whether b is either less than or greater than c is the same as testing that they're not equal:
a < value && b != c
and as was shown above, a < value is the same as c > 1, thus
c > 1 && b != c
The only thing i can reduce is your increment(), it can be a single line expression. Also use parenthesis in if condition to make it more clear. Also b>c && c<b is same thing in two form reduce it to b>c only.
public boolean compare(int a, int b, int c) {
int value = a*c;
if (a < value && b < c || a < value && b > c) {
return true;
}
return false;
}
Maybe you can clarify what you want to do here, the code as you have laid it out is very repetitive and looks like it might have logic bugs...
As for simplification:
1) The if in compare can be greatly simplified:
if (a < value && b!=c) {
return true;
}
This is because you test for a < value on both sides of the ||, and then test for b<c on one side and c<b on the other. Thus this only fails when a>value or when b==c.
2) In increment you can just multiply your input parameters:
private int increment(int a, int c) {
return a*c;
}
You add a a number of times equal to c, which is exactly what multiplication does...

Return the larger value if it is in the range 10..20

I am trying to work out this problem on codingbat and the problem is Given 2 positive int values, return the larger value that is in the range 10..20 inclusive, or return 0 if neither is in that range. The solution has been given below but I can not understand the first part as the comment says larger value is a, but the code says( b > a ) and what does this mean: int temp = a; a = b; b = temp;. Can anyone please explain it...
public int max1020(int a, int b) {
// First make it so the bigger value is in a
if (b > a) {
int temp = a;
a = b;
b = temp;
}
// Knowing a is bigger, just check a first
if (a >= 10 && a <= 20) return a;
if (b >= 10 && b <= 20) return b;
return 0;
}
The first if statement makes sure that a is not smaller than b (if a is smaller than b, it swaps a and b - that's what the 3 assignment statements involving the temp variable do).
The second if statement returns a if it's in the required range (and at this point we know a >= b).
If not, the third if statement returns b if it's in the required range.
Otherwise 0 is returned (when both a and b are not in the required range).
It says that if the value of b is greater than that of a, switch the 2 values. So, for example, if a = 10 and b = 15:
if (b > a) { is true so will get in the if
int temp = a; temp will take the value 10
a = b; a will take the value 15
b = temp; b will take the value 10
So, the values of a and b will be switched, if the value of b is greater than that of a. Therefore, a will have the bigger value.

Calculating best case run time complexity of recursive algorithm?

In class i have started learning how to calculate the run time complexity functions of various algorithms and am finding it difficult. I am trying to calculate the best case rune time complexity of my recursive algorithm below.
At the moment i am choosing my fundamental operation to be a comparison between the index of two chars, and assuming i am trying to find the path where my algorithm outputs a result as soon as possible, i am thinking this first comparison being false would lead my algorithm to do this if i am correct.
Would i be correct in thinking the best case run time complexity function for this algorithm would be t(n) = 1 and in taking the comparison of indexes as a fundamental operation?
public class StringShuffleTest {
public static boolean isOrderedShuffle(String a, String b, String c){
//variables for the size of Strings a, b and c.
int n = a.length();
int m = b.length();
int len = c.length();
//if the length of c is not the length of a + b, return false.
if (len != (n + m)){
return false;
}
//if String c contains String b as a substring, then remove String b from c and make m = 0.
//This statement avoids errors when dealing with Strings with very similar characters.
if (c.contains(b)){
c = c.replace(b, "");
m = 0;
}
//if the length of a or b is 0, and c equals a or b, return true, otherwise,
//return false.
if (n == 0 || m == 0){
if (c.equals(a) || c.equals(b)){
return true;
}
else
return false;
}
//if String a has length 1, remove a from String c and make String a empty.
if (n == 1){
c = c.substring(0, c.indexOf(a.charAt(0))) + c.substring(c.indexOf(a.charAt(0)) +1);
a = "";
return isOrderedShuffle(a, b, c);
}
//An ordered shuffle of two given strings, a and b, is a string that can be formed by interspersing
//the characters of a and b in a way that maintains the left-to-right order of the characters from each
//string.
//Recursive algorithm to determine if String c is an ordered shuffle of a and b.
else
if (c.indexOf(a.charAt(0)) >= 0){
int indexOfFirsta = c.indexOf(a.charAt(0));
int indexOfSeconda = c.indexOf(a.charAt(1));
if (indexOfFirsta <= indexOfSeconda){//Taking as fund operation.
c = c.substring(0, indexOfFirsta) + c.substring(indexOfFirsta +1);
a = a.substring(1, n);
System.out.println(a);
System.out.println(c);
return isOrderedShuffle(a, b, c);
}
else
if (c.indexOf(b.charAt(0)) >= 0){
int indexOfFirstb = c.indexOf(b.charAt(0));
int indexOfSecondb = c.indexOf(b.charAt(1));
if (indexOfFirstb <= indexOfSecondb){
c = c.substring(0, indexOfFirstb) + c.substring(indexOfFirstb +1);
b = b.substring(1, m);
System.out.println(b);
System.out.println(c);
return isOrderedShuffle(a, b, c);
}
}
}
return false;
}
public static void main(String[] args) {
System.out.println(StringShuffleTest.isOrderedShuffle("abc", "def", "abedcf"));
}
}

If equivalent without using conditional operations and other loop methods java

int function(int a, int b, int c){
if(a==c)
return a;
else
return b;
}
Question is to achieve a same o/p without using if, while, do, for, switch,conditional expression(?:) and other general inbuilt methods like equals
Please tell me the logic and code..
Here's one fairly straightforward option:
int function(int a, int b, int c) {
java.util.HashMap<Boolean, Integer> map = new java.util.HashMap<Boolean, Integer>();
map.put(true, a);
map.put(false, b);
return map.get(a == c);
}
Using maps to emulate switch statements in languages that don't have them is pretty common. Using them to emulate if statements is probably an abuse.
Here's an approach using operators only:
int function(int a, int b, int c) {
//If a == c: result = 0x00000000
//Else: result = 0xFFFFFFFF
int result = (a - c | c - a) >> 31;
//If a == c: result = 0x00000000 & (a ^ b) = 0
//Else: result = 0xFFFFFFFF & (a ^ b) = a ^ b
result &= a ^ b;
//If a == c: result = 0 ^ a = a
//Else: result = (a ^ b) ^ a = b
result ^= a;
return result;
}
I really wish I came up with Cairnarvon's solution. Here's what I got, but in any case you'll end up using conditional statements somewhere hidden in a function call, unless you can figure out how to do this with bitwise operators.
public static int fn(int a, int b, int c) {
Boolean equal = (a == c);
//if equal is false, compareTo will return 0.
//if equal is true, compareTo will return any positive integer, thus we take mod 2 to ensure this is 1
int ret_a = equal.compareTo(Boolean.FALSE) % 2;
//if ret_a is 0, make ret_b = 1
//if ret_a is 1, make ret_b = 0
int ret_b = (ret_a + 1) % 2;
//one of these two terms is guaranteed to be zero, therefore you will only
//return the value of a, or b.
return (ret_a * a) + (ret_b * b);
}
Here is my attempt at a solution with no comparison or bit twiddling. Sadly as #Pshemo pointed out my logic is flawed.
public static int fn(int a, int b, int c) {
//I assumed this will return 1 if not a != c
//See Pshemo's comment about why this is wrong.
int not_equal = ((a - c) * (a - c) ) % 2;
int ret_a = (not_equal + 1) % 2;
int ret_b = not_equal;
//one of these two terms is guaranteed to be zero, therefore you will only
//return the value of a, or b.
return (ret_a * a) + (ret_b * b);
}
There are a number of possible approaches, including:
Do the test in native code. That's cheating.
Find some library class that can used to do the job. There are probably lots of variations on this approach; e.g. see #Cairnarvon's answer.
Do something tricky to generate an exception (or not) depending on the inputs. My initial idea was to use division by zero, but here's another way ...
int insanelyStupidConditional (int a, int b, int c) {
int[] dummy = new int[1];
try {
int foo = dummy[a - c];
} catch (ArrayIndexOutOfBoundsException ex) {
return b;
}
return a;
}
Bit twiddling ... like #Vlad's answer
Anyway, the point of the interview question is not the answer, but whether you are able to think outside of the box to arrive at something. The most practical answer is "change the requirements ... this is insane".
Another way
Base idea return b * f(a,c) + a * (1 - f(a,c)) where
f(a,c) -> 1 for a != c
f(a,c) -> 0 for a == c
so
for a!=c we will return b*(1) + a*(0);
and for a==c we will return b*(0) + a*(1);
code
public static int test(int a, int b, int c) {
// (a - c) | (c - a) will give
// for a != b negative value
// for a == c zero
// to get sign of that value we need to get highest bit
// so >>>31 will do the trick
int signum = ((a - c) | (c - a)) >>> 31;
//for a == c -> signum = 0
//for a != c -> signum = 1 (it indicates that (a - c) | (c - a) was negative)
return b * signum + a * (1 - signum);
}
There you go, no if, while, do, for, switch, inline if (?:), or any other operator (==, !=, >, <, >=, etc.):
int function(int a, int b, int c){
int[] result = {-1, a, b};
return result[new TreeSet<Integer>(Arrays.asList(a, c)).size()];
}
Logic: Adds both a and c to a Set. If they are equal, they'll be added only once, and the set's size will be 1. If they are different, the size will be 2.

check if two integers sum to a third

Ok I'm doing this programming assignment and need a little help.
Here is the problem:
Given three ints, a b c, return true if it is possible to add two of the ints to get the third.
twoAsOne(1, 2, 3) → true
twoAsOne(3, 1, 2) → true
twoAsOne(3, 2, 2) → false
Here's the what I have gotten so far:
public boolean twoAsOne(int a, int b, int c) {
return a + b != c;
}
It keeps saying it is not fully correct and I do not know where I am going wrong.
The question asks if it is possible to add any two to get the remaining one. Your code tests only if the first two add to the third.
Thus, twoAsOne(3,1,2) should return true because 3 = 1 + 2; but you are only checking whether 3 + 1 = 2, which is false.
You're only checking one of the possibilities and, on top of that, you're checking it wrongly since you'll return false if a + b == c (because you're using the != operator).
I'm not going to do you homework for you, but the full list of possibilities is:
n1 = n2 + n3
n2 = n1 + n3
n3 = n1 + n2
It should be a simple matter: the result should be true if any of those is true. Otherwise the result should be false.
Or, to provide even a more obvious clue: it should be true if one or more of those conditions are met. Else it should be false.
I don't know how much more obvious I can make it without writing the code for you :-)
Update: And now that more than enough time has probably elapsed to make the homework point moot, here's my solution:
public boolean twoAsOne (int n1, int n2, int n3) {
if (n1 == n2 + n3) return true;
if (n2 == n1 + n3) return true;
if (n3 == n1 + n2) return true;
return false;
}
Although those last two lines could be replaced with:
return (n3 == n1 + n2);
I prefer the (to me, anyway) more readable version.
Besides the answers provided by itowlson and Pax, since you are dealing with ints, there is a possibility that they will overflow, e.g.
Integer.MAX_VALUE + 1 == Integer.MIN_VALUE
Which is not mathematically true
You may want to check this kind of scenarios to make your program complete.
Your code only takes into consideration the sum of int a and int b. The solution requires all possibilities to be covered i.e. "sum of int a and int c" and "sum of int b and int c". Refer to the code mentioned below, hope it helps!
public boolean twoAsOne(int a, int b, int c) {
return ((a + b == c) || (b + c == a) || (c + a == b));
}
Dude I hope you got the answer by now... if you haven't
public boolean twoAsOne(int a, int b, int c) {
return ((a+b==c) || (a+c==b) || (b+c==a));
}
I might be very late yet I have minimized it. twoAsOne
public boolean twoAsOne(integer a, integer b, integer c){
return ((a+b) == c ? true : (a+c) == b ? true : (b+c == a)? true : false);
}
package get_third;
public class Get_third {
int a , b ,c ;
boolean third_value(int a , int b , int c){
if(a+b==c||b+c==a||c+a==b)
{
return true;
}
else
return false ;
}
public static void main(String[] args) {
Get_third obj =new Get_third();
System.out.println(obj.third_value(1, 2, 3));
System.out.println(obj.third_value(3, 1, 2));
System.out.println(obj.third_value(3, 2, 2));
}
}
// start
public boolean twoAsOne(int a, int b, int c) {
if (a + b == c) {
return true;
}
else if (a + c == b) {
return true;
}
else if (b + c == a) {
return true;
}
else {
return false;
}
}
// end

Categories

Resources