下面是我必须检查字符串子字符串中特定字符的代码。当我使用三个for
循环但想在两个或一个循环中进行操作时,如何降低其复杂性?
int main(void) {
int i, j, k, t, n;
scanf("%d", &t);
while (t--) {
int count = 0;
scanf("%d", &n);
char a[n], ch;
scanf("%s %c", a, &ch);
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
for (k = i; k <= j; k++) {
if (a[k] == ch) {
count++;
break;
}
}
}
}
printf("%d", count);
}
}
答案 0 :(得分:0)
因此,从代码中可以看出,您试图生成一组子字符串,因此,如果您的数组为abc
,则子字符串将为a, ab, abc, b, bc, c
。然后,您尝试计算字符出现的次数,因此,如果ch = 'b'
,则结果为4。因此,您要计算包含ch的字符串的数目。
因此,以较少的循环来解决此问题的一种方法是,通过为每个i
值识别一个字符串,方法是在最后一个字符串中添加一个字符,并且如果前一个字符串包含n
ch
的副本,则下一个字符串包含n
或n+1
的副本,具体取决于实际值。
下降到一个循环的另一种可能的方法是在数组中循环一次,每次您找到字符ch
时,计算在该位置将包含该字符的子字符串数。因此,对于abc
示例,从位置0开始的3个字符串中的2个和从位置1开始的2个字符串中的2个将包含值。
答案 1 :(得分:0)
您可以使用memchr
代替最内层的循环。
替代
for (k = i; k <= j; k++) {
if (a[k] == ch) {
count++;
break;
}
}
为
if (memchr(&a[i], ch, j - i + 1) != NULL) {
count++;
}
这将使您在代码中使用两个循环。