给出三个字符串A,B和C.编写一个函数,检查C是否是A和B的交织。如果C包含A和B的所有字符以及所有字符的顺序,则称其为交错A和B.保留单个字符串中的字符。
例如:
我在net找到了一些解决方案,但下面是我的方法,有人可以告诉我,我错过了什么或我的算法会有效吗?谢谢。
我的Algo:
a
和c
。在遍历时,我们首先计算两件事:char是否存在并保存索引,即找到char的索引f
。一旦我们找到了char,我们应该在那个地方添加一些特殊的char,这样我们就不会再考虑这个char了。a
中的c
中的下一个字符,搜索您找到上一个字符的索引f
,即b
。如果我们找不到回报。false
相同。b
而不是重复a
而不是a = xxy, b = xxz and c = xxzxxxy
并返回结果。e.g。
a
以:
开头
- for a in a,c = 0xzxxxy(我将0作为特殊字符)
- 对于x中的x,从索引0开始(因为我们在0处找到了前一个char)c = 00zxxxy。
- for a in a,c = 00zxxx0
- for b in b,c = 00z0xx0
- 表示b中的x,c = 00z00x0
- 对于b中的z,我们在索引4之后找不到z,索引4是我们找到b的前一个字符的索引。
醇>从 {{1}} 开始返回false,因此我们现在将从 b 开始。
首先从b:
开始
- for b in b,c = 0xzxxxy
- for b in b,c = 00zxxxy
- for b in b,c = 000xxxy
- for a in a,c = 0000xxy
- for a in a,c = 00000xy
- 表示y,c = 00000x0
醇>
因此,true ie.c是a和b的交错字符串。
答案 0 :(得分:9)
您的解决方案代表greedy algorithm略有修改,因为它会将C
中的字符计为第一次传递中的A
(或B
上的A = xxyxxy
B = xxzxxz
C = xxzxxyxxyxxz
第二次通过)一旦找到匹配。这会破坏以下字符串:
A
作为C
成员的匹配字符的第一次传递会将00zxx0000xxz
变为
B
将匹配字符计为C
成员的第二个字段会将00000yxxyxx0
变为
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);
}
以下是memoized解决方案的简单Java实现:
{{1}}
答案 1 :(得分:0)
首先,我会检查A的长度和B的长度总和等于C的长度。
接下来,检查A的第一个字符是否等于C的第一个字符。
如果没有,检查B的第一个字符是否等于C的第一个字符。
检查以A或B开头的其他字符,具体取决于上述两个条件中的哪一个为真。
这是一个可以进行测试的方法:
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;
}
您最多可以调用此方法两次。电话会是
if (isInterleaved(a, b, c))
或
if (isInterleaved(b, a, c))
如果A的第一个字符和B的第一个字符相等,请检查以上一步中没有开头的A或B字符串开头的其他字符。
这样,您可以保存可能满足条件的字符串的复杂测试。
答案 2 :(得分:0)
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