繁体   English   中英

字符串的所有可能的子字符串,最多包含6500个字符

[英]All possible substrings of a string having up to 6500 characters

所以我在codeforces.com上解决了另一个问题,称为Even Substrings( https://codeforces.com/contest/1139/problem/A )。 以下是问题的要点:

用户首先输入n,即数字位数,然后输入一串n位数字。 我们需要输出其子串中有多少是偶数。 例如,考虑字符串“123”。 子串“2”和“12”是偶数而其余的不是(即“1”,“123”,“23”,“3”),输出将是2。

我尝试实现一个非常简单的方法。 一次一个,我尝试每个可能的子串(使用std :: string.substr()),然后将其转换为整数(使用std :: stoi())并检查它是否是偶数。 如果是,我将计数器加1。 问题是,当我输入一个像9572683145这样的大数字时,VS2019会调用abort()。在我看来,std :: stoi()就是这样做的。 所以我尝试通过尝试不同的方法完全消除这个因素。

所以在我的第二种方法中,第一步是相同的。 我尝试从字符串中的每个可能的子字符串然后检查每个子字符串中的最后一个元素是0,2,4,6还是8.如果是,我将计数增加1。 这种方法可以解决像9572683145这样的输入,但是其中一个测试有n = 65000,最终是一个非常大的数字并且尝试每个可能的子串似乎都不切实际,因为判断返回“超出时间限制”。

两次尝试的代码如下所示:

//Attempt 1
#include<iostream>
#include<string>

int main()
{
    int n;
    std::cin >> n;
    std::string s;
    std::cin >> s;

    int count = 0;

    for (int i = 0; i < s.length(); i++)
    {
        for (int j = 1; j <= n; j++)
        {
            std::string sub = s.substr(i, j);
            int num = std::stoi(sub);
            if (num % 2 == 0)
            {
                count++;
            }
        }
        n--;
    }

    std::cout << count;
}

//Attempt 2
#include<iostream>
#include<string>

int main()
{
    int n;
    std::cin >> n;
    std::string s;
    std::cin >> s;

    int count = 0;

    for (int i = 0; i < s.length(); i++)
    {
        for (int j = 1; j <= n; j++)
        {
            std::string sub = s.substr(i, j);
            if (sub[sub.length() - 1] == '0' || sub[sub.length() - 1] == '2' || sub[sub.length() - 1] == '4' || sub[sub.length() - 1] == '6' || sub[sub.length() - 1] == '8')
            {
                count++;
            }
        }
        n--;
    }

    std::cout << count;
}

在查看输入之后,我意识到std :: stoi方法将无法工作,因为没有整数可以存储多达10 ^ 65(可能是long或long int或long long int)。 在任何情况下,这都无关紧要,除非我能找到一种更有效的方法来测试子串,而不是我在这里。

任何意见或建议都是最受欢迎的。 非常感谢您的帮助和支持!

嗯,回答我自己的问题很尴尬,但我想我可能应该,考虑到我找到了一个解决方案(感谢评论家伙,如果没有你的意见,就无法想出来)。 解决方案背后有两个简单的想法:

1)如果字符串的第i个元素是偶数,那么以该元素结尾的每个子字符串也将是偶数。

2)对于第i个元素,有i + 1个子串,其中第i个元素作为它们的最后一个元素。

例如:考虑输入1234.第一个索引是偶数,因此向我们显示2个子串甚至在它之前(“2”和“12”)然后第3个索引是偶数所以4个子串甚至在它之前(“4 “,”34“,”234“和”1234“)。 所以总的偶数子串将是2 + 4,这给我们6。

将这两个想法放在一起,就可以消除创建子串的需要,并将整个过程简化为重复添加。 这是代码:

#include<iostream>
#include<string>

int main()
{
    int n;
    std::cin >> n;
    std::string s;
    std::cin >> s;

    int count = 0;

    for (int i = 0; i < n; i++)
    {
        if ((s[i] - '0') % 2 == 0)
        {
            count += (i + 1);
        }
    }


    std::cout << count;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM