为什么我的程序总是跳过最后一个子字符串计数?
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循环中声明我的j
和count
为0
?是因为j
必须保持为0
(子串保持不变),只要它循环?
答案 0 :(得分:3)
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()
}
)可以继续比较任一字符串中的空终止符。
只要其中一个字符串到达终止空字符,就需要立即停止它。while
电话。只需迭代直到空字符。strlen
移出循环以避免可能重新计算它。更好的版本可能如下:
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);)
使用两个代替一个非常复杂的循环,因为它更容易调试。