📜  将数字字符串拆分为斐波纳契数列

📅  最后修改于: 2021-05-04 23:23:47             🧑  作者: Mango

给定表示大数的数字字符串S ,任务是从给定字符串形成长度至少为3的斐波那契数列。如果无法进行这样的分割,请打印-1。

例子:

方法:
为了解决这个问题,我们的想法是使用回溯来找到遵循斐波那契数列条件的序列

请按照以下步骤解决问题:

  1. 初始化向量seq []以存储斐波那契序列
  2. 初始化变量pos ,该变量pos指向字符串S的当前索引,初始为0
  3. 遍历索引[pos,length – 1]
    • 添加的数量S [POS:I]至Fibonacci序列SEQ如果SEQ的长度小于2或当前数目等于SEQ的最后两个数字的总和。为索引i +1递归并继续。
    • 如果最后添加的数字S [pos: i]没有形成斐波那契数列,并且在递归后返回false ,则将其从seq中删除
    • 否则,结束循环并在形成斐波那契数列时返回true。
  4. 如果pos超过S的长度,则:
    • 如果序列seq的长度大于或等于3 ,则找到斐波那契序列,因此返回true
    • 否则,斐波那契数列是不可能的,因此返回false
  5. 最后,如果seq的长度大于或等于3,则将seq中的数字打印为所需的斐波那契数列,否则打印-1

下面是递归结构的说明,其中仅扩展了一个分支即可得到结果:

下面是上述方法的实现:

C++
// C++ program of the above approach
#include 
using namespace std;
 
#define LL long long
 
// Function that returns true if
// Fibonacci sequence is found
bool splitIntoFibonacciHelper(int pos,
                              string S,
                              vector& seq)
{
    // Base condition:
    // If pos is equal to length of S
    // and seq length is greater than 3
    if (pos == S.length()
        and (seq.size() >= 3)) {
 
        // Return true
        return true;
    }
 
    // Stores current number
    LL num = 0;
 
    for (int i = pos; i < S.length(); i++) {
 
        // Add current digit to num
        num = num * 10 + (S[i] - '0');
 
        // Avoid integer overflow
        if (num > INT_MAX)
            break;
 
        // Avoid leading zeros
        if (S[pos] == '0' and i > pos)
            break;
 
        // If current number is greater
        // than last two number of seq
        if (seq.size() > 2
            and (num > ((LL)seq.back()
                        + (LL)seq[seq.size()
                                  - 2])))
            break;
 
        // If seq length is less
        // 2 or current number is
        // is equal to the last
        // two of the seq
        if (seq.size() < 2
            or (num == ((LL)seq.back()
                        + (LL)seq[seq.size()
                                  - 2]))) {
 
            // Add to the seq
            seq.push_back(num);
 
            // Recur for i+1
            if (splitIntoFibonacciHelper(i + 1,
                                         S, seq))
                return true;
 
            // Remove last added number
            seq.pop_back();
        }
    }
 
    // If no sequence is found
    return false;
}
 
// Function that prints the Fibonacci
// sequence from the split of string S
void splitIntoFibonacci(string S)
{
    // Initialize a vector to
    // store the sequence
    vector seq;
 
    // Call helper function
    splitIntoFibonacciHelper(0, S,
                             seq);
 
    // If sequence length is
    // greater than 3
    if (seq.size() >= 3) {
 
        // Print the sequence
        for (int i : seq)
            cout << i << " ";
    }
 
    // If no sequence is found
    else {
 
        // Print -1
        cout << -1;
    }
}
 
// Driver Code
int main()
{
    // Given String
    string S = "11235813";
 
    // Function Call
    splitIntoFibonacci(S);
    return 0;
}


Java
// Java program of the above approach
import java.util.*;
 
