6-3 用指针统计字符出现次数 (10分)/pta

函数接口定义:

int StringCount(char *p, char ch);

题目要求统计在字符串中字符ch出现的次数,并将其次数返回主函数输出。题目保证字符串长度不超过80字符。

裁判测试程序样例:

#include <stdio.h>

int StringCount(char *p, char ch);

int main(void)
{

  char  str[81], ch;

	ch=getchar();
	getchar();
	gets(str);

  printf("%d", StringCount(str, ch));

  return 0;

}

/* 请在这里填写答案 */

输入样例:

c
abcdefjh

输出样例:

1

答案:

int StringCount(char *p, char ch)
{
    int count = 0;
    while (*p){
        if (*p == ch){
            count++;
            
        }
        p++;
    }
    return count;
}
改进后的 KMP 算法在字符串模式匹配成功时,字符比较次数具有一定的规律性,可以通过算法的运行机制进行析。 KMP 算法的核心思想是通过预处理模式串,构建一个 `next` 数组(也称为部匹配表),从而在匹配失败时快速调整模式串的位置,避免重复比较主串中的字符。这使得 KMP 算法的时间复杂度为 $ O(n + m) $,其中 $ n $ 是主串长度,$ m $ 是模式串长度。这种特性使得算法在匹配成功时,字符比较次数的规律性更加明显 [^3]。 ### 1. 比较次数的上限 在匹配成功的情况下,KMP 算法中主串字符的比较次数不会超过 $ 2n $ 次。这是因为在 KMP 算法中,主串的指针 $ i $ 总是向前移动,而模式串的指针 $ j $ 可能回退到某个位置继续比较。即使在最坏情况下,主串中的每个字符最多会被比较两次:一次是匹配成功,另一次是匹配失败后通过 `next` 数组调整位置 [^4]。 ### 2. `next` 数组的影响 KMP 算法通过 `next` 数组来指导模式串的滑动,从而减少不必要的字符比较。当模式匹配成功时,`next` 数组决定了模式串的滑动距离。模式串中存在较多重复子串的模式,其 `next` 数组值较大,匹配过程中滑动距离更短,字符比较次数相对较多;而模式串中重复子串较少的模式,其 `next` 数组值较小,滑动距离更长,字符比较次数相对较少 [^5]。 例如,模式串 `ababc` 的 `next` 数组为 `[0, 0, 1, 2, 3]`,匹配成功时,滑动距离较短,字符比较次数较多。而模式串 `abcd` 的 `next` 数组为 `[0, 0, 0, 0]`,滑动距离较长,字符比较次数较少 [^4]。 ### 3. 匹配成功时的比较次数 在模式匹配成功的情况下,KMP 算法的字符比较次数与模式串的长度 $ m $ 直接相关。具体来说,匹配成功时,字符比较次数至少为 $ m $ 次(即模式串的所有字符都与主串的字符匹配)。此外,由于 `next` 数组的存在,可能还会增加一些额外的比较次数,具体取决于模式串的结构和匹配过程中的滑动情况 [^2]。 ### 4. 实验析 通过实验可以验证 KMP 算法在匹配成功时的字符比较次数规律。例如,主串为 `s = "abababaabab"`,模式串为 `t = "abab"`,匹配成功时,字符比较次数为 8 次。而模式串为 `t = "abcd"` 时,匹配成功时,字符比较次数为 4 次。这表明,模式串的结构对字符比较次数有直接影响 [^1]。 综上所述,改进后的 KMP 算法在模式匹配成功时,字符比较次数的规律性主要体现在以下几点: - 比较次数的上限为 $ 2n $ 次。 - 比较次数与模式串的 `next` 数组密切相关。 - 匹配成功时,比较次数至少为模式串的长度 $ m $ 次。 ```python # KMP 算法实现 def compute_next_array(pattern): m = len(pattern) next_array = [0] * m length = 0 # length of the previous longest prefix suffix i = 1 while i < m: if pattern[i] == pattern[length]: length += 1 next_array[i] = length i += 1 else: if length != 0: length = next_array[length - 1] else: next_array[i] = 0 i += 1 return next_array def kmp_search(text, pattern): n = len(text) m = len(pattern) next_array = compute_next_array(pattern) i = 0 # index for text j = 0 # index for pattern comparisons = 0 # 字符比较次数 while i < n: if pattern[j] == text[i]: i += 1 j += 1 comparisons += 1 if j == m: print(f"Pattern found at index {i - j}") j = next_array[j - 1] elif i < n and pattern[j] != text[i]: if j != 0: j = next_array[j - 1] else: i += 1 comparisons += 1 return comparisons # 示例测试 text = "abababaabab" pattern = "abab" comparisons = kmp_search(text, pattern) print(f"Character comparisons: {comparisons}") ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值