判断两个字符串是否互为旋转词

判断两个字符串是否互为旋转词

旋转词

【题目】
如果一个字符串str,把字符串str前面任意的部分挪到后面形成的字符串叫作str的旋转词
比如str=“12345”,str的旋转词 有"12345"、“23451”、“34512”、“45123"和"51234”。
给定两个字符串a和b,请判断a和b是否互为旋转词。
若a和b长度不相等,则a和b必然不互为旋转词,直接返回False

【举例】
a=“cdab”,b=“abcd”,返回True。
a=“1ab2”,b=“ab12”,返回False。
a=“2ab1”,b=“ab12”,返回True。

算法思路

b+b组合的字符串,包含b所有的旋转词+表示字符串拼接操作
其中
任意长度为n的子串都是b的旋转词
,n为字符串b的长度
假设字符串b的字符表示形式 b = b 0 b 1 . . . b i . . . b n − 1 b=b_0b_1...b_i...b_{n-1} b=b0b1...bi...bn1
b [ 0 : n ] + b [ 0 : 0 ] = b 0 b 1 . . . b i . . . b n − 1 b[0:n]+b[0:0]=b_0b_1...b_i...b_{n-1} b[0:n]+b[0:0]=b0b1...bi...bn1
b [ 1 : n ] + b [ 0 : 1 ] = b 1 b 2 . . . b i . . . b n − 1 b 0 b[1:n]+b[0:1]=b_1b_2...b_i...b_{n-1}b_0 b[1:n]+b[0:1]=b1b2...bi...bn1b0

b [ i : n ] + b [ 0 : i ] = b i b i + 1 . . . b n − 1 b 0 b 1 . . . b i − 1 b[i:n]+b[0:i]=b_ib_{i+1}...b_{n-1}b_0b_1...b_{i-1} b[i:n]+b[0:i]=bibi+1...bn1b0b1...bi1

b [ n : n ] + b [ 0 : n ] = b 0 b 1 . . . b i . . . b n − 1 b[n:n]+b[0:n]=b_0b_1...b_i...b_{n-1} b[n:n]+b[0:n]=b0b1...bi...bn1
第i个长度为n的字符串为前i个字符移至后面的旋转词

因此b+b包含b所有的旋转词,其中任意长度为n的子串都是b的旋转词
判断a与b是否互为旋转词,只需判断a是否包含在组合字符串b+b中,在则互为旋转词,不在则不互为旋转词
字符串匹配使用KMP算法,时间复杂度为 O ( N ) O(N) O(N)

注意:
KMP算法可本地自行实现,详见字符串匹配
也可使用字符串库函数
  str1.find(str2),若包含,返回第一次出现的位置,否则返回-1;
  str1.index(str2),若包含,返回第一次出现的位置,否则抛出异常ValueError: substring not found

为简单起见,才用字符串库函数find()完成本题。


相应代码

# 判断两个字符串是否互为旋转词
def rotate_word(a, b):
    if a is None or b is None or len(a) == 0 and len(b) == 0 or len(a) != len(b):
        return False
    rotate_str = b + b
    if rotate_str.find(a) != -1:  # KMP算法,采用字符串库函数find()
        return True
    else:
        return False

# 简单测试
if __name__ == '__main__':
    a = "cdab"
    b = "abcd"
    print(rotate_word(a, b))  # True

    a = "1ab2"
    b = "ab12"
    print(rotate_word(a, b))  # False

    a = "2ab1"
    b = "ab12"
    print(rotate_word(a, b))  # True

有任何疑问和建议,欢迎在评论区留言和指正!

感谢您所花费的时间与精力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值