字符串集合算法题汇总(使用C++和python语言)--hard001

这篇博客总结了字符串排序、合并处理和截取问题的算法解决方案,包括C++和Python两种语言的应用。在字符串排序中,重点处理了逆序和非英文字母的情况。字符串合并处理通过构建辅助字符串解决复杂替换问题。字符串截取问题中,讨论了如何找到最大回文子串的算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串排序

在这里插入图片描述
这道题难点在于逆序非英文字母的保持原位,可以考虑使用vectorpush_back单独处理英文字母的逆序,再并到原字符串

#include<vector>
#include<iostream>
#include<string>
 
using namespace std;
 
int main()
{
    string s;
    vector<char> Temp;
    while(getline(cin,s))
    {
        Temp.clear();
        int len = s.size();
        for(int j=0; j<26; j++)
        {
            for(int i=0; i<len; i++)
            {
                if(s[i]-'a'==j||s[i]-'A'==j)
                {
                    Temp.push_back(s[i]);
                }
            }
        }
        for(int i=0,k=0;(i<len)&&k<Temp.size();i++)
        {
            if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z'))
                s[i]=Temp[k++];
        }
        cout<<s<<endl;
    }
    return 0;
}

使用python

while True:
    try:
        a = input()
        # res定义为最终返回的字符串的列表,char是提取的英文字母。
        res = [False] * len(a) 
        char = []
        for i, k in enumerate(a):
            if k.isalpha():
                char.append(k)        ##存放英文字母
            else:
                res[i] = k            #存放非英文字母
                
        char.sort(key=lambda c: c.lower())        #处理英文字母的排序
        # 将char中对应的字符填到res中。
        for i, k in enumerate(res):
            if not k:
                res[i] = char[0]
                char.pop(0)
        print("".join(res))
    except:
        break

知识点:

  1. [False]*len(a) [False] 是列表list,len(dados_estacionamento)是获得a的长度。
    乘以长度值,即是初始化一个含有该长度值个False的列表。

  2. enumerate() 函数用于将一个可遍历的数据对象(如列表元组字符串)组合为一个索引序列,同时列出数据数据下标

    enumerate(sequence, [start=0])

  • sequence – 一个序列、迭代器或其他支持迭代对象。
  • start – 下标起始位置。
  1. join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
    str.join(sequence)
    • sequence– 要连接的元素序列。
字符串合并处理

在这里插入图片描述
思路:

  1. 对于BIT倒序操作,因为字符数不多,可以通过定义辅助字符串组来进行解决
  2. 对于奇数排序和偶数排序,可以通过分割字符串分别进行排序后再进行拼接
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const string helper1 = "0123456789abcdefABCDEF";
const string helper2 = "084C2A6E195D3B7F5D3B7F";
int main()
{
    string s1,s2,s;
    while(cin >> s1 >> s2)
    {
        s = s1 + s2;
        string str1,str2,str;
        for(int i = 0;i < s.length();i++)
        {
            if(i % 2 == 0)
                str1 += s[i];		//偶数
            else
                str2 += s[i];		//奇数
        }
        sort(str1.begin(),str1.end());	
        sort(str2.begin(),str2.end());
        for(int i = 0;i < s.length();i++)
        {
            if(i % 2 == 0)
                str += str1[i/2];
            else
                str += str2[i/2];
        }
        for(int i = 0;i < str.length();i++)	//BIT倒序替换
        {
            int n = helper1.find(str[i]);		//定位
                if(n != -1)
                    str[i] = helper2[n];
        }
        cout << str << endl;
    }
    getchar();
    return 0;
}

总结:
像一些密码题,IP题,对于自定义规则的替换(数量有限),都可以通过构建辅助字符串来进行替换,进而避免进行麻烦的书写

python解法思路一样

