查找具有给定长度的“游程”的十进制字符串的数量

时间:2019-05-19 17:22:00

标签: python

我遇到了一个问题,我想查找长度为n(每个n位数字可以为0,1,... 9)的十进制字符串的数目,这些数字的“游程”至少为{{ 1}}。 “游程”是连续的递增/递减的数字序列,可以使mod 10上溢/下溢。例如,“ 345600”,“ 901285”,“ 098723”的游程长度均为4,但是“ 123890”的游程长度只有两个3.

我的想法是遍历每个length >= k个可能的候选人。我知道,对于每个候选人,您都需要检查10^n个数字的n-k+1个“块”,以查看它们是“递增”还是“递减”。

k

我在想出一个功能来检查“递增模块10”时遇到了麻烦。当前,此函数很容易返回False。也许我错过了一个我还没有学到的标准技巧,或者有一种简单的递归方法可以做到这一点?感谢您的指导。

这是我第一次在StackOverflow上提问。请让我知道我以后如何能提出更好的问题。

1 个答案:

答案 0 :(得分:0)

当(a-b + 10)%10等于1时,数字a,b按递增顺序排列;如果等于9,则数字按a递减顺序排列。其他任何值表示它们不按顺序排列。

您可以创建一个成对的字典,该字典将告诉两个连续的字符是递增(1)还是递减(9)运行的一部分。然后处理字符串中的每对字符以将它们转换为运行指示器。如果找到长度为N-1的连续“ 1”或“ 9”指示符,则说明您至少有一个长度为N的游程:

def hasRun(string,count):
    match = {(str(n),str((n+d)%10)):str(d) for d in [1,9] for n in range(10) }
    runs  =  "".join( match.get(pair,".") for pair in zip(string,string[1:]) )
    return "1"*(count-1) in runs or "9"*(count-1) in runs

解决此问题的另一种方法是在字符串中搜索长度N的20个可能的游程(10个递增,其10个倒数):

def hasRun(string,count):
    for i in range(10):
        run = "".join(str((d+i)%10) for d in range(count))
        if run in string or run[::-1] in string: return True
    return False

最后,如果您需要一种程序方法,可以这样做:

def hasRun(string,count):
    runType  = 0
    runCount = 0
    match = {(str(n),str((n+d)%10)):d for d in [1,9] for n in range(10) }
    for a,b in zip(string,string[1:]):
        delta    = match.get((a,b),0)
        runCount = 2 if delta != runType else runCount + 1
        if delta != 0 and runCount == count:
            return True
        runType  = delta
    return False

注意:此过程方法运行时间为O(n)。当它在字符串的开头找到所请求长度的游程时,它通常比其他两个执行得更快。这是因为它立即停止迭代并且不处理字符串的其余部分。