字符串排序
这道题难点在于逆序和非英文字母的保持原位,可以考虑使用vector
的push_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
知识点:
-
[False]*len(a)
[False] 是列表list,len(dados_estacionamento)
是获得a
的长度。
乘以长度值,即是初始化一个含有该长度值个False
的列表。 -
enumerate()
函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标enumerate(sequence, [start=0])
sequence
– 一个序列、迭代器或其他支持迭代对象。start
– 下标起始位置。
join()
方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
str.join(sequence)
sequence
– 要连接的元素序列。
字符串合并处理
思路:
- 对于BIT倒序操作,因为字符数不多,可以通过定义辅助字符串组来进行解决
- 对于奇数排序和偶数排序,可以通过分割字符串分别进行排序后再进行拼接
#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
总结知识点:
str.replace(old, new[, max])
:replace()
方法把字符串中的old
(旧字符串) 替换成new
(新字符串),如果指定第三个参数max
,则替换不超过max
次
old
– 将被替换的子字符串。new
– 新字符串,用于替换old
子字符串。max
– 可选字符串, 替换不超过max
次
str.rjust(width[, fillchar])
: 返回一个原字符串右对齐,并使用空格填充至长度width
的新字符串。如果指定的长度小于字符串的长度则返回原字符串。
width
– 指定填充指定字符后中字符串的总长度.fillchar
– 填充的字符,默认为空格。
bin
: 返回一个整数int
或者长整数long int
的二进制表示。[::-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