C++初阶—string类(2)

目录

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.找出字符串中第一个只出现一次的字符


vs和g++下string结构的说明

注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节。

1.vs下string的结构

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个字节。

2.g++下string的结构

G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指 针将来指向一块堆空间,内部包含了如下字段:

  • 空间总大小
  • 字符串有效长度
  • 引用计数
struct _Rep_base
{
	size_type _M_length;
	size_type _M_capacity;
	_Atomic_word _M_refcount;
};
  • 指向堆空间的指针,用来存储字符串。

1.OJ——仅仅反转字母

917. 仅仅反转字母 - 力扣(LeetCode)

#include<ctype.h>
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<ctype.h>
//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;
//	}
//};

2.OJ——找字符串中第一个只出现一次的字符

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;
	}
};

3.OJ——字符串里面最后一个单词的长度

字符串最后一个单词的长度_牛客题霸_牛客网 (nowcoder.com)

#include<iostream>
#include<string>
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;
}

4.OJ——验证一个字符串是否是回文

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;
	}
};

5.OJ——字符串相加

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;
	}
};

6.其他字符串OJ题目

1.反转字符串

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;
    }
};

2.反转字符串中的的单词

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;
    }
};

3.字符串相乘

43. 字符串相乘 - 力扣(LeetCode)icon-default.png?t=N2N8https://leetcode.cn/problems/multiply-strings/description/

4.找出字符串中第一个只出现一次的字符

找出字符串中第一个只出现一次的字符_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N2N8https://www.nowcoder.com/practice/e896d0f82f1246a3aa7b232ce38029d4?tpId=37&&tqId=21282&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking

猜你喜欢

转载自blog.csdn.net/IfYouHave/article/details/130014913
今日推荐