算法练习--字符串相关

单词倒排

对字符串中的所有单词进行倒排。
1、构成单词的字符只有26个大写或小写英文字母;
2、非构成单词的字符均视为单词间隔符;
3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;
4、每个单词最长20个字母;

输入描述:
输入一行字符串

输出描述:
输出单词的倒排结果

示例1
输入:
I am a student
输出:
student a am I

示例2
输入:
$bo*y gi!r#l
输出:
l r gi y bo

python实现,关键找出所有的单词

while True:
    try:
        s = input()

        # 找出所有的单词
        word = ""
        words = []
        for i in s:
            if i.isalpha():
                word += i
            else:
                if word:
                    words.append(word)
                    word = ""
        
        if word:
            words.append(word)
        result = " ".join(words[::-1])

        print(result)

    except:
        break

 

计算某字符出现次数

写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出字符串中该字符的出现次数。(不区分大小写字母)

输入描述:
第一行输入一个由字母、数字和空格组成的字符串,
第二行输入一个字符(非空格)

输出描述:
输出字符串中含有该字符的个数。(不区分大小写字母)

示例1
输入:
ABCabc
A
输出:
2
python实现

def statistic_char_num():
    s1 = input()
    s2 = input().strip().lower()

    num = 0
    for i in s1.lower():
        if i == s2:
            num += 1

    print(num)

statistic_char_num()

 

明明的随机数

  • 输入N个 1到500之间 的随机整数;
  • 删去其中重复的数字,即相同的数字只保留一个;
  • 把去重后的数从小到大排序, 并顺序输出。
  • 1≤N≤1000 ;1≤val≤500
    输入描述:
    第一行先输入随机整数的个数 N ;接下来的 N 行每行输入一个整数;
    代表明明生成的随机数。
    输出描述:
    输出多行,表示处理后的结果
     
    示例1
    输入:
    3
    2
    2
    1
    输出:
    1
    2
    说明:
    输入解释:
    第一个数字是3,也即这个小样例的N=3,说明用计算机生成了3个1到500之间的随机整数,接下来每行一个随机数字,共3行,也即这3个随机数字为:
    2
    2
    1
    所以样例的输出为:
    1
    2

# 输入一个数n
n = int(input("输入n:").strip())

# 输入n个随机整数
nums = []
i = 0
while i < n:
    cur = int(input().strip())
    nums.append(cur)
    i += 1

# 去重,并排序
nums = sorted(list(set(nums)))

for i in nums:
    print(i)

回文字符串

  1. 判断一个字符串是否为回文字符串。(两边对称)
# 判断一个字符串是否两边对称
def is_palindrom(s):
    n = len(s)
    mid = n // 2 - 1
    for i in range(0, mid, 1):
        if s[i] != s[n-1-i]:
            return False
    return True


if __name__ == '__main__':
    s = "abcdef"
    s1 = "abccba"
    print("s:", is_palindrom(s))
    print("s1:", is_palindrom(s1))

  1. 找出一个字符串中的最大回文子串。
# 中心扩展法

def get_max_palindrom(s):
    n = len(s)
    result = ""
    # 奇对称 扩展
    for i in range(n):
        # 两边扩展,并判断
        left = i - 1
        right = i + 1
        while left >= 0 and right < n and s[left] == s[right]:
            left -= 1
            right += 1
        # 获取当前回文字符串
        temp = s[left+1: right]
        if len(temp) > len(result):
            result = temp

    # 偶对称扩展
    for i in range(n-1):
        left = i
        right = i + 1
        while left >= 0 and right < n and s[left] == s[right]:
            left -= 1
            right += 1
        # 获取当前回文字符串
        temp = s[left+1: right]
        if len(temp) > len(result):
            result = temp

    return result


if __name__ == '__main__':
    s = "aaaaaaaaaaaabceddefabccbaggffggffggffggffgg"
    print(get_max_palindrom(s))

 

回文数字

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。

示例 1:
输入:x = 121
输出:true
 
示例 2:
输入:x = -121
输出:false

示例 3:
输入:x = 10
输出:false
进阶:你能不将整数转为字符串来解决这个问题吗?

python实现:
思路:将整数反转过来,与原值比较,相等则为True,否则False

class Solution:
    def isPalindrome(self, x: int) -> bool:
        # 负数不是
        if x < 0:
            return False
        # 单个数字 是回文
        elif x <= 9:
            return True

        else: # >= 10   O(n)
            origin = x
            reverse = 0
            base = 10
            while x // base: 
                base *= 10
            base /= 10

            while x:
                reverse += x % 10 * base
                x //= 10
                base /= 10 
            return reverse == origin

 

无重复字符的最大子串长度

pending

 

有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 每个右括号都有一个对应的相同类型的左括号。

