当前位置: 首页 > article >正文

最长的指定瑕疵度的元音子串

一、题目

最长的指定瑕疵度的元音子串
定义:开头和结尾都是元音字母(aeiouAEIOU)的字符串为 元音字符串 ,其中混杂的非元音字母数量为其 瑕疵度 。比如:
“a” 、 "aa"是元音字符串,其瑕疵度都为0
"aiur"不是元音字符串(结尾不是元音字符)
"abira"是元音字符串,其瑕疵度为2
给定一个字符串str和瑕疵度flaw,请找出瑕疵度等于 flaw 的最长元音字符子串,并输出其长度,如果找不到满足条件的元音字符子串,输出0。
子串:字符串中任意个连续的字符组成的子序列称为该字符串的子串。

输入
首行输入一个整数 flaw,取值范围 [0, 65535]。
接下来一行是字符串str,仅由字符a-z和A-Z组成,字符串长度 (0, 65535]。
输出
输出为一个整数,代表满足条件的元音字符子串的长度。

样例1
复制输入:
0
“asdbuiodevauufgh”
复制输出:
3
解释:
满足条件的最长元音字符子串有两个,分别为uio和auu,长度为3。

样例2
复制输入:
2
“aeueo”
复制输出:
0
解释:
没有满足条件的元音字符子串,输出0

样例3
复制输入:
1
“aabeebuu”
复制输出:
5
解释:
满足条件的最长元音字符子串有两个,分别为aabee和eebuu,长度为5

二、解题

代码一

static int GetFlawLength(const char* str, int slow, int fast)
{
    int len = 0;
    for (int i = slow; i <= fast; i++) {
        char c = tolower(str[i]);
        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
            continue;
        } else {
            len++;
        }
    }
    return len;
}

static int GetLongestFlawedVowelSubstrLen(int flaw, const char* str)
{
    int max = 0;
    int len = strlen(str);
    int slow = 0;
    int fast = slow;
    while (fast < len) {
        int flawLen = GetFlawLength(str, slow, fast);
        if (flawLen == flaw) {
            max = max > fast - slow ? max : fast - slow + 1;
            fast++;
        } else if (flawLen < flaw) {
            fast++;
        } else if (flawLen > flaw) {
            if (slow == fast) {
                fast++;
            }
            slow++;
        }
    }
    return max;
}

上述代码可以通过题目3个用例,下面的用例执行失败

1
"ab"
// 预期输出
0
// 实际输出
2

经过调试发现是因为判断是否是元音子串还有个条件是结尾的字符的是元音字符,增加对这个条件的判断。修改代码如下

static bool IsTargetCharacter(char c)
{
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
        return true;
    }
    return false;
}

static int GetFlawLength(const char* str, int slow, int fast)
{
    int len = 0;
    for (int i = slow; i <= fast; i++) {
        char c = tolower(str[i]);
        if (IsTargetCharacter(c)) {
            continue;
        } else {
            len++;
        }
    }
    return len;
}

static int GetLongestFlawedVowelSubstrLen(int flaw, const char* str)
{
    int max = 0;
    int len = strlen(str);
    int slow = 0;
    int fast = slow;
    while (fast < len) {
        int flawLen = GetFlawLength(str, slow, fast);
        if (flawLen == flaw) {
            if(fast < len && IsTargetCharacter(str[fast])) {
                max = max > fast - slow ? max : fast - slow + 1;
            }
            fast++;
        } else if (flawLen < flaw) {
            fast++;
        } else if (flawLen > flaw) {
            if (slow == fast) {
                fast++;
            }
            slow++;
        }
    }
    return max;
}

可以通过上述实例,但是下述用例无法通过

0
"NA"
// 预期输出
1
// 实际输出
0

经过调试发现代码有点小问题

将IsTargetCharacter函数修改如下:

static bool IsTargetCharacter(char tempC)
{
    char c = tolower(tempC);
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
        return true;
    }
    return false;
}

可以通过上述用例,但是下面的测试用例失败

3
"asdbuiodevauufghA"
// 预期输出
7
// 实际输出10

经过调试发现是元音子串还需要满足第一个字符是元音字符,在GetLongestFlawedVowelSubstrLen函数增加此条件,修改GetLongestFlawedVowelSubstrLen函数代码如下

static int GetLongestFlawedVowelSubstrLen(int flaw, const char* str)
{
    int max = 0;
    int len = strlen(str);
    int slow = 0;
    int fast = slow;
    while (fast < len) {
        int flawLen = GetFlawLength(str, slow, fast);
        if (flawLen == flaw) {
            if (fast < len && IsTargetCharacter(str[fast]) && IsTargetCharacter(str[slow])) {
                max = max > fast - slow ? max : fast - slow + 1;
            }
            fast++;
        } else if (flawLen < flaw) {
            fast++;
        } else if (flawLen > flaw) {
            if (slow == fast) {
                fast++;
            }
            slow++;
        }
    }
    return max;
}

上述代码通过通过上述用例,但是执行一个特别长的字符串报错"CPU资源占用过高"

检查代码,需要确定是哪里的代码占用资源过高。经过判断是因为GetLongestFlawedVowelSubstrLen函数中的这条语句

int flawLen = GetFlawLength(str, slow, fast);

这段代码等于是fast指针每加一次,都要对slow和fast之间的字符串进行遍历计数。这样时间复杂度就能达到O(n2),对这行代码进行修改,看了之前的代码,是对瑕疵字符进行同步计数的,所以优化方向就是取消对字符串的重复多次计数。

修改代码后,程序果然可以执行通过,看到耗时的代码就是GetFlawLength函数。

Aced代码

static bool IsTargetCharacter(char tempC)
{
    char c = tolower(tempC);
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
        return true;
    }
    return false;
}

static int GetLongestFlawedVowelSubstrLen(int flaw, const char* str)
{
    int max = 0;
    int len = strlen(str);
    int slow = 0;
    int fast = slow;
    int flawLength = 0;
    while (fast < len) {
        //int flawLen = GetFlawLength(str, slow, fast);
        if (flawLength == flaw) {
            if (fast < len && IsTargetCharacter(str[fast]) && IsTargetCharacter(str[slow])) {
                max = max > fast - slow ? max : fast - slow + 1;
            }
            if (!IsTargetCharacter(str[fast])) {
                flawLength++;
            }
            fast++;
        } else if (flawLength < flaw) {
            if (!IsTargetCharacter(str[fast])) {
                flawLength++;
            }
            fast++;
        } else if (flawLength > flaw) {
            if (slow == fast) {
                if (!IsTargetCharacter(str[fast])) {
                    flawLength++;
                }
                fast++;
            }
            if (!IsTargetCharacter(str[slow])) {
                flawLength--;
            }
            slow++;
        }
    }
    return max;
}

之前的Aced代码

#include <stdio.h>
#include "securec.h"
#include "stdbool.h"

#define MAX_LEN 65536

_Bool isTargetCharacter(char* c)
{
    int copy = tolower(c);
    if(copy == 'a' || copy == 'e' || copy == 'i' || copy == 'o' || copy == 'u')
    {
        return true;
    }
    
    return false;
}

int getFlaw(char* str, int l, int r)
{
    int flawCount = 0;
    for(int i = l; i < r; i++)
    {
        if(!isTargetCharacter(str[i]))
        {
            flawCount++;
        }
    }
    
    //printf("flawCount:%d\n", flawCount);
    return flawCount;
}

int getCount(int flaw, char* str)
{
    int maxCount = 0;
    int length = 0;
    int len = strlen(str);
    int l = 0, r = 0;
    while(r < len)
    {
        if(!isTargetCharacter(str[r]))
        {
            length++;
        }
        
        while(length > flaw)
        {
            if(!isTargetCharacter(str[l]))
            {
                length--;
            }
            l++;
        }
        
        if(flaw == length)
        {
            if(isTargetCharacter(str[l]) && isTargetCharacter(str[r]))
            {
                int count = r - l + 1;
                maxCount = maxCount > count ? maxCount : count;
            }
        }
        
        r++;
    }
    
    return maxCount;
}

//1
//asdbuiodevauufghA
//例子不符
int getCount4(int flaw, char* str)
{
    int maxCount = 0;
    int length = 0;
    int len = strlen(str);
    int l = 0, r = 0;
    while(r < len)
    {
        int realFlaw = getFlaw(str, l, r);
        
        while(l <= r)
        {
            if(flaw == getFlaw(str, l, r) && isTargetCharacter(str[l]))
            {
                break;
            }
            l++;
        }
        
        if(flaw == realFlaw)
        {
            if(isTargetCharacter(str[l]) && isTargetCharacter(str[r]))
            {
                int count = r - l + 1;
                maxCount = maxCount > count ? maxCount : count;
            }
        }
        
        r++;
    }
    
    return maxCount;
}

