📜  将给定数字分成素数段的方法数

📅  最后修改于: 2021-09-22 09:59:42             🧑  作者: Mango

给定数字字符串str ,任务是计算给定字符串可以被分割的方式的数量,这样每个部分都是一个质数。由于答案可能很大,返回模10 9 + 7的答案。
注意:包含带有前导零的数字的拆分将无效,并且初始字符串不包含前导零。
例子:

朴素的方法:为了解决上面提到的问题,朴素的方法是使用递归。

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

以下是上述方法的实现:

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


Javascript


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


Javascript


输出:

3

时间复杂度: O(N 2 )
辅助空间: O(N)
Efficient Approach:优化上述方法的主要思想是使用memoization技术来降低上面讨论的递归解决方案的时间复杂度。让我们考虑一个dp[]表,它存储在每个索引dp[i] 处,拆分字符串str的前i 个数字的方法。使用埃拉托色尼筛法可以进一步降低检查一个数是否为素数的复杂性。
下面是上述方法的实现:

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

Javascript


输出:
3

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