class GFG{
 
// Function that returns true if
// Fibonacci sequence is found
static boolean splitIntoFibonacciHelper(int pos,
                                        String S,
                              ArrayList seq)
{
     
    // Base condition:
    // If pos is equal to length of S
    // and seq length is greater than 3
    if (pos == S.length() && (seq.size() >= 3))
    {
 
        // Return true
        return true;
    }
 
    // Stores current number
    long num = 0;
 
    for(int i = pos; i < S.length(); i++)
    {
         
        // Add current digit to num
        num = num * 10 + (S.charAt(i) - '0');
 
        // Avoid integer overflow
        if (num > Integer.MAX_VALUE)
            break;
 
        // Avoid leading zeros
        if (S.charAt(pos) == '0' && i > pos)
            break;
 
        // If current number is greater
        // than last two number of seq
        if (seq.size() > 2 &&
           (num > ((long)seq.get(seq.size() - 1) +
                   (long)seq.get(seq.size() - 2))))
            break;
 
        // If seq length is less
        // 2 or current number is
        // is equal to the last
        // two of the seq
        if (seq.size() < 2 ||
            (num == ((long)seq.get(seq.size() - 1) +
                     (long)seq.get(seq.size() - 2))))
        {
             
            // Add to the seq
            seq.add(num);
 
            // Recur for i+1
            if (splitIntoFibonacciHelper(i + 1,
                                         S, seq))
                return true;
 
            // Remove last added number
            seq.remove(seq.size() - 1);
        }
    }
     
    // If no sequence is found
    return false;
}
 
// Function that prints the Fibonacci
// sequence from the split of string S
static void splitIntoFibonacci(String S)
{
     
    // Initialize a vector to
    // store the sequence
    ArrayList seq = new ArrayList<>();
 
    // Call helper function
    splitIntoFibonacciHelper(0, S, seq);
 
    // If sequence length is
    // greater than 3
    if (seq.size() >= 3)
    {
         
        // Print the sequence
        for (int i = 0; i < seq.size(); i++)
            System.out.print(seq.get(i) + " ");
    }
 
    // If no sequence is found
    else
    {
 
        // Print -1
        System.out.print("-1");
    }
}
 
// Driver code
public static void main(String[] args)
{
     
    // Given String
    String S = "11235813";
     
    // Function Call
    splitIntoFibonacci(S);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program of the above approach
import sys
 
# Function that returns true if
# Fibonacci sequence is found
def splitIntoFibonacciHelper(pos, S, seq):
 
    # Base condition:
    # If pos is equal to length of S
    # and seq length is greater than 3
    if (pos == len(S) and (len(seq) >= 3)):
  
        # Return true
        return True
  
    # Stores current number
    num = 0
     
    for i in range(pos, len(S)):
  
        # Add current digit to num
        num = num * 10 + (ord(S[i]) - ord('0'))
  
        # Avoid integer overflow
        if (num > sys.maxsize):
            break
  
        # Avoid leading zeros
        if (ord(S[pos]) == ord('0') and i > pos):
            break
  
        # If current number is greater
        # than last two number of seq
        if (len(seq) > 2 and
                (num > (seq[-1] +
                        seq[len(seq) - 2]))):
            break
  
        # If seq length is less
        # 2 or current number is
        # is equal to the last
        # two of the seq
        if (len(seq) < 2 or
           (num == (seq[-1] +
                    seq[len(seq) - 2]))):
  
            # Add to the seq
            seq.append(num)
  
            # Recur for i+1
            if (splitIntoFibonacciHelper(
                i + 1, S, seq)):
                return True
  
            # Remove last added number
            seq.pop()
  
    # If no sequence is found
    return False
 
# Function that prints the Fibonacci
# sequence from the split of string S
def splitIntoFibonacci(S):
     
    # Initialize a vector to
    # store the sequence
    seq = []
  
    # Call helper function
    splitIntoFibonacciHelper(0, S, seq)
  
    # If sequence length is
    # greater than 3
    if (len(seq) >= 3):
  
        # Print the sequence
        for i in seq:
            print(i, end = ' ')
             
    # If no sequence is found
    else:
  
        # Print -1
        print(-1, end = '')
         
# Driver Code
if __name__=='__main__':
     
    # Given String
    S = "11235813"
  
    # Function Call
    splitIntoFibonacci(S)
 
# This code is contributed by pratham76


C#
// C# program of the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
     
// Function that returns true if
// Fibonacci sequence is found
static bool splitIntoFibonacciHelper(int pos,
                                     string S,
                                ArrayList seq)
{
     
    // Base condition:
    // If pos is equal to length of S
    // and seq length is greater than 3
    if (pos == S.Length && (seq.Count >= 3))
    {
 
        // Return true
        return true;
    }
 
    // Stores current number
    long num = 0;
 
    for(int i = pos; i < S.Length; i++)
    {
         
        // Add current digit to num
        num = num * 10 + (S[i] - '0');
 
        // Avoid integer overflow
        if (num > Int64.MaxValue)
            break;
     
        // Avoid leading zeros
        if (S[pos] == '0' && i > pos)
            break;
 
        // If current number is greater
        // than last two number of seq
        if (seq.Count> 2 &&
           (num > ((long)seq[seq.Count - 1] +
                   (long)seq[seq.Count - 2])))
            break;
 
        // If seq length is less
        // 2 or current number is
        // is equal to the last
        // two of the seq
        if (seq.Count < 2 ||
           (num == ((long)seq[seq.Count - 1] +
                    (long)seq[seq.Count - 2])))
        {
             
            // Add to the seq
            seq.Add(num);
 
            // Recur for i+1
            if (splitIntoFibonacciHelper(i + 1,
                                         S, seq))
                return true;
 
            // Remove last added number
            seq.Remove(seq.Count - 1);
        }
    }
     
    // If no sequence is found
    return false;
}
 
// Function that prints the Fibonacci
// sequence from the split of string S
static void splitIntoFibonacci(string S)
{
     
    // Initialize a vector to
    // store the sequence
    ArrayList seq = new ArrayList();
 
    // Call helper function
    splitIntoFibonacciHelper(0, S, seq);
 
    // If sequence length is
    // greater than 3
    if (seq.Count >= 3)
    {
         
        // Print the sequence
        for(int i = 0; i < seq.Count; i++)
            Console.Write(seq[i] + " ");
    }
 
    // If no sequence is found
    else
    {
         
        // Print -1
        Console.Write("-1");
    }
}
 
// Driver Code
public static void Main(string[] args)
{
     
    // Given String
    string S = "11235813";
     
    // Function call
    splitIntoFibonacci(S);
}
}
 
// This code is contributed by rutvik_56


输出:
1 1 2 3 5 8 13

时间复杂度: O(N 2 )
空间复杂度: O(N)