题库里关于字符串的题型大致是以下几类
- 字符串,字符数组,整数等转换
-
规则判断
-
数字运算
-
与数组操作相关
-
动态规划
-
高级数据结构
1.字符串,字符数组,整数等转换
(1)字符串与字符数组的转换
int main()
{
string s = "hello";
const char* s1 = NULL;
//string转const char*
s1 = s.c_str();
char* s2 = NULL;
const char* s3 = NULL;
/*string转char*
* 先将字符串转换为const char*
* 再将const char转char
*/
s3 = s.c_str();
s2 = const_cast<char*>(s3);
//string转char[],按下标挨个赋值
char s4[10] = {0};
for(int i = 0; i < s.length(); i++){
s4[i] = s[i];
}
//const char*转string
const char* s5 = "hello";
string s6;
s6 = s5;
char* s7 = NULL;
//char[]转其他类型都可直接赋值
}
这里要注意下const char*,char*,char[]之间的区别,对于char*他是指向一块存放这字符串内存,是不可以更改其指向内存内容,但可以改变其指向对象,char[]可读可写的。主要要注意下字符串只能转换为const char*。
(2)字符串与整数
这里可以记住两个函数
字符串转整数
int atoi(const char *str );
整数转字符串
sprintf(str, "%d", rand());
2.规则判断
(1)是否符合整数规则
看剑指上的一道题:将一个字符串转换成一个整数
int StrToInt(string str) {
const int length = str.length();
int isNegtive = 1, overValue = 0;
int digit = 0, value = 0;
if (length == 0) return 0;
else {
int idx = 0;
if (str[0] == '-') { isNegtive = -1; idx = 1;}
else if (str[0] == '+') {idx = 1;}
for (; idx<length; idx++) {
digit = str[idx]-'0';
// overValue表示本轮循环是否会越界
overValue = isNegtive*value - INT_MAX/10
+ (((isNegtive+1)/2 + digit > 8) ? 1:0);
if (digit<0 || digit>9) return 0;
else if (overValue > 0) return 0;
value = value*10 + isNegtive*digit;
}
return value;
}
}
其中要注意整数的越界判断,在每次每轮循环相加前都要先判断下相加后会不会溢出
overValue = isNegtive*value - INT_MAX/10+ (((isNegtive+1)/2 + digit > 8) ? 1:0);
(2)是否符合浮点数规则
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
bool isNumeric(char* string)
{
bool sig = false;
bool ife = false;
bool dec = false;
for(int i=0;i<strlen(string) ;i++){
if (string[i] == 'e' || string[i] == 'E') {
if (i == strlen(string)-1) return false; // e后面一定要接数字
if (ife) return false; // 不能同时存在两个e
ife = true;
} else if (string[i] == '+' || string[i] == '-') {
// 第二次出现+-符号,则必须紧接在e之后
if (sig && string[i-1] != 'e' && string[i-1] != 'E') return false;
// 第一次出现+-符号,且不是在字符串开头,则也必须紧接在e之后
if (!sig && i > 0 && string[i-1] != 'e' && string[i-1] != 'E') return false;
sig = true;
} else if (string[i] == '.') {
// e后面不能接小数点,小数点不能出现两次
if (ife || dec) return false;
dec = true;
} else if (string[i] < '0' || string[i] > '9') // 不合法字符
return false;
}
return true;
}
3.数字运算
有大整数加减乘除,同上字符串转为整数,主要是注意溢出判断
4.与下表操作相关
有字符的调整,排序,替换等
(1)请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
void replaceSpace(char *str,int length) {
//遍历一边字符串找出空格的数量
if(str==NULL||length<0)
return ;
int i=0;
int oldlen=0;//记录以前的长度
int space=0;//记录空格的数量
while(str[i]!='\0')
{
oldlen++;
if(str[i]==' ')
{
space++;
}
i++;
}
int newlen=oldlen+space*2;//插入后的长度
if(newlen>length)//如果计算后的长度大于总长度就无法插入
return ;
while(oldlen>=0 && newlen>oldlen)//放字符
{
if(str[oldlen]==' ') //碰到空格就替换
{
str[newlen--]='0';
str[newlen--]='2';
str[newlen--]='%';
}
else //不是空格
{
str[newlen--]=str[oldlen];
}
oldlen--;
}
}
思路是先计算出有的空格个数,从而算出替换后字符串的总长度,然后从后想前添加,这样每个字符移动的次数更少。
(2)输入一个字符串,按字典序打印出该字符串中字符的所有排列
void swap(char& p,char& q){
char temp = p;
p = q;
q = temp;
}
void perm(string& str,vector<string>& res, int begin)
{
if(begin == str.length()-1){
if(find(res.begin(),res.end(),str) == res.end()){
res.push_back(str);
}
return ;
}
else{
for(int i=begin;i<str.length();i++){
swap(str[begin],str[i]);
perm(str,res,begin+1);
swap(str[i],str[begin]);
}
}
}
int main()
{
string s = "abcd";
vector<string> res;
int begin = 0;
perm(s,res,begin);
for(int i=0;i<res.size();i++){
cout<<res[i]<<endl;
}
return 0;
}
思路就是递归。固定第一个字符,递归取得首位后面的各种字符串组合;再把第一个字符与后面每一个字符交换,并同样递归获得首位后面的字符串组合;递归的出口,就是只剩一个字符的时候,递归的循环过程,就是从每个子串的第二个字符开始依次与第一个字符交换,然后继续处理子串
(3)求字符的所有组合
void perm(char* str,vector<char>& res, int begin)
{
if(begin == 0){
for(int i=0;i<res.size();i++){
cout<<res[i];
}
cout<<endl;
return ;
}
if(*str == '\0')
return ;
res.push_back(*str);
perm(str+1,res,begin-1);
res.pop_back();
perm(str+1,res,begin);
}
int main()
{
char s[] = "abcd";
vector<char> res;
for(int i = 1;i <= strlen(s);i++){
perm(s,res,i);
}
return 0;
}
对于n长度的字符串求其组合,则他的长度有n中,就设置循环从1到n。求长度为m的组合,那对于第一个字符,它可以添加进,那后面就再需要m-1个字符,它可以不添加进,再在后面选m个字符。
(4)将字符串循环左移n位
string LeftRotateString(string str, int n) {
reverse(str.begin(), str.end());
reverse(str.begin(), str.begin() + str.size() - n);
reverse(str.begin() + str.size() - n, str.end());
return str;
}
6.动态规划
求最长公共子串,最长公共子序列,最长回文子串,最长回文子序列等等(另写一篇总结)
7.高级算法
manached,kmp
来源:CSDN
作者:穿着靴子的猫
链接:https://blog.csdn.net/sydney__/article/details/104138577