我尝试使用CLRS实现KMP字符串匹配算法,但文本输入为" bbaa"并且模式输入为" aab",它被卡在while
函数内的getKMPPrefix
循环中的无限循环中。我的代码如下:
private int[] getKMPPrefix(char[] p, int m) {
int[] prefix = new int[m];
prefix[0] = 0;
int k = 0;
for(int q = 1; q < m; q++) {
while(k > 0 && p[k] != p[q] ) { //Stuck here
k = prefix[k];
}
if(p[k] == p[q]) {
k++;
}
prefix[q] = k;
}
return prefix;
}
public void kmp(String text, String pattern) {
char[] t = text.toCharArray();
char[] p = pattern.toCharArray();
int n = text.length();
int m = pattern.length();
int[] prefix = getKMPPrefix(p, m);
int q = 0;
for(int i = 1; i < n; i++) {
while(q > 0 && p[q] != t[i]) {
q = prefix[q];
}
if(p[q] == t[i]) {
q++;
}
if(q == m) {
System.out.println("Pattern occurs with shift " + (i-m+1));
q = prefix[m-1];
}
}
}
知道为什么会这样吗?
答案 0 :(得分:2)
以下是发生的事情:
它到达了这条线:
while(k > 0 && p[k] != p[q] ) { //Stuck here
k=0
显然这会失败,它会跳出循环并转到下一个
if(p[k] == p[q]) {
k++;
}
在您的情况下,输入为aab
,因此这是p[0]=p[1]=a
现在,k=1
现在您将k
的值分配给prefix
prefix[q] = k;
现在它陷入了僵局。
它现在回到while
循环
while(k > 0 && p[k] != p[q] ) { //Stuck here
k = prefix[k];
}
注意,您刚刚在早期循环prefix[q] = k;
中分配,即p[1] = 1
涉及while
循环k=1
和&#39; p [1]!= p [2]&#39;即a!=b
它通过并进入循环
k = prefix[k];
k=1
和prefix[1] = 1
,这意味着您要将值1
重新分配给k
它再次返回到k=1
和p=1
的while循环和值,因为它永远不会超过while
循环以增加p
存在死锁,true
循环的条件将保持while
,并且程序永远不会出现while
循环。
您可以更改while
循环条件或在循环内部增加p
或在某些条件之后增加break
内部。我解释了Deadlock
,尝试自己弄清楚程序。古德勒克
答案 1 :(得分:0)
// Tint the image
- (UIImage *)imageWithTint:(UIColor *)tintColor alpha:(CGFloat)alpha {
UIImage *image = self;
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
CGContextRef c = UIGraphicsGetCurrentContext();
[image drawInRect:rect];
CGContextSetFillColorWithColor(c, [[tintColor colorWithAlphaComponent:0.25] CGColor]);
CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
CGContextFillRect(c, rect);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
如果模式是&#34; aabaaa&#34;,您的代码将导致死锁。这个正确的条件将以正确的方式生成前缀。