示例 1:
输入:s = “()”
输出:true

示例 2:
输入:s = “()[]{}”
输出:true
 
示例 3:
输入:s = “(]”
输出:false
 
示例 4:
输入:s = “([”
输出:false
 
示例 5:
输入:s = “]}”
输出:false

提示:
1 <= s.length <= 104
s 仅由括号 ‘()[]{}’ 组成
 
python 实现:
hash + 栈空间

# hash存储对应关系
# 遍历字符串,左括号入栈
# 右括号出栈,并对比
class Solution:
    def isValid(self, s: str) -> bool:
        n = len(s)
        if n % 2 != 0:  # 有效则必然成对出现
            return False

        dict_ = {  # 存储对应关系
            "(": ")",
            "[": "]",
            "{": "}",
            "0": "0"
        }

        stack = ["0"] # 防止第一个就是右括号,出栈报错
        for c in s:
            if c in dict_: # 左括号入栈
                stack.append(c)
            elif dict_[stack.pop()] != c: # 右括号出栈
                return False
        return len(stack) == 1  
     

 

罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000

例如, 罗马数字 2 写做 II ,12 写做 XII ,27 写做 XXVII 。

罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。

示例 1:
输入: s = “III”
输出: 3
 
示例 2:
输入: s = “IV”
输出: 4

示例 3:
输入: s = “IX”
输出: 9

示例 4:
输入: s = “LVIII”
输出: 58
解释: L = 50, V= 5, III = 3.

示例 5:
输入: s = “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

python实现

  • 当前符号大于等于右边的符号,则表示为正;
  • 当前符号小于右边的符号,则表示为负。
class Solution:
    def romanToInt(self, s: str) -> int:
        dict_ = {
            "I": 1,
            "V": 5,
            "X": 10,
            "L": 50,
            "C": 100,
            "D": 500,
            "M": 1000
        }

        result = 0
        n = len(s)
        for i in range(n-1):
            c = s[i]
            if dict_.get(c) >= dict_.get(s[i+1]):
                # positive
                result += dict_.get(c)

            else:
                # negative
                result -= dict_.get(c)
        result += dict_.get(s[-1])

        return result

 

字符串通配符

通配符是一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。
实现如下2个通配符:
*:匹配0个或以上的字符(注:能被 *和 ?匹配的字符仅由字母和数字0到9组成)
?:匹配1个字符

注意:匹配时不区分大小写。

输入:

  • 通配符表达式;
  • 一组字符串。

输出:

  • 匹配成功输出true
  • 匹配失败输出false

进阶:时间复杂度: O ( n 2 ) {O(n^2)} O(n2),空间复杂度: O ( n ) {O(n)} O(n)

 
示例1
输入:

  • 第一行 te?t*.*
  • 第二行 txt12.xls

输出:

  • false

 
示例2
输入:

  • 第一行 z
  • 第二行 zz

输出:

  • false

 
示例3
输入:

  • pq
  • pppq

输出:

  • false

示例4
输入:

  • **z
  • 0QZz

输出:

  • true

示例5
输入:

  • ?*Bc*?
  • abcd

输出:

  • true

示例6
输入:

  • h*?*a
  • h#a

输出:

  • false

示例7
输入:

  • p*p*qp**pq*p**p***ppq
  • pppppppqppqqppqppppqqqppqppqpqqqppqpqpppqpppqpqqqpqqp

输出:

  • false

python实现

  • s1, s2均为空;
  • s1, s2有一个空;
  • s1, s2均非空;从最后一个元素,递归解决。
  • s1最后一位是字母、数字时;
  • s1最后一位是?时;
  • s1最后一位是*时;
# 匹配函数
def fun(s1, s2):
    if s1 == "" and s2 == "":
        return True
    elif s1 == "" and s2 != "":
        return False
    elif s1 != "" and s2 == "":
        if s1.replace("*", "") == "":
            return True
        else:
            return False
    else:
        m, n = len(s1), len(s2)
        if s1[m - 1] == s2[n - 1] or (s1[m - 1] == "?" and s2.isalnum()):
            return fun(s1[: m - 1], s2[: n - 1])

        elif s1[m - 1] == "*":
            return fun(s1[: m - 1], s2) or fun(s1, s2[: n - 1])
        else:
            return False


s1, s2 = input().lower(), input().lower()
if fun(s1, s2):
    print("true")
else:
    print("false")
    

有点问题。
 

杨辉三角

在这里插入图片描述
第一行只有一个数1,以下每行的每个数,是恰好是它上面的数、左上角数和右上角的数,3个数之和(如果不存在某个数,认为该数就是0)。

求第n行第一个偶数出现的位置。如果没有偶数,则输出-1
输入第n行,
输出第n行第一个偶数的位置。
示例1
输入:
4
输出:
3 即第四行的6
python代码

