Given numeric string str, the task is to count the number of ways the given string can be split, such that each segment is a prime number. Since the answer can be large, return the answer modulo 109 + 7.
Note: A split that contains numbers with leading zeroes will be invalid and the initial string does not contain leading zeroes.
Examples:
Input: str = “3175”
Output: 3
Explanation:
There are 3 ways to split this string into prime numbers which are (31, 7, 5), (3, 17, 5), (317, 5).
Input: str = “11373”
Output: 6
Explanation:
There are 6 ways to split this string into prime numbers which are (11, 3, 7, 3), (113, 7, 3), (11, 37, 3), (11, 3, 73), (113, 73) and (11, 373).
Naive Approach: To solve the problem mentioned above, the naive method is to use Recursion.
- Start recursing from the ending index of the given string and consider every suffix up to 6 digits (given that the prime number must be in the range of [1, 106)] and check if it is a prime number or not.
- If the suffix doesn’t contain a leading zero and it is a prime number, then recursively call the function to count the ways for the remaining string and add to the total count.
- When the index reaches 0, we reach the base case and return 1 to consider current splits as a valid count.
- Take mod of the count at each iteration and return the count at the end.
Below is the implementation above approach:
C++
// C++ implementation to count total // number of ways to split a // string to get prime numbers #include <bits/stdc++.h> 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 |
3
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The optimize the above method the main idea is to use memoization technique to reduce the time complexity of the recursion solution discussed above. Let us consider a dp[] table which stores at every index dp[i], the ways to split the first i digits of the string str. The complexity to check if a number is prime or not can be further reduced by using Sieve of Eratosthenes.
Below is the implementation of the above approach:
C++
// C++ implementation to count total // number of ways to split a // string to get prime numbers #include <bits/stdc++.h> 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< 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.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< int > 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
Time Complexity: O(N + N*log(log(N)))
Auxiliary Space: O(N)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.