目录
vs和g++下string结构的说明
1.vs下string的结构
2.g++下string的结构
1.OJ——仅仅反转字母
2.OJ——找字符串中第一个只出现一次的字符
3.OJ——字符串里面最后一个单词的长度
4.OJ——验证一个字符串是否是回文
5.OJ——字符串相加
6.其他字符串OJ题目
1.反转字符串
2.反转字符串中的的单词
3.字符串相乘
4.找出字符串中第一个只出现一次的字符
注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节。
string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字 符串的存储空间:
- 当字符串长度小于16时,使用内部固定的字符数组来存放
- 当字符串长度大于等于16时,从堆上开辟空间
union _Bxty { // storage for small buffer or pointer to larger one value_type _Buf[_BUF_SIZE]; pointer _Ptr; char _Alias[_BUF_SIZE]; // to permit aliasing } _Bx;
这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内 部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。
其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量
最后:还有一个指针做一些其他事情。
故总共占16+4+4+4=28个字节。
G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指 针将来指向一块堆空间,内部包含了如下字段:
- 空间总大小
- 字符串有效长度
- 引用计数
struct _Rep_base { size_type _M_length; size_type _M_capacity; _Atomic_word _M_refcount; };
- 指向堆空间的指针,用来存储字符串。
917. 仅仅反转字母 - 力扣(LeetCode)
#include
class Solution {
public:
string reverseOnlyLetters(string s) {
size_t begin = 0;
size_t end = s.size() - 1;
while(begin < end)
{
while(begin < end && (!isalpha(s[begin])))
++begin;
while(begin < end && (!isalpha(s[end])))
--end;
swap(s[begin],s[end]);
++begin;
--end;
}
return s;
}
};
//#include
//class Solution {
//public:
// string reverseOnlyLetters(string s) {
// size_t begin = 0;
// size_t end = s.size() - 1;
// while (begin < end)
// {
// while (begin < end && (!isalpha(s[begin])))
// ++begin;
// while (begin < end && (!isalpha(s[end])))
// --end;
// swap(s[begin], s[end]);
// ++begin;
// --end;
// }
// return s;
// }
//};
387. 字符串中的第一个唯一字符 - 力扣(LeetCode)
class Solution {
public:
int firstUniqChar(string s) {
// 统计每个字符出现的次数
int count[256] = { 0 };
int size = s.size();
for (int i = 0; i < size; ++i)
count[s[i]] += 1;
// 按照字符次序从前往后找只出现一次的字符
for (int i = 0; i < size; ++i)
if (1 == count[s[i]])
return i;
return -1;
}
};
字符串最后一个单词的长度_牛客题霸_牛客网 (nowcoder.com)
#include
#include
using namespace std;
int main()
{
string line;
// 不要使用cin>>line,因为会它遇到空格就结束了
// while(cin>>line)
while (getline(cin, line))
{
size_t pos = line.rfind(' ');
cout << line.size() - pos - 1 << endl;
}
return 0;
}
125. 验证回文串 - 力扣(LeetCode)
class Solution {
public:
bool isLetterOrNumber(char ch)
{
return (ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'z')
|| (ch >= 'A' && ch <= 'Z');
}
bool isPalindrome(string s) {
// 先小写字母转换成大写,再进行判断
for (auto& ch : s)
{
if (ch >= 'a' && ch <= 'z')
ch -= 32;
}
int begin = 0, end = s.size() - 1;
while (begin < end)
{
while (begin < end && !isLetterOrNumber(s[begin]))
++begin;
while (begin < end && !isLetterOrNumber(s[end]))
--end;
if (s[begin] != s[end])
{
return false;
}
else
{
++begin;
--end;
}
}
return true;
}
};
415. 字符串相加 - 力扣(LeetCode)
class Solution {
public:
string addStrings(string num1, string num2) {
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
string strRet;
int next = 0;
while (end1 >= 0 || end2 >= 0 || next > 0)
{
int val1 = end1 >= 0 ? num1[end1] - '0' : 0;
int val2 = end2 >= 0 ? num2[end2] - '0' : 0;
int ret = val1 + val2 + next;
next = ret / 10;
strRet += ('0' + (ret % 10));
--end1;
--end2;
}
reverse(strRet.begin(), strRet.end());
return strRet;
}
};
//方法
class Solution {
public:
string addstrings(string num1, string num2)
{
// 从后往前相加,相加的结果到字符串可以使用insert头插
// 或者+=尾插以后再reverse过来
int end1 = num1.size() - 1;
int end2 = num2.size() - 1;
int value1 = 0, value2 = 0, next = 0;
string addret;
while (end1 >= 0 || end2 >= 0)
{
if (end1 >= 0)
value1 = num1[end1--] - '0';
else
value1 = 0;
if (end2 >= 0)
value2 = num2[end2--] - '0';
else
value2 = 0;
int valueret = value1 + value2 + next;
if (valueret > 9)
{
next = 1;
valueret -= 10;
}
else
{
next = 0;
}
//addret.insert(addret.begin(), valueret+'0');
addret += (valueret + '0');
}
if (next == 1)
{
//addret.insert(addret.begin(), '1');
addret += '1';
}
reverse(addret.begin(), addret.end());
return addret;
}
};
541. 反转字符串 II - 力扣(LeetCode)
class Solution {
public:
string reverseStr(string s, int k) {
int n = s.length();
for (int i = 0; i < n; i += 2 * k) {
reverse(s.begin() + i, s.begin() + min(i + k, n));
}
return s;
}
};
557. 反转字符串中的单词 III - 力扣(LeetCode)
class Solution {
public:
string reverseWords(string s) {
auto left = s.begin();
auto emp = find(s.begin(), s.end(), ' ');
auto right = emp;
reverse(left, right);
while (emp != s.end())
{
left = emp;
left ++;
emp = find(left, s.end(), ' ');
right = emp;
reverse(left, right);
}
return s;
}
};
43. 字符串相乘 - 力扣(LeetCode)https://leetcode.cn/problems/multiply-strings/description/
找出字符串中第一个只出现一次的字符_牛客题霸_牛客网 (nowcoder.com)https://www.nowcoder.com/practice/e896d0f82f1246a3aa7b232ce38029d4?tpId=37&&tqId=21282&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking