📜  将给定数字分为多个主要部分的方法数量

📅  最后修改于: 2021-04-27 21:10:18             🧑  作者: Mango

给定数字字符串str ,任务是计算给定字符串可以分割的方式的数目,以使每个段都是质数。由于答案可能很大,因此请以10 9 + 7为模返回答案。
注意:包含前导零的数字的拆分将无效,并且初始字符串不包含前导零。
例子:

幼稚的方法:为了解决上述问题,幼稚的方法是使用递归。

  • 从给定字符串的结束索引开始递归,并考虑每个后缀最多6个数字(假设质数必须在[1,10 6 ]的范围内),并检查它是否为质数。
  • 如果后缀不包含前导零并且它是质数,则以递归方式调用该函数以计算剩余字符串的方式并加到总计数中。
  • 当索引达到0时,我们到达基本情况并返回1,以将当前拆分视为有效计数。
  • 在每次迭代中获取计数的mod并在最后返回计数。

下面是上述方法的实现:

C++
// C++ implementation to count total
// number of ways to split a
// string to get prime numbers
 
#include 
using namespace std;
#define MOD 1000000007
 
// Function to check whether a number
// is a prime number or not
bool isPrime(string number)
{
    int num = stoi(number);
    for (int i = 2; i * i <= num; i++)
        if ((num % i) == 0)
            return false;
    return num > 1 ? true : false;
}
 
// Function to find the count
// of ways to split string
// into prime numbers
int countPrimeStrings(
    string& number, int i)
{
 
    // 1 based indexing
    if (i == 0)
        return 1;
    int cnt = 0;
 
    // Consider every suffix up to 6 digits
    for (int j = 1; j <= 6; j++) {
 
        // Number should not have
        // a leading zero and
        // it should be a prime number
        if (i - j >= 0
            && number[i - j] != '0'
            && isPrime(
                   number.substr(i - j, j))) {
            cnt
                += countPrimeStrings(
                    number,
                    i - j);
 
            cnt %= MOD;
        }
    }
 
    // Return the final result
    return cnt;
}
 
// Driver code
int main()
{
    string s1 = "3175";
 
    int l = s1.length();
    cout << countPrimeStrings(s1, l);
 
    return 0;
}


Java
// Java implementation to count total
// number of ways to split a string
// to get prime numbers
import java.util.*;
 
class GFG{
     
static final int MOD =1000000007;
 
// Function to check whether a number
// is a prime number or not
static boolean isPrime(String number)
{
    int num = Integer.valueOf(number);
     
    for(int i = 2; i * i <= num; i++)
    {
       if ((num % i) == 0)
           return false;
    }
    return num > 1 ? true : false;
}
 
// Function to find the count
// of ways to split String
// into prime numbers
static int countPrimeStrings(String number,
                                     int i)
{
 
    // 1 based indexing
    if (i == 0)
        return 1;
         
    int cnt = 0;
 
    // Consider every suffix up to 6 digits
    for(int j = 1; j <= 6; j++)
    {
        
       // Number should not have
       // a leading zero and it
       // should be a prime number
       if (i - j >= 0 &&
           number.charAt(i - j) != '0' &&
           isPrime(number.substring(i - j, i)))
       {
           cnt += countPrimeStrings(number,
                                    i - j);
           cnt %= MOD;
       }
    }
     
    // Return the final result
    return cnt;
}
 
// Driver code
public static void main(String[] args)
{
    String s1 = "3175";
    int l = s1.length();
     
    System.out.print(countPrimeStrings(s1, l));
}
}
 
// This code is contributed by sapnasingh4991


Python3
# Python3 implementation to
# count total number of ways
# to split a string to get
# prime numbers
MOD = 1000000007
 
# Function to check whether
# a number is a prime number
# or not
def isPrime(number):
 
    num = int(number)
    i = 2
     
    while i * i <= num:
        if ((num % i) == 0):
            return False
        i += 1
         
    if num > 1:
      return True
    else:
      return False
 
# Function to find the count
# of ways to split string
# into prime numbers
def countPrimeStrings(number, i):
 
    # 1 based indexing
    if (i == 0):
        return 1
    cnt = 0
 
    # Consider every suffix
    # up to 6 digits
    for j in range(1, 7):
 
        # Number should not have
        # a leading zero and
        # it should be a prime number
        if (i - j >= 0 and
            number[i - j] != '0' and
            isPrime(number[i - j : i])):
            cnt += countPrimeStrings(number,
                                     i - j)
            cnt %= MOD
         
    # Return the final result
    return cnt
 
# Driver code
if __name__ == "__main__":
   
    s1 = "3175"
    l = len(s1)
    print (countPrimeStrings(s1, l))
 
# This code is contributed by Chitranayal


C#
// C# implementation to count total
// number of ways to split a string
// to get prime numbers
using System;
class GFG{
     
static readonly int MOD =1000000007;
 
// Function to check whether a number
// is a prime number or not
static bool isPrime(String number)
{
    int num = Int32.Parse(number);
     
    for(int i = 2; i * i <= num; i++)
    {
        if ((num % i) == 0)
            return false;
    }
    return num > 1 ? true : false;
}
 
// Function to find the count
// of ways to split String
// into prime numbers
static int countPrimeStrings(String number,
                                     int i)
{
 
    // 1 based indexing
    if (i == 0)
        return 1;
         
    int cnt = 0;
 
    // Consider every suffix up to 6 digits
    for(int j = 1; j <= 6; j++)
    {
         
        // Number should not have
        // a leading zero and it
        // should be a prime number
        if (i - j >= 0 &&
            number[i - j] != '0' &&
            isPrime(number.Substring(i - j, j)))
        {
            cnt += countPrimeStrings(number,
                                     i - j);
            cnt %= MOD;
        }
    }
     
    // Return the readonly result
    return cnt;
}
 
// Driver code
public static void Main(String[] args)
{
    String s1 = "3175";
    int l = s1.Length;
     
    Console.Write(countPrimeStrings(s1, l));
}
}
 
// This code is contributed by sapnasingh4991


C++
// C++ implementation to count total
// number of ways to split a
// string to get prime numbers
 
#include 
using namespace std;
const int MOD = 1000000007;
bool sieve[1000000];
 
// Function to build sieve
void buildSieve()
{
    for (auto& i : sieve)
        i = true;
 
    sieve[0] = false;
    sieve[1] = false;
 
    for (int p = 2; p * p <= 1000000;
         p++) {
 
        // If p is a prime
        if (sieve[p] == true) {
 
            // Update all multiples
            // of p as non prime
 
            for (int i = p * p; i <= 1000000;
                 i += p)
                sieve[i] = false;
        }
    }
}
 
// Function to check whether a number
// is a prime number or not
bool isPrime(string number)
{
    int num = stoi(number);
    return sieve[num];
}
 
// Function to find the count
// of ways to split string
// into prime numbers
int rec(string& number, int i,
        vector& dp)
{
    if (dp[i] != -1)
        return dp[i];
 
    int cnt = 0;
 
    for (int j = 1; j <= 6; j++) {
 
        // Number should not have a
        // leading zero and it
        // should be a prime number
        if (i - j >= 0
            && number[i - j] != '0'
            && isPrime(
                   number.substr(i - j, j))) {
 
            cnt += rec(
                number, i - j, dp);
            cnt %= MOD;
        }
    }
    return dp[i] = cnt;
}
 
// Function to count the
// number of prime strings
int countPrimeStrings(string& number)
{
    int n = number.length();
    vector dp(n + 1, -1);
    dp[0] = 1;
    return rec(number, n, dp);
}
 
// Driver code
int main()
{
    buildSieve();
 
    string s1 = "3175";
 
    cout << countPrimeStrings(s1) << "\n";
 
    return 0;
}


Java
// Java implementation to count total
// number of ways to split a String
// to get prime numbers
import java.util.*;
 
class GFG{
     
static int MOD = 1000000007;
static boolean []sieve = new boolean[1000000];
 
// Function to build sieve
static void buildSieve()
{
    Arrays.fill(sieve, true);
 
    sieve[0] = false;
    sieve[1] = false;
 
    for(int p = 2; p * p <= 1000000; p++)
    {
 
       // If p is a prime
       if (sieve[p] == true)
       {
 
           // Update all multiples
           // of p as non prime
           for(int i = p * p; i < 1000000;
                   i += p)
              sieve[i] = false;
       }
    }
}
 
// Function to check whether a number
// is a prime number or not
static boolean isPrime(String number)
{
    int num = Integer.valueOf(number);
    return sieve[num];
}
 
// Function to find the count
// of ways to split String
// into prime numbers
static int rec(String number, int i,
                              int []dp)
{
    if (dp[i] != -1)
        return dp[i];
    int cnt = 0;
 
    for(int j = 1; j <= 6; j++)
    {
        
       // Number should not have a
       // leading zero and it
       // should be a prime number
       if (i - j >= 0 &&
           number.charAt(i - j) != '0' &&
           isPrime(number.substring(i - j, i)))
       {
           cnt += rec(number, i - j, dp);
           cnt %= MOD;
       }
    }
    return dp[i] = cnt;
}
 
// Function to count the
// number of prime Strings
static int countPrimeStrings(String number)
{
    int n = number.length();
    int []dp = new int[n + 1];
     
    Arrays.fill(dp, -1);
    dp[0] = 1;
 
    return rec(number, n, dp);
}
 
// Driver code
public static void main(String[] args)
{
    buildSieve();
 
    String s1 = "3175";
 
    System.out.print(countPrimeStrings(s1) + "\n");
}
}
 
