📜  C测验– 108 |问题5(1)

📅  最后修改于: 2023-12-03 14:40:26.266000             🧑  作者: Mango

C测验– 108 | 问题5
问题描述

问题5要求你实现一个函数,接受一个字符串作为参数,并返回一个整数值,该整数值表示字符串中非空子字符串的数量。

函数签名
int countSubstrings(char *s);
输入
  • 字符串s是一个非空字符串,长度不超过1000。
输出
  • 返回一个整数,表示非空子字符串的数量。
示例
输入:s = "abc"
输出:6
解释:非空子字符串包括 "a"、"b"、"c"、"ab"、"bc" 和 "abc"。

输入:s = "aaa"
输出:6
解释:非空子字符串包括 "a"、"a"、"a"、"aa"、"aa" 和 "aaa"。
解法

要解决该问题,可以使用动态规划的思想。

  • 初始化计数器count为0,表示当前的子字符串数量。
  • 创建一个布尔类型的二维数组dp,其中dp[i][j]表示字符串s[i...j]是否为回文子字符串。
  • 遍历字符串s,每遍历到一个字符s[i],都将dp[i][i]设置为true,同时增加计数器count
  • 遍历字符串s的所有子字符串长度len,从2开始。对于每个长度为len的子字符串s[i...j],如果s[i]等于s[j]并且dp[i+1][j-1]是回文字符串,则将dp[i][j]设置为true,同时增加计数器count
  • 最后返回计数器count即可。

以下是使用C代码实现上述解法的程序:

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

int countSubstrings(char *s) {
    int n = strlen(s);
    int count = 0;
    bool dp[n][n];
  
    // 遍历字符串,初始化dp数组并添加计数
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            dp[i][j] = false;
        }
    }
  
    for (int i = 0; i < n; i++) {
        dp[i][i] = true;
        count++;
    }
  
    // 计算回文子字符串数量
    for (int len = 2; len <= n; len++) {
        for (int i = 0; i <= n - len; i++) {
            int j = i + len - 1;
            if (s[i] == s[j]) {
                if (len == 2 || dp[i + 1][j - 1]) {
                    dp[i][j] = true;
                    count++;
                }
            }
        }
    }
  
    return count;
}

int main() {
    char s[] = "abc";
    int result = countSubstrings(s);
    printf("%d\n", result); // 输出: 6
  
    return 0;
}

该解法的时间复杂度为O(n^2),其中n是字符串s的长度。