string1 中的 string2 计数在 C 中不起作用,但在 Python 中起作用

Posted

技术标签:

【中文标题】string1 中的 string2 计数在 C 中不起作用,但在 Python 中起作用【英文标题】:Count of string2 in string1 not working in C, but works in Python 【发布时间】:2022-01-06 13:06:04 【问题描述】:

问题本身很简单。我必须计算 s1 中 s2 的出现次数。 s2 的长度始终为 2。我尝试用 C 来实现它,但即使我知道逻辑是正确的,它也不起作用。所以我在 pyhton 中尝试了相同的逻辑,并且效果很好。有人可以解释为什么吗?还是我在 C 语言中做错了什么。我在下面给出了两个代码。

C

#include<stdio.h>
#include<string.h>
int main()

char s1[100],s2[2];
int count = 0;
gets(s1);
gets(s2);
for(int i=0;i<strlen(s1);i++)

    if(s1[i] == s2[0] && s1[i+1] == s2[1])
    
        count++;
    

printf("%d",count);
return 0;

Python

s1 = input()
s2 = input()
count = 0
for i in range(0,len(s1)):
    if(s1[i] == s2[0] and s1[i+1] == s2[1]):
        count = count+1
print(count)

【问题讨论】:

你永远不应该使用gets。它被认为是危险的,在标准中已被淘汰。请查看fgets 的手册。您的第二个字符串s2 只能保存长度为 1 的字符串。终止 0 字节需要第二个字节。如果输入超过 1 个字符,则会导致缓冲区溢出,从而导致未定义的行为。 这不是导致问题的原因,但您的 for 循环可以在最后一次迭代时从数组外部访问数据 这能回答你的问题吗? find the count of substring in string s1[i+1] 这可能不会越界访问数组,但如果i == strlen(s1)-1 这不是您想要的,它将达到 0 字节。 感谢@Gerhardh,它现在可以工作了。所以 s2 的大小是问题所在。我从没想过 '\0' 在字符串中也需要空格。 :) 【参考方案1】:

您的 python 代码实际上不正确,如果 s1 的最后一个字符与 s2 的第一个字符匹配,它将引发 IndexError

您必须停止迭代 s1 的倒数第二个字符。

这是一个适用于任意长度 s2 的通用解决方案:

s1 = 'abaccabaabaccca'
s2 = 'aba'
count = 0
for i in range(len(s1)-len(s2)+1):
    if s2 == s1[i:i+len(s2)]:
        count += 1
print(count)

输出:3

【讨论】:

谢谢。我会记住这一点。【参考方案2】:

首先,正如其他人指出的那样,您不想使用gets(),请尝试使用fgets()。否则,您的逻辑是正确的,但是当您在输入中读取时,新行字符将包含在字符串中。

如果您要输入testes,您的字符串将包含test\nes\n(两者分别包含空终止字节\0)。然后导致您在字符串test\n 中搜索它找不到的子字符串es\n。因此,您必须首先从要搜索的子字符串中删除换行符,您可以使用 strcspn() 为您提供es

一旦尾随换行符 (\n) 被替换为空终止字节。您可以在字符串中搜索出现次数。

#include<stdio.h>
#include<string.h>

int main() 
    char s1[100], s2[4];
    int count = 0;
    fgets(s1, 99, stdin);
    fgets(s2, 3, stdin);
    s1[strcspn(s1, "\n")] = '\0';
    s2[strcspn(s2, "\n")] = '\0';

    for(int i=0;i < strlen(s1) - 1;i++) 
        if(s1[i] == s2[0] && s1[i+1] == s2[1]) 
            count++;
        
    

    printf("%d\n",count);
    return 0;

【讨论】:

那么您还应该在解释中说明导致问题的原因。 gets 只是其中的一部分。 @Gerhardh 如果您不关心换行符,则无需 4 大小来读取 2 个字符。 fgets 将始终添加 NUL 终止符,如果它位于 sizeof(buf) - 1 处,则覆盖换行符:godbolt.org/z/KdT6xq31G @yano 你是对的。我忘记了。

以上是关于string1 中的 string2 计数在 C 中不起作用,但在 Python 中起作用的主要内容,如果未能解决你的问题,请参考以下文章

想找一个解决两个字符串匹配程度的算法。

printf与C中的制表符对齐

VB.NET 赋值字符串 ---- String1 = String1+String2

在 Ruby 中设置哈希等于另一个哈希

包含string1的Grep行或包含string2的NOT

java查找string1和string2是不是含有相同的字母种类和数量(string1是否是string2的重新组合)