// This code is contributed by 29AjayKumar


C#
// C# implementation to count total
// number of ways to split a String
// to get prime numbers
using System;
 
class GFG{
     
static int MOD = 1000000007;
static bool []sieve = new bool[1000000];
 
// Function to build sieve
static void buildSieve()
{
    for(int j = 0; j < sieve.Length; j++)
       sieve[j] = true;
 
    sieve[0] = false;
    sieve[1] = false;
 
    for(int p = 2; p * p <= 1000000; p++)
    {
        
       // If p is a prime
       if (sieve[p] == true)
       {
            
           // Update all multiples
           // of p as non prime
           for(int i = p * p; i < 1000000;
                   i += p)
              sieve[i] = false;
       }
    }
}
 
// Function to check whether a number
// is a prime number or not
static bool isPrime(String number)
{
    int num = Int32.Parse(number);
    return sieve[num];
}
 
// Function to find the count
// of ways to split String
// into prime numbers
static int rec(String number, int i,
                              int []dp)
{
    if (dp[i] != -1)
        return dp[i];
    int cnt = 0;
 
    for(int j = 1; j <= 6; j++)
    {
        
       // Number should not have a
       // leading zero and it
       // should be a prime number
       if (i - j >= 0 &&
           number[i - j] != '0' &&
           isPrime(number.Substring(i - j, j)))
       {
           cnt += rec(number, i - j, dp);
           cnt %= MOD;
       }
    }
    return dp[i] = cnt;
}
 
// Function to count the
// number of prime Strings
static int countPrimeStrings(String number)
{
    int n = number.Length;
    int []dp = new int[n + 1];
     
    for(int j = 0; j < dp.Length; j++)
       dp[j] = -1;
    dp[0] = 1;
 
    return rec(number, n, dp);
}
 
// Driver code
public static void Main(String[] args)
{
    buildSieve();
 
    String s1 = "3175";
 
    Console.Write(countPrimeStrings(s1) + "\n");
}
}
 
// This code is contributed by 29AjayKumar


输出:
3


时间复杂度: O(N 2 )
辅助空间: O(N)
高效方法:优化上述方法的主要思想是使用记忆技术来降低上述递归解决方案的时间复杂度。让我们考虑一个dp []表,该表存储在每个索引dp [i]上,这是分割字符串str的前i个数字的方式。通过使用Eratosthenes筛网,可以进一步降低检查数字是否为质数的复杂度。
下面是上述方法的实现:

C++

// C++ implementation to count total
// number of ways to split a
// string to get prime numbers
 
#include 
using namespace std;
const int MOD = 1000000007;
bool sieve[1000000];
 
// Function to build sieve
void buildSieve()
{
    for (auto& i : sieve)
        i = true;
 
    sieve[0] = false;
    sieve[1] = false;
 
    for (int p = 2; p * p <= 1000000;
         p++) {
 
        // If p is a prime
        if (sieve[p] == true) {
 
            // Update all multiples
            // of p as non prime
 
            for (int i = p * p; i <= 1000000;
                 i += p)
                sieve[i] = false;
        }
    }
}
 
// Function to check whether a number
// is a prime number or not
bool isPrime(string number)
{
    int num = stoi(number);
    return sieve[num];
}
 
// Function to find the count
// of ways to split string
// into prime numbers
int rec(string& number, int i,
        vector& dp)
{
    if (dp[i] != -1)
        return dp[i];
 
    int cnt = 0;
 
    for (int j = 1; j <= 6; j++) {
 
        // Number should not have a
        // leading zero and it
        // should be a prime number
        if (i - j >= 0
            && number[i - j] != '0'
            && isPrime(
                   number.substr(i - j, j))) {
 
            cnt += rec(
                number, i - j, dp);
            cnt %= MOD;
        }
    }
    return dp[i] = cnt;
}
 
