📜  将数字转换为质数段所需的最小分割

📅  最后修改于: 2021-05-04 13:34:42             🧑  作者: Mango

给定字符串s形式的数字,任务是计算并显示所需的最小分割,以使形成的线段为Prime或print不可能

例子:

方法:
此问题是矩阵链乘法的一种变体,可以使用动态编程解决。

递归尝试所有可能的拆分,并在每个拆分中检查形成的段是否为质数。考虑一个二维数组dp ,其中dp [i] [j]显示从索引i到j的最小分割,并返回dp [0] [n],其中n是字符串的长度。

复发:

dp[i][j] = min(1 + solve(i, k) + solve(k + 1, j)) where i <= k <= j

实际上,在上面写的确切重复中,左段和右段都不都是素数,则1 + INT_MAX + INT_MAX将为负数,这将导致错误的答案。
因此,需要分别计算段和段。如果发现任何部分不是主要部分,则无需进一步进行操作。否则返回min(1 + left + right)

考虑的基本情况是:

  • 如果数字是素数,则返回0
  • 如果i == j并且数字为质数,则返回0
  • 如果i == j并且数字不是素数,则返回INT_MAX

下面的代码是上述方法的实现:

C++
#include 
using namespace std;
  
int dp[1000][1000] = { 0 };
  
// Checking for prime
bool isprime(long long num)
{
    if (num <= 1)
        return false;
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}
// Conversion of string to int
long long convert(string s, int i, int j)
{
    long long temp = 0;
    for (int k = i; k <= j; k++) {
        temp = temp * 10 + (s[k] - '0');
    }
    return temp;
}
// Function to get the minimum splits
int solve(string s, int i, int j)
{
    // Convert the segment to integer or long long
    long long num = convert(s, i, j);
    // Number is prime
    if (isprime(num)) {
        return 0;
    }
    // If a single digit is prime
    if (i == j && isprime(num))
        return 0;
  
    // If single digit is not prime
    if (i == j && isprime(num) == false)
        return INT_MAX;
  
    if (dp[i][j])
        return dp[i][j];
  
    int ans = INT_MAX;
    for (int k = i; k < j; k++) {
        // Recur for left segment
        int left = solve(s, i, k);
        if (left == INT_MAX) {
            continue;
        } 
  
        // Recur for right segment
        int right = solve(s, k + 1, j);
        if (right == INT_MAX) {
            continue;
        }
        // Minimum from left and right segment
        ans = min(ans, 1 + left + right);
    }
    return dp[i][j] = ans;
}
int main()
{
  
    string s = "2352";
    int n = s.length();
  
    int cuts = solve(s, 0, n - 1);
    if (cuts != INT_MAX) {
        cout << cuts;
    }
    else {
        cout << "Not Possible";
    }
}


Java
import java.util.*; 
  
class GFG 
{
  
    static int dp[][] = new int[1000][1000];
  
    // Checking for prime
    static boolean isprime(long num){
        int i;
        if (num <= 1)
            return false;
        for (i = 2; i * i <= num; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }
  
    // Conversion of string to int
    static long convert(String s, int i, int j)
    {
        long temp = 0;
        int k;
        for (k = i; k <= j; k++) {
            temp = temp * 10 + (s.charAt(k) - '0');
        }
        return temp;
    }
  
    // Function to get the minimum splits
    static int solve(String s, int i, int j)
    {
        int k;
  
        // Convert the segment to integer or long long
        long num = convert(s, i, j);
  
        // Number is prime
        if (isprime(num)) {
            return 0;
        }
  
        // If a single digit is prime
        if (i == j && isprime(num))
            return 0;
      
        // If single digit is not prime
        if (i == j && isprime(num) == false)
            return Integer.MAX_VALUE;
      
        if (dp[i][j] != 0)
            return dp[i][j];
      
        int ans = Integer.MAX_VALUE;
        for (k = i; k < j; k++) {
  
            // Recur for left segment
            int left = solve(s, i, k);
            if (left == Integer.MAX_VALUE) {
                continue;
            } 
      
            // Recur for right segment
            int right = solve(s, k + 1, j);
            if (right == Integer.MAX_VALUE) {
                continue;
            }
  
            // Minimum from left and right segment
            ans = Math.min(ans, 1 + left + right);
        }
        return dp[i][j] = ans;
    }
      
    public static void main (String []args)
    {
      
        String s = "2352";
        int n = s.length();
      
        int cuts = solve(s, 0, n - 1);
        if (cuts != Integer.MAX_VALUE) {
            System.out.print(cuts);
        }
        else {
            System.out.print("Not Possible");
        }
    } 
}
  
// This code is contributed by chitranayal


Python3
# Python3 Implementation of the above approach
import numpy as np;
import sys
  
dp = np.zeros((1000,1000)) ; 
  
INT_MAX = sys.maxsize;
  
# Checking for prime 
def isprime(num) : 
  
    if (num <= 1) :
        return False; 
    for i in range(2, int(num ** (1/2)) + 1) :
        if (num % i == 0) :
            return False; 
    return True; 
  
# Conversion of string to int 
def convert(s, i, j) : 
  
    temp = 0; 
    for k in range(i, j + 1) : 
        temp = temp * 10 + (ord(s[k]) - ord('0')); 
  
    return temp; 
  
# Function to get the minimum splits 
def solve(s, i, j) : 
  
    # Convert the segment to integer or long long 
    num = convert(s, i, j); 
    # Number is prime 
    if (isprime(num)) :
        return 0; 
  
    # If a single digit is prime 
    if (i == j and isprime(num)) :
        return 0; 
  
    # If single digit is not prime 
    if (i == j and isprime(num) == False) :
        return INT_MAX; 
  
    if (dp[i][j]) :
        return dp[i][j]; 
  
    ans = INT_MAX; 
      
    for k in range(i, j) : 
        # Recur for left segment 
        left = solve(s, i, k); 
        if (left == INT_MAX) :
            continue; 
  
        # Recur for right segment 
        right = solve(s, k + 1, j); 
        if (right == INT_MAX) :
            continue; 
      
        # Minimum from left and right segment 
        ans = min(ans, 1 + left + right); 
      
    dp[i][j] = ans; 
      
    return ans;
  
# Driver code    
if __name__ == "__main__" : 
  
    s = "2352"; 
    n = len(s); 
  
    cuts = solve(s, 0, n - 1); 
    if (cuts != INT_MAX) :
        print(cuts); 
      
    else :
        print("Not Possible"); 
  
# This code is converted by Yash_R


C#
using System;
  
class GFG 
{
   
    static int [,]dp = new int[1000,1000];
   
    // Checking for prime
    static bool isprime(long num){
        int i;
        if (num <= 1)
            return false;
        for (i = 2; i * i <= num; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }
   
    // Conversion of string to int
    static long convert(String s, int i, int j)
    {
        long temp = 0;
        int k;
        for (k = i; k <= j; k++) {
            temp = temp * 10 + (s[k] - '0');
        }
        return temp;
    }
   
    // Function to get the minimum splits
    static int solve(String s, int i, int j)
    {
        int k;
   
        // Convert the segment to integer or long long
        long num = convert(s, i, j);
   
        // Number is prime
        if (isprime(num)) {
            return 0;
        }
   
        // If a single digit is prime
        if (i == j && isprime(num))
            return 0;
       
        // If single digit is not prime
        if (i == j && isprime(num) == false)
            return int.MaxValue;
       
        if (dp[i,j] != 0)
            return dp[i, j];
       
        int ans = int.MaxValue;
        for (k = i; k < j; k++) {
   
            // Recur for left segment
            int left = solve(s, i, k);
            if (left == int.MaxValue) {
                continue;
            } 
       
            // Recur for right segment
            int right = solve(s, k + 1, j);
            if (right == int.MaxValue) {
                continue;
            }
   
            // Minimum from left and right segment
            ans = Math.Min(ans, 1 + left + right);
        }
        return dp[i,j] = ans;
    }
       
    public static void Main(String []args)
    {
       
        String s = "2352";
        int n = s.Length;
       
        int cuts = solve(s, 0, n - 1);
        if (cuts != int.MaxValue) {
            Console.Write(cuts);
        }
        else {
            Console.Write("Not Possible");
        }
    } 
}
  
// This code is contributed by PrinciRaj1992


输出:
2