while True:
    try:
        dic = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]
        s = input().replace(" ", "")  #s是输入的合并后的字符串
        ss = ""  #ss为最终返回的字符串
        odd, even = "", ""  # 字符串的奇数子串和偶数子串
        for i, v in enumerate(s):
            if i % 2 == 0:
                even += v
            else:
                odd += v
        odd = sorted(odd)
        even = sorted(even)
        #BIT倒序替换
        for i in range(len(even)):
            if even[i] in "0123456789abcdefABCDEF":
                ss += dic[int(bin(dic.index(even[i].upper())).replace("0b", "").rjust(4, "0")[::-1], 2)]
            else:
                ss += even[i]
            if len(odd) != i:   #注意偶数串可能比奇数串长一个字符,所以要做一下判断。
                if odd[i] in "0123456789abcdefABCDEF":
                    ss += dic[int(bin(dic.index(odd[i].upper())).replace("0b", "").rjust(4, "0")[::-1], 2)]
                else:
                    ss += odd[i]
        print(ss)
    except:
        break

总结知识点:

  1. str.replace(old, new[, max]):replace()方法把字符串中的old(旧字符串) 替换成new(新字符串),如果指定第三个参数max,则替换不超过 max
  • old– 将被替换的子字符串。
  • new – 新字符串,用于替换old子字符串。
  • max – 可选字符串, 替换不超过 max
  1. str.rjust(width[, fillchar]): 返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串。如果指定的长度小于字符串的长度则返回原字符串。
  • width – 指定填充指定字符后中字符串的总长度.
  • fillchar – 填充的字符,默认为空格。
  1. bin: 返回一个整数int 或者长整数 long int 的二进制表示。
  2. [::-1]:逆序
字符串的截取问题

在这里插入图片描述
求字符串中的最大回文,最好的算法应该就是manacher算法了。比较经典,都批注在代码里了

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int Manacher(string oriStr) {
    string newStr;
    int len = oriStr.size();
    for (int i = 0; i < len; i++) {//插入间隔符
        newStr += '#';
        newStr += oriStr[i];
    }
    newStr += '#';
    len = 2 * len + 1;             //新串长度,必为奇数
    int maxRight = 0;              //当前访问到的所有回文子串中,所能触及的最右一个字符的位置
    int pos = 0;                   //maxRight对应的回文子串对称轴的位置
    int*RL = new int[len];         //RL[i]记录以i为对称轴的最长回文子串半径长度(对称轴到最左或最右的距离)
    int maxLength = 0;             //记录最长回文子串长度
    for (int i = 0; i < len; i++) {
        if (i < maxRight) {        //分两种情况,i在maxRight左边和右边
            RL[i] = min(RL[2 * pos - i], maxRight - i);
        }
        else RL[i] = 1;
        while (i - RL[i]>=0 && RL[i] + i < len && newStr[i - RL[i]] == newStr[i + RL[i]])
            RL[i]++;               //以i为中心,在上步的基础上扩展,直至到达边界或左右字符不相等
        if (maxRight < RL[i] + i - 1) {//更新maxRight和pos
            maxRight = RL[i] + i - 1;
            pos = i;
        }
        maxLength = max(maxLength, RL[i] - 1);//对以i为中心的回文子串在原串总的长度即为RL[i] - 1
                                              //证明:新串中回文子串长度为2*RL[i]-1,其中RL[i]个
                                              //插入字符,则剩下的RL[i]-1个为原字符
    }
    return maxLength;
}
 
int main() {
    string str;
    while (cin >> str) {
        cout << Manacher(str) << endl;
    }
    return 0;
}

python的解法

def longestPalindrome(s):
    if s==s[::-1]:return len(s)
    maxLen=0
    for i in range(len(s)):
        if i-maxLen>=1 and s[i-maxLen-1:i+1]==s[i-maxLen-1:i+1][::-1]:
            maxLen+=2
            continue
        if i-maxLen>=0 and s[i-maxLen:i+1]==s[i-maxLen:i+1][::-1]:
            maxLen+=1
    return maxLen
while True:
    try:
        a=input()
        if a:
            print(longestPalindrome(a))
 
    except:
        break
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值