字符串
1.字符串的旋转
给定一个字符串,要求将字符串前面的若干个字符一刀字符串的尾部。
蛮力位移
def shift_one(str_a, length): list_a = [] for i in str_a: list_a.append(i) t = list_a[0] for i in range(length-1): list_a[i] = list_a[i+1] list_a[length-1] = t return ''.join(list_a) def rotate_string(str_a, length, m): for i in range(m): str_a = shift_one(str_a, length) return str_a
三步反转
def reverse_string(str_a, begin, end): list_a = [] for i in str_a: list_a.append(i) while begin < end: list_a[begin], list_a[end] = list_a[end], list_a[begin] begin += 1 end -= 1 str_b = ''.join(list_a) return str_b def rotate_string(str_a, length, m): m = m % length str_a1 = reverse_string(str_a, 0, m-1) str_a2 = reverse_string(str_a1, m, length-1) str_a3 = reverse_string(str_a2, 0, length-1) return str_a3
转化步骤是因为Python中字符串是不可变的,需要先转化为list类型。
2.字符串的包含
给定一个长字符串和一个短字符串,如何最快的判断出短字符串中的所有字符是否都在长字符串a中。
蛮力轮询
def string_contain(str_a, str_b): for i in str_b: count = 0 for j in str_a: if i == j: break count +=1 if count == len(str_a): return False return True
排序后轮询
3.字符串的全排列
输入一个字符,打印出该字符串中字符的所有排列。
例如输入字符串‘abc’,则输出有字符a,b,c所能排列出的所有字符串。
递归实现
def perms(elements): if len(elements) <=1: yield elements else: #全排列 等价于 将首字符插入到除去首字符的全排列中
for perm in perms(elements[1:]): for i in range(len(elements)): yield perm[:i] + elements[0:1] + perm[i:] for item in perms([1, 2, 3,4]): print item
字典序排列
以‘12345’为例
算法起点为字典序最小的排列,即‘12345’
算法终点为字典序最大的排列,即‘54321’
算法的执行过程 从当前排列生成字典序刚好比它大的下一个排列
算法执行步骤:
找到排列中最后一个升序的首位位置i,x=a[i]
找到排列中最后一个比a[i]打的位置j,y=a[j]
交换x,y
把第i+1位到最后的部分翻转。
4.字符串转换成整数
输入一个由数字组成的字符串,请把它转换成整数并输出。
如果不考虑溢出或者负数的情况比较简单
def str_to_int(str_a): int_a = 0 for i in str_a: int_a = 10 * int_a + int(i) return int_a
5.回文判断
给定一个字符串,如何判断这个字符串是否是回文串。
两头往中间扫
def is_palindrome(str_a, length): begin = 0 end = length-1 while begin < end: if str_a[begin] != str_a[end]: return False begin += 1 end -= 1 return True
中间往两头扫同理
6.最长回文子串
给定一个字符串,求它的最长回文子串的长度。
最简单的方法是列出所有的子串进行判断,并且记录最长的回文子串长度。
结合5中给出的方法两个循环即可。
中心拓展法
def longest_palindrome(str_a, length): if str_a == '' or length == 0: return 0 max_len = 0 for i in range(length): for j in range(length): if i-j < 0 or i+j > length-1: break if str_a[i-j] != str_a[i+j]: break c = j*2 + 1 if c > max_len: max_len = c for i in range(length): for j in range(length): if i-j < 0 or i+j+1 > length-1: break if str_a[i-j] != str_a[i+j+1]: break c = 2*j + 2 if c > max_len: max_len = c return max_len
逻辑相当简单,就是以某个字符作为中心,向两端拓展。
需要同时考虑到偶数和奇数的情况。
manacher算法
这个算法厉害了,时间复杂度达到了O(n)。
但是书中对于id和i这部分概念比较绕,而且使用c语言的实现也有问题。
留作以后研究吧。