//
//0
//a
//例子不符
int getCount3(int flaw, char* str)
{
    int maxCount = 0;
    int length = 0;
    int len = strlen(str);
    int l = 0, r = 1;
    while(r < len)
    {
        int realFlaw = getFlaw(str, l, r);
        
        while(l < r)
        {
            if(flaw == realFlaw)
            {
                break;
            }
            l++;
        }
        
        if(flaw == realFlaw)
        {
            if(isTargetCharacter(str[l]) && isTargetCharacter(str[r]))
            {
                int count = r - l + 1;
                maxCount = maxCount > count ? maxCount : count;
            }
        }
        
        r++;
    }
    
    return maxCount;
}

int getCount2(int flaw, char* str)
{
    int maxCount = 0;
    int length = 0;
    int len = strlen(str);
    int l = 0, r = 1;
    while(l < r && r < len)
    {
        if(isTargetCharacter(str[r]))
        {
            printf("r:%d", r);
            while(l < r)
            {
                if(isTargetCharacter(str[l]))
                {
                    printf("l:%d", l);
                    if(flaw == getFlaw(str, l, r))
                    {
                        int count = r - l + 1;
                        maxCount = maxCount > count ? maxCount : count;
                    }
                    else if(flaw < getFlaw(str, l, r))
                    {
                        l++;
                    }
                    else if(flaw > getFlaw(str, l, r))
                    {
                        r++;
                    }
                }
                else
                {
                    l++;
                }
            }
        }
        else
        {
            r++;
        }
    }
    
    return maxCount;
}

int GetLongestFlawedVowelSubstrLen(int flaw, char* str)      
{                     
   // 添加你的代码
    int count = 0;
    count = getCount(flaw, str);
    
    return count;
}                     

int main(void) 
{ 
    int flaw = 0;  
    if (scanf_s("%d\n", &flaw) != 1) { return -1; }   
    char str[MAX_LEN];   
    if (NULL == gets_s(str, sizeof(str))) { return -1; }   
    int result = GetLongestFlawedVowelSubstrLen(flaw, str);
    (void)printf("%d", result); 
    return 0;           

这版代码应该是我参考别人答案写的吧。


http://www.kler.cn/a/488711.html

相关文章:

  • 深入浅出负载均衡:理解其原理并选择最适合你的实现方式
  • Linux:深入了解fd文件描述符
  • leetcode 面试经典 150 题:两数之和
  • 在Jmeter中跨线程组传递变量(token)--设置全局变量
  • 【MySQL系列文章】Linux环境下安装部署MySQL
  • FPGA的 基本结构(Xilinx 公司Virtex-II 系列FPGA )
  • linux centos挂载未分配的磁盘空间
  • Linux 下信号的保存和处理
  • Python 的医疗问句中的实体识别算法的研究(Flask)
  • SpringCloud微服务架构高可用设计方案
  • 自动驾驶领域的基础模型综述
  • 学习HLS.js
  • 高级java每日一道面试题-2025年01月08日-微服务篇-负载平衡的意义什么 ?
  • 2025-1-10-sklearn学习(36、37) 数据集转换-无监督降维+随机投影 沙上并禽池上暝。云破月来花弄影。
  • 二手母婴商品交易系统|Java|SSM|VUE| 前后端分离
  • JSON.stringify 实现深度克隆的缺陷
  • 《庐山派K230 从入熟悉到...》按键拍照保存
  • 牛客周赛74
  • Wireshark TCP 分析标志位说明汇总
  • 【Golang 面试题】每日 3 题(二十六)
  • MiniMind - 从0训练语言模型
  • 蓝桥杯python省赛备战day2--连续求和公式应用--829连续整数求和-枚举算法刷题学习笔记2--leetcode
  • ue5 动画通知
  • JavaScript 数组拓展:方法与实例全解析
  • 安科瑞 Acrel-1000DP 分布式光伏监控系统在工业厂房分布式光伏发电项目中的应用
  • 微信小程序评分小程序ssm+论文源码调试讲解