📌  相关文章
📜  将给定的字符串拆分为赔率:Digit DP

📅  最后修改于: 2021-09-22 10:17:44             🧑  作者: Mango

先决条件:数字DP
给定代表一个大数的字符串str ,任务是找到给定字符串可以划分的最小段数,使得每个段都是1 到 10 9范围内的奇数。
例子:

方法:思路是借助digit-dp的概念,使用动态规划来解决这个问题。因此,定义了splitDP[]数组,其中 splitDP[i] 表示长度为 ‘i’ 的前缀字符串中将其分成奇数细分所需的最小分割数。
splitDP[] 数组的填充方式如下:

  • 循环用于遍历给定字符串 的所有索引。
  • 对于上述循环中的每个索引“i”,另一个循环从 1 到 9 进行迭代,以检查第 (i + j) 个索引中的子字符串是否为奇数。
  • 如果它形成一个奇数,则 splitDP[] 处的值更新为:
    splitDP[i + j] = min(splitDP[i + j], 1 + splitDP[i]);
  • 更新完数组的所有值后,最后一个索引处的值是整个字符串的最小分割数。

下面是上述方法的实现:

C++
// C++ program to split the given string into odds
#include 
using namespace std;
  
// Function to check whether a string
// is an odd number or not
bool checkOdd(string number)
{
    int n = number.length();
  
    int num = number[n - 1] - '0';
  
    return (num & 1);
}
  
// A function to find the minimum
// number of segments the given string
// can be divided such that every
// segment is a odd number
int splitIntoOdds(string number)
{
    int numLen = number.length();
  
    // Declare a splitdp[] array
    // and initialize to -1
    int splitDP[numLen + 1];
    memset(splitDP, -1, sizeof(splitDP));
  
    // Build the DP table in
    // a bottom-up manner
    for (int i = 1; i <= numLen; i++) {
  
        // Initially Check if the entire prefix is odd
        if (i <= 9 && checkOdd(number.substr(0, i)))
            splitDP[i] = 1;
  
        // If the Given Prefix can be split into Odds
        // then for the remaining string from i to j
        // Check if Odd. If yes calculate
        // the minimum split till j
        if (splitDP[i] != -1) {
            for (int j = 1; j <= 9
                            && i + j <= numLen;
                 j++) {
  
                // To check if the substring from i to j
                // is a odd number or not
                if (checkOdd(number.substr(i, j))) {
  
                    // If it is an odd number,
                    // then update the dp array
                    if (splitDP[i + j] == -1)
                        splitDP[i + j] = 1 + splitDP[i];
  
                    else
                        splitDP[i + j] = min(splitDP[i + j],
                                             1 + splitDP[i]);
                }
            }
        }
    }
  
    // Return the minimum number of splits
    // for the entire string
    return splitDP[numLen];
}
  
// Driver code
int main()
{
    cout << splitIntoOdds("123456789123456789123") << "\n";
    return 0;
}


Java
// Java program to split the given string into odds 
class GFG {
  
    // Function to check whether a string 
    // is an odd number or not 
    static int checkOdd(String number) 
    { 
        int n = number.length(); 
      
        int num = number.charAt(n - 1) - '0'; 
      
        return (num & 1); 
    } 
  
    // A function to find the minimum 
    // number of segments the given string 
    // can be divided such that every 
    // segment is a odd number 
    static int splitIntoOdds(String number) 
    { 
        int numLen = number.length(); 
      
        // Declare a splitdp[] array 
        // and initialize to -1 
        int splitDP[] = new int[numLen + 1]; 
          
        for(int i= 0; i < numLen + 1; i++)
            splitDP[i] = -1;
              
        // Build the DP table in 
        // a bottom-up manner 
        for (int i = 1; i <= numLen; i++) { 
      
            // Initially Check if the entire prefix is odd 
            if (i <= 9 && (checkOdd(number.substring(0, i)) == 1)) 
                splitDP[i] = 1; 
      
            // If the Given Prefix can be split into Odds 
            // then for the remaining string from i to j 
            // Check if Odd. If yes calculate 
            // the minimum split till j 
            if (splitDP[i] != -1) { 
                for (int j = 1; j <= 9 
                                && i + j <= numLen; 
                    j++) { 
      
                    // To check if the substring from i to j 
                    // is a odd number or not 
                    if (checkOdd(number.substring(i, i + j)) == 1) { 
      
                        // If it is an odd number, 
                        // then update the dp array 
                        if (splitDP[i + j] == -1) 
                            splitDP[i + j] = 1 + splitDP[i]; 
      
                        else
                            splitDP[i + j] = Math.min(splitDP[i + j], 
                                                1 + splitDP[i]); 
                    } 
                } 
            } 
        } 
      
        // Return the minimum number of splits 
        // for the entire string 
        return splitDP[numLen]; 
    } 
      
