C程序来计算子串

时间:2017-09-15 15:18:14

标签: c string substring

为什么我的程序总是跳过最后一个子字符串计数?

EG1。字符串:dbdbsnasdb dbdxx

子字符串:db

计数:4(无错误)

EG2。字符串:dbdbsnasmfdb

子字符串:db

计数:2(应该是3)

仅** #include <stdio.h>

int countSubstr(char string[], char substring[]) {
    int i, j;
    int count = 0;
    int subcount = 0;
    for (i = 0; i <= strlen(string);) {
        j = 0;
        count = 0;
        while ((string[i] == substring[j])) {
            count++;
            i++;
            j++;
        }
        if (count == strlen(substring)) {
            subcount++;
            count = 0;
        } else
            i++;
    }
    return subcount;
}

为什么我必须在for循环中声明我的jcount0?是因为j必须保持为0(子串保持不变),只要它循环?

5 个答案:

答案 0 :(得分:3)

  1. 您的内部循环(function Debug-ProcessVS([int] $processId) { $vsProcess = Get-Process devenv | Select-Object -First 1 if (!$vsProcess) {throw "Visual Studio is not running"} $vsMajorVersion = $vsProcess.FileVersion -replace '^(\d+).*', '$1' $dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("VisualStudio.DTE.$vsMajorVersion.0") $debugee = $dte.Debugger.LocalProcesses | ? {$_.ProcessID -eq $processId} if (!$debugee) {throw "Process with ID $processId does not exist."} $debugee.Attach() } )可以继续比较任一字符串中的空终止符。 只要其中一个字符串到达​​终止空字符,就需要立即停止它。
  2. 您的外部循环条件有一个错误。但是你无论如何都不需要while电话。只需迭代直到空字符。
  3. 您还可以将strlen移出循环以避免可能重新计算它。
  4. 更好的版本可能如下:

    strlen(substring)

答案 1 :(得分:1)

您的代码中存在一些问题:

  • 循环for (i = 0; i <= strlen(string);)每次迭代循环重新计算一次字符串的长度,并且迭代一次太远。你应该写:for (i = 0; string[i] != '\0';)

  • 第二个循环可能会超出string的末尾,并产生一个很大的count值:它将为第二个示例生成至少3个为null在所有情况下都会计算终止符。这就解释了为什么你得到不正确的匹配数。当您阅读超出两个字符串的末尾时,行为实际上是未定义的。

以下是更正后的版本:

int countSubstr(char string[], char substring[]) {
    int len = strlen(string);
    int sublen = strlen(substring);
    int i, j, count = 0;
    for (i = 0; i <= len - sublen; i++) {
        for (j = 0; j < sublen && string[i + j] == substring[j]; j++)
            continue;
        if (j == sublen)
            count++;
    }
    return count;
}

请注意,任何给定字符串中空字符串的出现次数将为1加上字符串的长度,这确实有意义。

另请注意,此代码会为countSubstr("bbb", "bb")返回2,这可能不是您所期望的。接受的答案返回1,这是有争议的。

答案 2 :(得分:1)

这适用于我测试的所有边缘情况

#include <stdio.h>

int countSubstr(char string[], char substring[])
{
    int count = 0;
    size_t i = 0;
    while(string[i])
    {
        int match = 1;
        size_t j = 0;
        while (substring[j])
        {
            match &= substring[j] == string[i + j];
            j++;
        }
        count += match;
        i++;
    }
    return count;
}

以下是一些测试用例:

void test(char name[], int expected, char string[], char substring[]){
    int actual = countSubstr(string, substring);
    char* status = (actual == expected)? "PASS" : "FAIL";
    printf("%s: %s\nActual: %d\nExpected: %d\n\n",name,status,actual,expected);
}

int main(void) {
    test("Two empty strings", 0, "", "");
    test("Empty substring", 19, "sub str sub str sub", "");
    test("Empty string", 0, "", "sub");
    test("Case 1", 4, "dbdbsnasdb dbdxx", "db");
    test("Case 2", 3, "dbdbsnasmfdb", "db");
    test("No match", 0, "dbdbsnasmfdb", "dxb");
    test("Inner matching", 3, "abababa", "aba");
    test("Identity test", 1, "a", "a");
    return 0;
}

答案 3 :(得分:0)

在你的while循环中,你还没有检查你是否超过了字符串长度。

编辑:
请记住,在C中,所有字符串都有一个&#39; \ 0&#39;最后但是在你的while循环中你不会检查它。

在我们得到的特定例子中(从最后一个db开始):
i = 10, j = 0, count = 1 (check for 'd')
i = 11, j = 1, count = 2 (check for 'b')
i = 12, j = 2, count = 3 (check for '\0')
i = 13, j = 3, count = 3 (exit loop)

count = 3与strlen(substring)== 2
不同 - &GT;子计划没有增加

答案 4 :(得分:-1)

for(i = 0; i&lt; = strlen(string);)

必须

for(i = 0; i&lt; strlen(string);)

使用两个代替一个非常复杂的循环,因为它更容易调试。