手撕题4——拆分

本文介绍了一种用于计算给定字符串中ABA型子串数量的算法,特别关注于子串长度及内部结构的限制条件。通过实例解析,详细说明了如何利用C++实现这一算法,包括字符串操作和条件判断的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
给定长度为n的串S,仅包含小写字母。定义
在这里插入图片描述
公式中,|A|代表字符串A的长度
也就是说如果子串是一个ABA型的字符串,且满足长度限制,则f(l,r)=1,否则等于0。(注意:形如“ababab”也可视为ABA型)
在这里插入图片描述
例如当n=2时,原式为f(1,1)+f(1,2)+f(2,2)。

输入
第一行一个字符串S
第二行一个数字k
输出
输出题目描述中式子的值

样例输入
abcabcabc
2
样例输出
8
提示
1<=n<=2000 , S[i]为小写字母

样例解释:
在这个字符串中,有f(1,5),f(1,8),f(1,9),f(2,6),f(2,9),f(3,7),f(4,8),f(5,9)的值为1,其他为0,故和为8。以f(1,5)为例,选择的子串是abcab,令A=“ab”,B=“c”,则|A|>=k且|B|>=1,因此f(1,5)等于1,以此类推。

分析:
OK,重新整理一下,把例子理一遍,其实就是一个变上下线的加和式子:
在这里插入图片描述
样例中的A>=2,B>=1意思就是这个字符串就是ABA式的,其中A和B可能代表长度不一的字符串。

代码:

#include <iostream>
#include <string>
using namespace std;

int f(string s, int l, int r, int k)
{
    string subs = s.substr(l-1,r-l+1);	//从l开始截取r-l+1个
    auto len = subs.size();//子串长度
    for (int i=k; i<=len/2; i++)//这里s[0~k]就相当于A
	{
		//让|A|从k开始增加
        string s1 = subs.substr(0,i);//子串的前一部分(从0开始截i个)
        string s2 = subs.substr(len-i,i);//子串的后一部分(从len-i开始截i个)
        if ((s1 == s2) && (i!=len-i))//若前后相等且为ABA格式则返回1
		{
			//判断最前和最后的部分是否相同
            //cout<<subs<<endl;
            //printf("\n");
            return 1;
        }
    }

    return 0;
}
int main()
{
    string s;
	int k;
    cin >> s;
	cin >> k;
    auto n = s.size();
    int i, j, res = 0;
    for (i=1; i<=n; i++)
	{
        for (j=i; j<=n; j++)
		{
            res = res + f(s,i,j,k);
        }
    }
    cout << res << endl;
    return 0;
}

笔记:

  1. 定义字符串时注意
    int a[100] = {};定义时数组不能这样初始化;
    int a[100] = {0};这个写法意味着a[0]=0;
  2. substr(pos = 0, count);
    参数:
    pos,所需的子字符串的起始位置。字符串中第一个字符的索引为 0,默认值为0;
    count:要截取的子串的长度;
    返回值:一个子字符串,从其指定的位置开始。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值