    // Driver code 
    public static void main (String[] args)
    { 
        System.out.println(splitIntoOdds("123456789123456789123")); 
    } 
}
  
// This code is contributed by AnkitRai01


Python3
# Python3 program to split the given string into odds 
  
# Function to check whether a string 
# is an odd number or not 
def checkOdd(number):
    n = len(number)
    num = ord(number[n - 1]) - 48
    return (num & 1)
  
# A function to find the minimum 
# number of segments the given string 
# can be divided such that every 
# segment is a odd number 
def splitIntoOdds(number): 
    numLen = len(number)
      
    # Declare a splitdp[] array 
    # and initialize to -1 
    splitDP = [-1 for i in range(numLen + 1)] 
  
    # Build the DP table in 
    # a bottom-up manner 
    for i in range(1, numLen + 1): 
  
        # Initially Check if the entire prefix is odd 
        if (i <= 9 and checkOdd(number[0:i]) > 0): 
            splitDP[i] = 1
  
        # If the Given Prefix can be split into Odds 
        # then for the remaining string from i to j 
        # Check if Odd. If yes calculate 
        # the minimum split till j 
        if (splitDP[i] != -1):
            for j in range(1, 10):
                if(i + j > numLen):
                    break;
  
                # To check if the substring from i to j 
                # is a odd number or not 
                if (checkOdd(number[i:i + j])):
                      
                    # If it is an odd number, 
                    # then update the dp array 
                    if (splitDP[i + j] == -1):
                        splitDP[i + j] = 1 + splitDP[i] 
                    else:
                        splitDP[i + j] = min(splitDP[i + j], 1 + splitDP[i])
  
    # Return the minimum number of splits 
    # for the entire string 
    return splitDP[numLen]
  
# Driver code 
print(splitIntoOdds("123456789123456789123"))
  
# This code is contributed by Sanjit_Prasad


C#
// C# program to split the given string into odds 
using System;
  
class GFG { 
  
    // Function to check whether a string 
    // is an odd number or not 
    static int checkOdd(string number) 
    { 
        int n = number.Length; 
      
        int num = number[n - 1] - '0'; 
      
        return (num & 1); 
    } 
  
    // A function to find the minimum 
    // number of segments the given string 
    // can be divided such that every 
    // segment is a odd number 
    static int splitIntoOdds(string number) 
    { 
        int numLen = number.Length; 
      
        // Declare a splitdp[] array 
        // and initialize to -1 
        int []splitDP = new int[numLen + 1]; 
          
        for(int i= 0; i < numLen + 1; i++) 
            splitDP[i] = -1; 
              
        // Build the DP table in 
        // a bottom-up manner 
        for (int i = 1; i <= numLen; i++) { 
      
            // Initially Check if the entire prefix is odd 
            if (i <= 9 && (checkOdd(number.Substring(0, i)) == 1)) 
                splitDP[i] = 1; 
      
            // If the Given Prefix can be split into Odds 
            // then for the remaining string from i to j 
            // Check if Odd. If yes calculate 
            // the minimum split till j 
            if (splitDP[i] != -1) { 
                for (int j = 1; j <= 9
                                && i + j <= numLen; 
                    j++) { 
      
                    // To check if the substring from i to j 
                    // is a odd number or not 
                    if (checkOdd(number.Substring(i, j)) == 1) { 
      
                        // If it is an odd number, 
                        // then update the dp array 
                        if (splitDP[i + j] == -1) 
                            splitDP[i + j] = 1 + splitDP[i]; 
      
                        else
                            splitDP[i + j] = Math.Min(splitDP[i + j], 
                                                1 + splitDP[i]); 
                    } 
                } 
            } 
        } 
      
        // Return the minimum number of splits 
        // for the entire string 
        return splitDP[numLen]; 
    } 
      
    // Driver code 
    public static void Main (string[] args) 
    { 
        Console.WriteLine(splitIntoOdds("123456789123456789123")); 
    } 
} 
  
// This code is contributed by AnkitRai01


Javascript


输出:
3

时间复杂度: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程