剑指offer || 字符串
剑指offer中有关字符串的题目汇总
面试题5:替换空格
题目:替换空格
请实现一个函数,把字符串中的每个空格替换成“%20”.
输入: 'hello world'
输出:'hello%20world'
代码
#################面试题5#######################
#替换空格 (非剑指offer的解法)
class Solution:
# s 源字符串
def replaceSpace(self, s):
# write code here
news = ''
for i in s:
if i ==' ':
news += '%23'
else:
news += i
print(news)
测试
################测试1#################
#功能测试
s = Solution()
s.replaceSpace('hello world')
面试题19:正则表达式匹配
题目:正则表达式匹配
请实现一个函数用来匹配包含‘ .’ 和‘*’的正则表达式
代码
#################面试题19#######################
#正则表达式匹配
测试
################测试1#################
# 功能测试
面试题20:表示数值的字符串
题目:表示数值的字符串
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
例如:'+100','5e2','-123','3.1416','-1E-16'都是表示数字
'12e','1a3.14','1.2.3','+-5','12e+5.4'都不是
思路
表示字符串遵循模式 A[.[B]][e|EC] A [ . [ B ] ] [ e | E C ] 或者 .B[e|EC] . B [ e | E C ]
A A 为数值的整数部分,为紧跟小数点为数值的小数部分, C C 紧跟着‘e’或‘E’为数值的指数部分
部分非必须,如果 A A 为空,则不能为空
A A 和前都可以有 + + 或 开头的 0 0 ~ 的数位串,
B B 也是 ~ 9 9 的数位串,前面不能有或 − −
首先尽可能多地扫描 ~ 9 9 的数位,小数点前部分是;遇到小数点开始扫描 B B
遇到或 E E ,则开始扫描
代码
#################面试题20#######################
#表示数值的字符串
def isNumeric(string):
if not string:
return
if string == '':
return False
i = 0
positionOfPoint = -1
positionOfE = len(string)
while i < len(string):
if string[i] == '.':
A = string[0:i]
positionOfPoint = i
i += 1
if string[i] == 'e' or string[i] == 'E':
if positionOfPoint == -1:#说明 无"."
positionOfE = i
A = string[:i]
B = ''
i += 1
else:
positionOfE = i
i += 1
i += 1
B = string[positionOfPoint + 1:positionOfE]
if positionOfPoint == -1 and positionOfE == len(string):
#纯整数的情况
A = string
B = ''
C = string[positionOfE+1:len(string)]
if positionOfE == 0: #第一位元素是E
return False
if (A == '' or scanInteger(A)) and (B =='' or scanNumber(B)) and (C =='' or scanInteger(C)):
return True
else:
return False
def scanNumber(string):
if string == '':
return False
i = 0
while i < len(string):
if '0' <= string[i] <= '9':
i+=1
else:
return False
return True
def scanInteger( string):
L = len(string)
if string[0] == '-' or string[0]=='+':
return scanNumber(string[1:L])
else:
return scanNumber(string)
测试
################测试1#################
# 功能测试
string = '+123.11e-122'
isNumeric(string)
isNumeric('+1') #测试正数
#return True
isNumeric('-1') #测试正数
#return True
isNumeric('.123') #不包含整数部分
#return True
isNumeric('e123') #
#return False
# 特殊输入测试
isNumeric(None)
面试题38:字符串的排列
题目:正则表达式匹配
输入一个字符串,打印出该字符串中字符的所有排列。
输入:abc
输出:abc、acb、bac、bca、cab、cba
代码
#################面试题19#######################
#正则表达式匹配
测试
################测试1#################
# 功能测试
面试题46:把数字翻译成字符串
题目:把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成’a’,1翻译成’b’,25翻译成’z’
一个数字有多种翻译,例如12258有5钟不同的翻译
编程实现一个函数,用来计算一个数字有多少种不同的翻译方法
思路
以12258为例
两种翻译方法
- 数字1单独翻译成b 剩下数字2258
- 数字12翻译成m,后面剩下数字258
递归翻译剩下的数字 递归造成重复计算 需要从下往上翻译
f(i)=f(i+1)+g(i,i+1)f(i+2) f ( i ) = f ( i + 1 ) + g ( i , i + 1 ) f ( i + 2 )
f(i) f ( i ) 表示从第 i i 位数字起不同翻译的数目
当第位和第 i+1 i + 1 位的两位数字拼接起来的数字在 10 10 ~ 25 25 的范围内,函数 g(i,i+1)=1 g ( i , i + 1 ) = 1 ,否则为 0 0
代码
#################面试题46#######################
#把数字翻译成字符串
def GetTranslationCount(number):
if number < 0:
return 0
strNum = str(number)
length = len(strNum)
counts = [0] * length
count = 0
for i in range(length - 1, -1, -1):
count = 0
if i < length - 1:
count = counts[i + 1]
else: # i = length - 1
count = 1
if i < length - 1:
converted = strNum[i:i + 2]
if '10' <= converted <= '25':
if i < length - 2:
count += counts[i + 2]
else: # i = length - 2
count += 1
counts[i] = count
return counts[0]
测试
################测试#################
# 功能测试
# 只有一位数字
GetTranslationCount(8)
# 包含多位数字
GetTranslationCount(12)
GetTranslationCount(12258)
# 特殊输入测试
# 负数
GetTranslationCount(-8)
# 0
GetTranslationCount(0)
GetTranslationCount(2526)
面试题48:最长不含重复字符的子字符串
题目:最长不含重复字符的子字符串
请从字符串中找出一个最长的不包含重复字符的子字符串,计算最长该子字符串的长度。假设字符串中只包含’a’ ~ ‘z’ 的字符
输入:'arabcacfr'
输出:最长的不包含重复字符的子字符串是'acfr'
思路
动态规划
:以第 i i 个字符为结尾的不包含重复字符的子字符串的最长长度
第i个字符之前没出现过, f(i)=f(i−1)+1 f ( i ) = f ( i − 1 ) + 1
(2) ( 2 ) 第i个字符之前已经出现过。
计算第i个字符和它上次出现在字符串中的位置的距离, d d
1、 第i个字符上次出现在f(i-1)对应的最长子字符串之中
f(i)=d f ( i ) = d
2、 d>f(i−1) d > f ( i − 1 ) 第i个字符上次出现在f(i-1)对应的最长子字符串之前
f(i)=f(i−1)+1 f ( i ) = f ( i − 1 ) + 1
代码
#################面试题48#######################
#最长不含重复字符的子字符串
def longestSubstringWithoutDuplication(string):
curLength = 0
maxLength = 0
position = [-1] * 26 # 26个字母
if not string:
return None
for i in range(len(string)):
preIndex = position[ord(string[i]) - ord('a')]
if preIndex < 0 or i - preIndex > curLength:
curLength += 1
else:
if curLength > maxLength:
maxLength = curLength
curLength = i - preIndex
position[ord(string[i]) - ord('a')] = i
if curLength > maxLength:
maxLength = curLength
return maxLength
测试
################测试1#################
# 功能测试
# 包含多个字符的字符串
longestSubstringWithoutDuplication('arabcacfr')
# 只有一个字符的字符串
longestSubstringWithoutDuplication('a')
# 所有字符都相同的字符串
longestSubstringWithoutDuplication('aaaa')
# 特殊输入测试
longestSubstringWithoutDuplication(None)
面试题58:翻转字符串
题目一:翻转单词顺序
输入一个英文句子,翻转句子中的单词顺序,但单词内的字符顺序不变。为简单起见,标点符号和普通字母一样处理。
输入:“ I am a student."
输出:student. a am I
代码
#################面试题58#######################
#翻转单词顺序
测试
################测试1#################
# 功能测试