// Function to count the
// number of prime strings
int countPrimeStrings(string& number)
{
    int n = number.length();
    vector dp(n + 1, -1);
    dp[0] = 1;
    return rec(number, n, dp);
}
 
// Driver code
int main()
{
    buildSieve();
 
    string s1 = "3175";
 
    cout << countPrimeStrings(s1) << "\n";
 
    return 0;
}

Java

// Java implementation to count total
// number of ways to split a String
// to get prime numbers
import java.util.*;
 
class GFG{
     
static int MOD = 1000000007;
static boolean []sieve = new boolean[1000000];
 
// Function to build sieve
static void buildSieve()
{
    Arrays.fill(sieve, true);
 
    sieve[0] = false;
    sieve[1] = false;
 
    for(int p = 2; p * p <= 1000000; p++)
    {
 
       // If p is a prime
       if (sieve[p] == true)
       {
 
           // Update all multiples
           // of p as non prime
           for(int i = p * p; i < 1000000;
                   i += p)
              sieve[i] = false;
       }
    }
}
 
// Function to check whether a number
// is a prime number or not
static boolean isPrime(String number)
{
    int num = Integer.valueOf(number);
    return sieve[num];
}
 
// Function to find the count
// of ways to split String
// into prime numbers
static int rec(String number, int i,
                              int []dp)
{
    if (dp[i] != -1)
        return dp[i];
    int cnt = 0;
 
    for(int j = 1; j <= 6; j++)
    {
        
       // Number should not have a
       // leading zero and it
       // should be a prime number
       if (i - j >= 0 &&
           number.charAt(i - j) != '0' &&
           isPrime(number.substring(i - j, i)))
       {
           cnt += rec(number, i - j, dp);
           cnt %= MOD;
       }
    }
    return dp[i] = cnt;
}
 
// Function to count the
// number of prime Strings
static int countPrimeStrings(String number)
{
    int n = number.length();
    int []dp = new int[n + 1];
     
    Arrays.fill(dp, -1);
    dp[0] = 1;
 
    return rec(number, n, dp);
}
 
// Driver code
public static void main(String[] args)
{
    buildSieve();
 
    String s1 = "3175";
 
    System.out.print(countPrimeStrings(s1) + "\n");
}
}
 
// This code is contributed by 29AjayKumar

C#

// C# implementation to count total
// number of ways to split a String
// to get prime numbers
using System;
 
class GFG{
     
static int MOD = 1000000007;
static bool []sieve = new bool[1000000];
 
// Function to build sieve
static void buildSieve()
{
    for(int j = 0; j < sieve.Length; j++)
       sieve[j] = true;
 
    sieve[0] = false;
    sieve[1] = false;
 
    for(int p = 2; p * p <= 1000000; p++)
    {
        
       // If p is a prime
       if (sieve[p] == true)
       {
            
           // Update all multiples
           // of p as non prime
           for(int i = p * p; i < 1000000;
                   i += p)
              sieve[i] = false;
       }
    }
}
 
// Function to check whether a number
// is a prime number or not
static bool isPrime(String number)
{
    int num = Int32.Parse(number);
    return sieve[num];
}
 
// Function to find the count
// of ways to split String
// into prime numbers
static int rec(String number, int i,
                              int []dp)
{
    if (dp[i] != -1)
        return dp[i];
    int cnt = 0;
 
    for(int j = 1; j <= 6; j++)
    {
        
       // Number should not have a
       // leading zero and it
       // should be a prime number
       if (i - j >= 0 &&
           number[i - j] != '0' &&
           isPrime(number.Substring(i - j, j)))
       {
           cnt += rec(number, i - j, dp);
           cnt %= MOD;
       }
    }
    return dp[i] = cnt;
}
 
// Function to count the
// number of prime Strings
static int countPrimeStrings(String number)
{
    int n = number.Length;
    int []dp = new int[n + 1];
     
    for(int j = 0; j < dp.Length; j++)
       dp[j] = -1;
    dp[0] = 1;
 
    return rec(number, n, dp);
}
 
// Driver code
public static void Main(String[] args)
{
    buildSieve();
 
    String s1 = "3175";
 
    Console.Write(countPrimeStrings(s1) + "\n");
}
}
 
// This code is contributed by 29AjayKumar
输出:
3


时间复杂度: O(N + N * log(log(N)))
辅助空间: O(N)