首页 > 试题广场 >

字符串计数

[编程题]字符串计数
  • 热度指数:12200 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
求字典序在 s1 和 s2 之间的,长度在 len1 到 len2 的字符串的个数,结果 mod 1000007。

数据范围:

注意:本题有多组输入

输入描述:
每组数据包涵s1(长度小于50),s2(长度小于50),len1(小于50),len2(大于len1,小于50)


输出描述:
输出答案。
示例1

输入

ab ce 1 2

输出

56
def gc(i,A):#将s1和s2补长到len2长度
    if i<len(A):
        return ord(A[i])
    else:
        return 96 #'a'-1

while 1:
    try:
        s1,s2,len1,len2=list(input().split())
        d,s,l1,l2=0,0,int(len1),int(len2)
        for i in range(l2):
            a,b=gc(i,s1),gc(i,s2)
            d=(26 * d + b - a) % 1000007#只包含小写字母的字符串可以看成26进制的数制
            if i == len(s2) - 1:#所有字符串最后都不包含是s2自身,所以最后要减1
                d -= 1
            if i >= l1 - 1:
                s = (s + d) % 1000007
        print(s)
    except:
        break

发表于 2018-08-19 14:54:48 回复(0)
# 借鉴10进制数的减法
def n_len(len_, s1=list(s1), s2=list(s2)):
    if len_ > len(s1):
        s1 = s1 + ['a'] * (len_ - len(s1))
        s2 = s2 + ['a'] * (len_ - len(s1))
    else:
        s1 = s1[:len_]
        s2 = s2[:len_]
    n = 0
    s1.reverse()  # 从低位到高位排序
    s2.reverse()
    for i in range(len_):
        if ord(s2[i]) >= ord(s1[i]):
            n += pow(26, i) * (ord(s2[i]) - ord(s1[i])) % 1000007
        else:  # 如果不够减,就向高位借一位
            s2[i+1] = chr(ord(s2[i+1]) - 1)
            n += pow(26, i) * (ord(s2[i]) - ord(s1[i]) + 26) % 1000007
    return n

input_ = input().strip().split()
s1, s2 = input_[0], input_[1]
len1, len2 = int(input_[2]), int(input_[3])
if s1 >= s2:
    print(0)

print((n_len(len2) + n_len(len1) -1) % 1000007)
# 本地测试通过了,但是提交之后又bug,不知道什么原因。
编辑于 2017-06-15 16:50:04 回复(0)
使用dp,并注意考虑length 比s1, s2的长度大的情况
while True:
    try:
        #字典序:从左往右比较,空<'a'<'b'<...,不同则必出大小,一样则比较后一位
        s1,s2,len1,len2 = raw_input().split(' ')
        len1 = int(len1)
        len2 = int(len2)
        #要保证s1<=s2算法才有效,所以先对s1>s2的print结果为0
        if s1>s2:
            print 0
        else:
            sum = 0
            last = 0
            for i in range(len2):
                #对于前i-1字符在s1,s2中间的,已经分出大小,第i个字符随便什么都可以
                current = last*26
                #对于前i-1个字符=s1的(len(s1)<i-1个时这种情况不存在),(s1<=s2)
                    #1)若s2[i]是最后一个,第i个字符>s1[i]且<s2[i]即可
                    #2)若s2[i]不是最后一个,第i个字符>s1[i]且<=s2[i]即可
                    #注意s2[i]可能为空,这时候没有可行的s1[i]可能为空,这时候所有字母都大于它
                if len(s1)>=i and len(s2)>=i+1:  #len(s1)>=i且s2[i]不为空
                    if len(s2) == i+1:  #s2[i]是最后一个
                        if len(s1) == i:  #s1[i]为空
                            current = current + (ord(s2[i])-1)-(ord('a')-1)
                        else:
                            current = current + (ord(s2[i])-1)-ord(s1[i])
                    else:
                        if len(s1) == i:  #s1[i]为空
                            current = current + ord(s2[i])-(ord('a')-1)
                        else:
                            current = current + ord(s2[i])-ord(s1[i])
                #从len1开始累加进sum
                if i>=len1-1:
                    sum = sum + current
                last = current
            print sum 
    except:
        break


发表于 2016-09-16 23:16:00 回复(0)




""" 思路:遍历 m-n 位字符串,符合要求的个数是两个字符串的差值
比如 ab ce 1-2
先求 1 位字符串,符合要求的个数
n = 'c' - 'a'  // python 用 ord() 获取 ascii 码

求 2 位字符串,符合要求的个数
n = 'ce' - 'ab' = 55 // 字母是 26 个数,不能按照 10 进制计算,而是 26 进制

这样计算的结果包括了 'ce' 最后结果得减 1  """ 
while True:
    try:
        s = raw_input()
        if s == None:
            break
        sa, sb, m, n = s.split()
        la = len(sa)
        lb = len(sb)
        sum = 0
        for i in range(int(m),int(n)+1):
            if i>la or i>lb:
                break
            t = 0
            n = 0
            while t<i:
                tmp = ord(sb[t])-ord(sa[t])
                n = (n*26 + tmp)%1000007
                t = t + 1
            sum = (sum + n)%1000007
        print sum - 1
    except: 
break
编辑于 2016-06-29 16:10:45 回复(0)