字符串中所有可能的子字符串(最多6500个字符)

时间:2019-04-21 15:00:40

标签: c++ string substring

因此,我在codeforces.com上解决了另一个问题,即偶数子串(https://codeforces.com/contest/1139/problem/A)。这是问题的要点:

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

我尝试实现一种非常简单的方法。一次,我尝试所有可能的子字符串(使用std :: string.substr()),然后将其转换为整数(使用std :: stoi()),并检查其是否为偶数。如果是,我将计数器增加一。问题是当我输入像9572683145这样的大数字时,VS2019会调用abort()。在我看来,好像std :: stoi()引起了这一问题。因此,我尝试通过尝试其他方法完全消除该因素。

因此,在第二种方法中,第一步是相同的。我尝试使用字符串中的每个可能的子字符串,然后检查每个子字符串中的最后一个元素是否为0、2、4、6或8。如果是,则将计数增加一。这种方法可以解决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 个答案:

答案 0 :(得分:0)

好吧,这很尴尬地回答了我自己的问题,但是考虑到我找到了一个解决方案,我想我应该应该这样做(感谢大家的意见,没有您的输入就无法弄清楚)。解决方案背后有两个简单的想法:

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

2)对于第i个元素,有i + 1个子字符串,其中第i个元素是最后一个元素。

例如:考虑输入1234。第一个索引为偶数,因此向我们显示2个子字符串在其之前为偶数(“ 2”和“ 12”),然后第三个索引为偶数,因此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;
}