如何计算给定字符串可以分割为质数的方式的数量?

时间:2019-12-19 10:14:18

标签: python data-structures

我有一个下面提到的问题,用于将字符串拆分为多种显示质数的方式的组合。但是我不确定如何开始编码。无法开始任何逻辑。

  

给出由数字[0-9]组成的长度为n的字符串,计算   给定字符串可以分割为质数的方式数,每种   其中范围为2到100(含2和100)。由于答案可以是   大,以109 + 7为模返回答案。注意:   包含前导零的数字将无效,并且初始   字符串不包含前导零。以输入为例   字符串为s =“ 11373”,则此字符串可以拆分为6   不同的方式,例如[11、37、3),[113、7、3),[11、3、73),[11、37、3),   (113,73)和[11,373)其中每个仅包含质数   数字。

     

用于自定义测试的输入格式
  第一行也是唯一一行包含字符串s。

样本案例0

  

样本输入

     

用于自定义测试
  3175

     

样本输出说明
  将字符串拆分为质数的3种方法是(31,7,5),(3,17,   5),(317,5)

3 个答案:

答案 0 :(得分:1)

您可以考虑在字符串中放置断点来解决此问题
例如:3175可以具有如下的断点:
31 | 7 | 5
我们可以使用递归方法:
遍历字符串时:
遇到字符串中的每个数字时,有两种选择:
  -在该数字之后放置一个断点
  -或者不要在该数字后放置断点
放置断点取决于到目前为止所遍历的数字是否形成质数(可以通过检查预先填充的质数<100的成员资格来轻松检查)

递归解决方案(在Python中):

listOfPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

def splitPrime(string):
    def helper(string, n, i):
        # If we are down to last 1 digit
        if i == n-1:
            if int(string[i]) in listOfPrimes:
                return 1
            else:
                return 0
        # If we are down to last 2 digits
        if i == n-2:
            if int(string[i:]) in listOfPrimes:
                return 1
            else:
                return 0
        else:
            # If single digit is prime, then place breakpoint here
            if int(string[i:i+1]) in listOfPrimes:
                return 1 + helper(string1, n, i+1)
            # If two digits make a prime, then place breakpoint here
            if int(string[i:i+2]) in listOfPrimes:
                return 1 + helper(string, n, i+2)
    n = len(string)
    return helper(string1, n, 0)

string1 = "3175"
string2 = "11373"
print(splitPrime(string1)) # 3
print(splitPrime(string2)) # 3

答案 1 :(得分:1)

[translate]="'<Group 1 value>'"

输出

def splitNum(s):
    """Split a string into all possible combinations"""
    assert "," not in s
    splits = []
    i = 0
    while i < 2 ** (len(s)-1):
        b = str(bin(i))[2:]
        b = "0" * (len(s)-len(b)-1) + b + "0"
        p = 0
        r = ""
        while p < len(s):
            r += s[p]
            if b[p] == "1":
                r += ","
            p += 1

        nums = [int(x) for x in r.split(",")]
        splits.append(nums)
        i += 1

    return splits


def isPrime(n):
    """A really simplistic way of identifying a prime number"""
    if n < 2:
        return False

    for i in range(2,n):
        if (n % i == 0):
            return False

    return True


def areAllPrimes(s):
    """Return True if all numbers in the set are Prime numbers"""
    for num in s:
        if not isPrime(num):
            return False

    return True


s = "3175"
for splits in splitNum(s):
    if areAllPrimes(splits):
        print(splits)

说明

将长度为4的字符串拆分为所有组合,可以通过从000到111的二进制计数来确定。当值为1时,表示应该在该点拆分字符串。

因此对于字符串“ 3175”,我们得到:

[317, 5]
[31, 7, 5]
[3, 17, 5]

答案 2 :(得分:1)

# sieve of eratosthenes
def sieve(n):
  isprime = [False, False] + [True]*n
  for p in range(2,n):
    if isprime[p]:
      for kp in range(2*p,n,p):
        isprime[kp] = False
  return isprime

isprime = sieve(100)

# Dynamic programming
# C[i] = number of ways to split S[:i] into primes
def dp(s):
  C = [0]*(len(s)+1)
  for i in range(1,len(s)+1):
    C[i] = sum(C[j] for j in range(i) if isprime[int(s[j:i])]) 
    C[i] += isprime[int(s[:i])]
  return C[len(s)]

print(dp('3175'))

说明:

C[i] =将S[:i]分解为素数的方式

如果对于j<i来说,S[j:i]是素数,则可以在j处分解以形成素数,并且至少有C[j]种方法来分解其余数S[:j]变成素数

所以,DP公式为

C[i] = sum(C[j] for j < i such that S[j:i] is a prime) + (1 if S[:i] is a prime)

注意:如果素数集限制为(0,100),则j的范围可以缩短为range(i-2,i),以加快DP的速度。