📜  带加法序列的字符串

📅  最后修改于: 2021-04-29 11:54:38             🧑  作者: Mango

给定一个字符串,任务是查找它是否包含加法序列。如果字符串的数字可以组成一个数字序列,其中每个数字都是前两个数字的加法,则该字符串包含加法序列。一个有效的字符串应至少包含三位数以构成一个加法序列。

例子:

Input : s = “235813”
Output : true
2 + 3 = 5, 3 + 5 = 8, 5 + 8 = 13

Input : s = “199100199”
Output : true
1 + 99 = 100, 99 + 100 = 199

Input : s = “12345678”
Output : false

此问题可以递归解决,请注意,增加值中的位数不能小于其任何操作数中的位数,这就是为什么我们要循环直到第一个数字为( 字符串的长度)/ 2和( 字符串的长度为–第一个数字的长度)/第二个数字的2忽略无效结果。
接下来要注意的是,第一个和第二个数字不能以0开头,这是通过isValid方法在下面的代码中检查的。当我们递归调用时,我们检查第一个和第二个数字的总和是否完全等于字符串的其余部分。如果是,则直接返回其他结果检查和字符串字符串的其余部分的前缀或不是,如果是的话,然后用第二个数字,和字符串递归调用以及如果字符串和休息去除和字符串和字符串不是休息后的字符串其余字符串的前缀,则没有可用的解决方案。

下面是C++的实现。

// C++ program to check whether a string
// makes an additive sequence or not
#include 
using namespace std;
  
// Checks whether num is valid or not, by
// checking first character and size
bool isValid(string num)
{
    if (num.size() > 1 && num[0] == '0')
        return false;
    return true;
}
  
// returns int value at pos string, if pos is
// out of bound then returns 0
int val(string a, int pos)
{
    if (pos >= a.length())
        return 0;
  
    //  converting character to integer
    return (a[pos] - '0');
}
  
// add two number in string form and return
// result as a string
string addString(string a, string b)
{
    string sum = "";
    int i = a.length() - 1;
    int j = b.length() - 1;
    int carry = 0;
  
    //  loop untill both string get processed
    while (i >= 0 || j >= 0)
    {
        int t = val(a, i) + val(b, j) + carry;
        sum += (t % 10 + '0');
        carry = t / 10;
        i--;    j--;
    }
    if (carry)
        sum += (carry + '0');
    reverse(sum.begin(), sum.end());
    return sum;
}
  
//  Recursive method to check c = a + b
bool checkAddition(list& res, string a,
                             string b, string c)
{
    //  both first and second number should be valid
    if (!isValid(a) || !isValid(b))
        return false;
    string sum = addString(a, b);
  
    //  if sum is same as c then direct return
    if (sum == c)
    {
        res.push_back(sum);
        return true;
    }
  
    /*  if sum size is greater than c, then no
        possible sequence further OR if c is not
        prefix of sum string, then no possible
        sequence further  */
    if (c.size() <= sum.size() ||
        sum != c.substr(0, sum.size()))
        return false;
    else
    {
        res.push_back(sum);
          
        //  next recursive call will have b as first
        //  number, sum as second number and string
        //  c as third number after removing prefix
        //  sum string from c
        return checkAddition(res, b, sum,
                             c.substr(sum.size()));
    }
}
  
//  Method returns additive sequence from string as
// a list
list additiveSequence(string num)
{
    list res;
    int l = num.length();
  
    // loop untill l/2 only, because if first
    // number is larger,then no possible sequence
    // later
    for (int i = 1; i <= l/2; i++)
    {
        for (int j = 1; j <= (l - i)/2; j++)
        {
            if (checkAddition(res, num.substr(0, i),
                              num.substr(i, j),
                              num.substr(i + j)))
            {
                // adding first and second number at
                // front of result list
                res.push_front(num.substr(i, j));
                res.push_front(num.substr(0, i));
                return res;
            }
        }
    }
  
    // If code execution reaches here, then string
    // doesn't have any additive sequence
    res.clear();
    return res;
}
  
//  Method to print result list
void printResult(list res)
{
    for (auto it = res.begin(); it != res.end(); it++)
        cout << *it << " ";
    cout << endl;
}
  
//  Driver code to test above methods
int main()
{
    string num = "235813";
    list res = additiveSequence(num);
    printResult(res);
  
    num = "199100199";
    res = additiveSequence(num);
    printResult(res);
    return 0;
}

输出:

2 3 5 8 13 
1 99 100 199