C++字符串的常见函数:
string
)函数 | 返回值 | 描述 |
---|---|---|
size() |
size_t |
返回字符串的长度。 |
length() |
size_t |
同 size() ,返回字符串的长度。 |
empty() |
布尔值 (true 或 false ) |
如果字符串为空,则返回 true ;否则返回 false 。 |
clear() |
无 | 清空字符串内容。 |
at(pos) |
字符的引用 | 返回位置 pos 的字符。 |
operator[] |
字符的引用 | 返回指定位置的字符。 |
substr(start, len) |
string |
返回一个子字符串,从位置 start 开始,长度为 len 。 |
append(str) |
string& |
将 str 追加到当前字符串的末尾。 |
push_back(ch) |
无 | 将字符 ch 添加到字符串末尾。 |
pop_back() |
无 | 删除字符串的最后一个字符。 |
erase(pos, len) |
string& |
从位置 pos 开始删除 len 个字符。 |
replace(pos, len, str) |
string& |
用 str 替换从位置 pos 开始的 len 个字符。 |
find(str, pos) |
size_t |
从位置 pos 开始查找子字符串 str 的首次出现。如果找到,返回起始位置;否则返回 string::npos 。 |
rfind(str, pos) |
size_t |
从位置 pos 开始向前查找子字符串 str 的最后一次出现。如果找到,返回起始位置;否则返回 string::npos 。 |
c_str() |
const char* |
返回C风格的字符串。 |
begin() |
迭代器 | 返回指向字符串首字符的迭代器。 |
end() |
迭代器 | 返回指向字符串末尾字符之后的迭代器。 |
compare(str) |
整数 | 比较当前字符串和 str 。返回值为0表示相等;小于0表示当前字符串小于 str ;大于0表示当前字符串大于 str 。 |
当然,下面我会为您列举和解释这些操作:
std::string str1; // 默认构造,空字符串
std::string str2("Hello"); // 从C风格字符串构造
std::string str3 = "World"; // 使用=运算符从C风格字符串赋值
std::string str4(5, 'a'); // 用5个字符'a'构造,结果:"aaaaa"
+
或 +=
运算符:std::string str1 = "Hello";
std::string str2 = "World";
std::string str3 = str1 + " " + str2; // 结果:"Hello World"
str1 += " World"; // str1现在是"Hello World"
append()
方法:std::string str1 = "Hello";
str1.append(" World"); // str1现在是"Hello World"
std::string str = "Hello";
for (char c : str) {
std::cout << c << std::endl;
}
std::string str = "Hello";
for (size_t i = 0; i < str.size(); i++) {
std::cout << str[i] << std::endl;
}
std::string str = "Hello";
for (auto it = str.begin(); it != str.end(); ++it) {
std::cout << *it << std::endl;
}
std::reverse()
函数:#include
std::string str = "Hello";
std::reverse(str.begin(), str.end()); // str现在是"olleH"
std::string reverseString(const std::string& input) {
std::string result;
for (int i = input.size() - 1; i >= 0; i--) {
result.push_back(input[i]);
}
return result;
}
思路:双指针,首部和尾部交换,方向向内。
class Solution {
public void reverseString(char[] s) {
// 第一反应:双指针。
int size = s.length;
int left = 0;
int right = size-1;
while(right > left){
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
}
class Solution {
public:
void reverseString(vector<char>& s) {
// 双指针,头部和尾部位置交换,方向向内
int left = 0;
int right = s.size() - 1;
while(left<right){
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
};
思路:双指针。找到交换位置的起始和结束位置,依次交换即可。
通过for循环里面的i += 2*k
,就可以找到每次交换的起始位置,因为i是从0开始的(如果从i=-1开始就是2k的位置,也就是交换起始位置的前一位)。
下面就是判断结束位置,但是结束位置要分情况,就是最有一个2k结束之后剩下的部分。
>k 则slow ,slow+k-1
的部分进入交换;
关键点:如何找到一种很好的方式确定这些位置,还有特殊情况的判定比较关键。
class Solution {
public String reverseStr(String s, int k) {
// 双指针
// 在for循环的时候就将2k找到 不用一步步遍历去找
// 清楚需要几个变量: k, 2k; 交换的first,end,需要知道四个变量的位置
/* 其中k和2k可以通过for确定;first的位置也可以通过佛如确定,
可以理解为当前i的位置就是交换的起始位置,而end的位置由于情况不同要分类,
所以通过Math.min(size-1, slow+k-1),表示当前s(i或者上一个2k后一位)到末尾还剩多少,
小于k就是size-1 ,大于k就是slow+k-1(-1 是因为for是从i开始的,实际上i的位置
可以理解为2k的后一个位置。例如,k=2 (0, 4, 8)都是交换的起始位置。)
*/
int size = s.length();
char[] ch = s.toCharArray();
for(int i=0;i<size;i += 2*k){
int slow = i;
int last = Math.min(size-1, slow+k-1);
while(slow<last){
ch[slow] ^= ch[last];
ch[last] ^= ch[slow];
ch[slow] ^= ch[last];
slow++;
last--;
}
}
return new String(ch);
}
}
C++:注意函数的使用
reverse(start, end)
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i+= (2*k)){ // i增加2k
// 如果总长度到当前i起点位置长度大于K,表示需要将前k个翻转
if(s.size() - i >=k){
reverse(s.begin()+i, s.begin()+i+k);
}
else{//如果总长度到当前i起点位置小于k,表示直接将i起点到结尾的翻转
reverse(s.begin()+i, s.end());
}
}
return s;
}
};
原题描述:
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1: 输入:s = “We are happy.”
输出:“We%20are%20happy.”
#思路
对于一些常用的java函数不够熟练。
思路:找到空格直接通过StringBuilder填充。
class Solution {
public String replaceSpace(String s) {
// StringBuilder 类似于python的列表 可以appen,可以修改里面的值
char[] ch = s.toCharArray(); //
StringBuilder sb = new StringBuilder();
for(int i=0;i<ch.length;i++){
if(ch[i]==' '){
sb.append("%20");
}
else{
sb.append(ch[i]);
}
}
return sb.toString();
}
}
思路:双指针,先按照空格多少扩充。然后从后往前一个个将原来的s添加到char[] 中。
class Solution {
public String replaceSpace(String s) {
// 双指针,好好了解一下扩充法。
// 先将原string扩充,然后从后向前填充,避免从前到后要把空格之后的往后移动
// 这里的替换%20 是三个字符
StringBuilder sb = new StringBuilder();
for(int i=0;i<s.length();i++){
if(s.charAt(i) == ' '){ // 如果找到空格就在sb最后在添加两个空格
sb.append(" ");
}
}
int first = s.length() -1; // 原s的长度
s = s + sb.toString(); // 不知道这个用法,s的拼接。s的扩充
int end = s.length() -1; // 扩充之后的长度,与first的差就是要填充的长度
char[] ch = s.toCharArray();
while(end>first){
if(ch[first] == ' '){
ch[end] ='0';
end--;
ch[end]='2';
end--;
ch[end] = '%';
}
else{
ch[end] = ch[first];
}
first--;
end--;
}
return new String(ch); // java字符串的常用函数要学
}
}
新题描述:
假定一段路径记作字符串 path,其中以 “.” 作为分隔符。现需将路径加密,加密方法为将 path 中的分隔符替换为空格 " ",请返回加密后的字符串。
示例 1:
输入:path = “a.aef.qerf.bb”
输出:“a aef qerf bb”
class Solution {
public:
string pathEncryption(string path) {
for(int i=0;i<path.size();i++){
if(path[i] == '.'){
path[i] = ' ';
}
}
return path;
}
};
需要三刷
class Solution {
public String reverseWords(String s) {
// 去除字符串中的多余空格
StringBuilder sb = trimSpaces(s);
// 翻转字符串
reverse(sb, 0, sb.length() - 1);
// 翻转每个单词
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder trimSpaces(String s) {
int left = 0, right = s.length() - 1;
// 去掉字符串开头的空白字符
while (left <= right && s.charAt(left) == ' ') {
++left;
}
// 去掉字符串末尾的空白字符
while (left <= right && s.charAt(right) == ' ') {
--right;
}
// 将字符串间多余的空白字符去除
// 这里多用了一个空间 来装去除多余空格之后的字符串
StringBuilder sb = new StringBuilder();
while (left <= right) {
char c = s.charAt(left);
if (c != ' ') {
sb.append(c);
} else if (sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
++left;
}
return sb;
}
public void reverse(StringBuilder sb, int left, int right) {
while (left < right) {
char tmp = sb.charAt(left);
sb.setCharAt(left++, sb.charAt(right));
sb.setCharAt(right--, tmp);
}
}
public void reverseEachWord(StringBuilder sb) {
int n = sb.length();
int start = 0, end = 0;
while (start < n) {
// 循环至单词的末尾
while (end < n && sb.charAt(end) != ' ') {
++end;
}
// 翻转单词
reverse(sb, start, end - 1);
// 更新start,去找下一个单词
start = end + 1;
++end;
}
}
}
必须掌握
class Solution {
public:
void reverse(string& s, int start, int end){
for(int i=start,j=end;i<j;i++,j--){
swap(s[i], s[j]);
}
}
// 这一步的逻辑想不出来,我只会最基础的分情况删除。
void removeblank(string& s){ //
int slow = 0;
for(int fast=0;fast<s.size();++fast){
// 和27题的区别是:多了一个添加空格的处理
if(s[fast] != ' '){ // 遇到一个新的单词,在操作。不然fast一直往后走。
if(slow != 0){ // 第一个单词的时候跳过,后面就是在遇到一个新单词之后,现在这个单词的前面加一个空格
s[slow++] = ' ';
}
while(fast < s.size() && s[fast] != ' '){ //在遇到空格之前,将单词往前移动
s[slow++] = s[fast++];
}
}
}
s.resize(slow);
}
string reverseWords(string s) {
removeblank(s); //去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。
reverse(s, 0, s.size() - 1);
int start = 0; //removeExtraSpaces后保证第一个单词的开始下标一定是0。
for (int i = 0; i <= s.size(); ++i) {
if (i == s.size() || s[i] == ' ') { //到达空格或者串尾,说明一个单词结束。进行翻转。
reverse(s, start, i - 1); //翻转,注意是左闭右闭 []的翻转。
start = i + 1; //更新下一个单词的开始下标start
}
}
return s;
}
};
class Solution {
public String reverseLeftWords(String s, int n) {
StringBuilder sb = new StringBuilder();
for(int i=0;i<n;i++){
sb.append(s.charAt(i));
}
int fast = n;
int slow = 0;
char[] ch = s.toCharArray();
while(s.length()>fast){
ch[slow] = ch[fast];
slow++;
fast++;
}
StringBuilder sb_1 = new StringBuilder();
for(int i=0;i<s.length()-n;i++){
sb_1.append(ch[i]);
}
sb_1.append(sb);
return sb_1.toString();
}
}
解法二:也可以翻转局部、然后在翻转整体。
class Solution {
public String reverseLeftWords(String s, int n) {
// 依据代码随想录的提示,先翻转局部,再反转整体。
String s1 = reverseSub(s, 0, n-1);
String s2 = reverseSub(s1, n, s.length()-1);
String s3 = reverseSub(s2,0,s.length()-1);
return s3;
}
public String reverseSub(String s, int start, int end){
char[] ch = s.toCharArray();
while(end>start){
ch[start] ^= ch[end];
ch[end] ^= ch[start];
ch[start] ^= ch[end];
end--;
start++;
}
return new String(ch);
}
}