import sys
alt=[2,3,2,4] # 发现规律,从第三行开始偶数位置为2324循环
for line in sys.stdin:
    n=int(line.strip())
    if n<3:
        print(-1)
    if n>=3: 
        print(alt[(n-3)%4]) #所以对4求余,映射到上面alt列表中

 

查找两个字符串a,b中的最长公共子串 **

进阶:时间复杂度: O ( n 3 ) {O(n^3)} O(n3)
空间复杂度: O ( n ) {O(n)} O(n)
输入:
输入两个字符串

输出:
返回重复出现的字符

示例1
输入:
abcdefghijklmnop
abcsafjklmnopqrstuvw

输出:
jklmnop

python实现
遍历短的子串,判断是否in长的字符串中。

def max_common_substring(a, b):
	if not a or not b:
        print("")
        return ""
    if len(a) > len(b):
        a, b = b, a
    res = ''
    # 遍历短的字符串
    for i in range(0, len(a)):
        for j in range(i, len(a)):
            if a[i:j + 1] in b:
                if j + 1 - i > len(res):
                    res = a[i:j + 1]
                    print(a[i:j + 1], "在")
            else:
                print(a[i:j + 1], "不在")
                break

    print(res)

 

找出字符串中第一个只出现一次的字符

找出字符串中第一个只出现一次的字符

输入描述:
输入一个非空字符串

输出描述:
输出第一个只出现一次的字符,如果不存在输出-1

示例1
输入:
asdfasdfo

输出:
o
python实现:

  • hash统计出现次数;
  • 列表记录出现一次的字符
def count_char(s):
    dict_ = {}
    temp = []
    for c in s:
        if c in dict_:
        	if c in temp:
            	temp.remove(c)
        else:
            dict_[c] = 1
            temp.append(c)
    if temp:
        print(temp[0])
        return temp[0]
    print(-1)
    return -1

s = input()
count_char(s)

 

表示数字

将一个字符串中所有的整数前后加上符号“*”,其他字符保持不变。连续的数字视为一个整数。
输入描述:
输入一个字符串

输出描述:
字符中所有出现的数字前后加上符号“*”,其他字符保持不变

示例1
输入:
Jkdi234klowe90a3
复制
输出:
Jkdi234klowe90a3

python实现:

def add_star():
    s = input()
    s_o = ''
    char_pre = ''
    for i in s: #遍历字符串
        if i.isdigit() : #遇到数字,判断其前面是否非数字,是则表示数字的开始,先插入‘*’
            if not char_pre.isdigit():
                s_o +='*'
        else: #非数字情况,判断其前是否为数字,是则表示数字结束,插入‘*’
            if char_pre.isdigit():
                s_o +='*'
        s_o += i #把当前字符带出来
        char_pre = i #当前字符更新到 前字符
    if i.isdigit(): #结束的时候,判断是否数字结束,如果是的话,插入‘*’
        s_o +='*'
    print(s_o)
        

add_star()

 

验证密码是否合格

密码要求:

1.长度超过8位

2.包括大小写字母.数字.其它符号,以上四种至少三种

3.不能有长度大于2的包含公共元素的子串重复 (注:其他符号不含空格或换行)

输入描述:
一组字符串。
输出描述:
符合要求输出:OK,否则输出NG

def check(s):
    if len(s) <= 8:
        return 0
    a, b, c, d = 0, 0, 0, 0
    for item in s:
        if ord('a') <= ord(item) <= ord('z'):
            a = 1
        elif ord('A') <= ord(item) <= ord('Z'):
            b = 1
        elif ord('0') <= ord(item) <= ord('9'):
            c = 1
        else:
            d = 1
    if a + b + c + d < 3:
        return 0
    for i in range(len(s)-3):
        if len(s.split(s[i:i+3])) >= 3:
            return 0
    return 1


s = input()
print('OK' if check(s) else 'NG')

 

字符串加密

有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS。如果单词中包含有重复的字母,只保留第1个,将所得结果作为新字母表开头,并将新建立的字母表中未出现的字母按照正常字母表顺序加入新字母表。如下所示:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

T R A I L B Z E S C D F G H J K M N O P Q U V W X Y (实际需建立小写字母的字母表,此字母表仅为方便演示)

上面其他用字母表中剩余的字母填充完整。在对信息进行加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应字母一一取代原文的字母(字母字符的大小写状态应该保留)。因此,使用这个密匙, Attack AT DAWN (黎明时攻击)就会被加密为Tpptad TP ITVH。

请实现下述接口,通过指定的密匙和明文得到密文。

保证输入的字符串中仅包含小写字母

输入描述:
先输入key和要加密的字符串

输出描述:
返回加密后的字符串

示例1
输入:
nihao
ni

输出:
le

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值