string模拟部分实现(字符串) 部分OJ题练习

string模拟实现中出现的个别问题:下述string类没有显式定义其拷贝构造函数与赋值运算符重载,此时编译器会合成默认的,当用s1构造s2时,编译器会调用默认的拷贝构造。最终导致的问题是,s1、s2共用同一块内存空间,在释放时同一块空间被释放多次而引起程序崩溃,这种拷贝方式,称为浅拷贝。
string模拟部分实现(字符串) 部分OJ题练习
浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以 当继续对资源进项操作时,就会发生发生了访问违规。
深拷贝:如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。对于上述这种情况,在C++中给出了深拷贝的方法。

 //构造函数
    String(const String& s)
    {
        m_data = new char[strlen(s.m_data) + 1];
        strcpy(m_data, s.m_data);
    }
 //赋值函数
String& operator=(const String& s)
{
    if (this != &s);
    {
        delete[]m_data;
        m_data = new char[strlen(s.m_data) + 1];
        strcpy(m_data, s.m_data);
    }
    return *this;
}

但是在构造函数与赋值运算符重载时深拷贝也是最好的选择吗?并不是!在赋值函数中被释放了的空间并不一定可以再次申请成功,针对此情况有两种解决方式:

//赋值函数
String& operator=(const String& s)
{
    if (this != &s);
    {
        delete[]m_data;
        m_data = new char[strlen(s.m_data) + 1]; //释放了之后  不一定能在申请成功
        strcpy(m_data, s.m_data);
        //改进后的方法(1)
        char* new_data = new char[strlen(s.m_data) + 1];
        strcpy(new_data, s.m_data);
        delete[]m_data;
        m_data = new_data;
    }
    return *this;
}
        //方法(2)
    String& operator=(const String& s)
    {
        if (this != &s)
        {
            //这里的空间通过临时对象释放的
            String Tmp(s);  //构建一个临时对象
            char* tmp_data = m_data;
            m_data = Tmp.m_data;
            Tmp.m_data = tmp_data;
        }
        return *this;
    }

string的部分实现

//string模拟的实现
class String
{
public:
    //构造函数
    String(const char* str = " ")
    {
        m_data = new char[strlen(str) + 1];
        strcpy(m_data, str);
    }
    //构造函数
    String(const String& s)
    {
        m_data = new char[strlen(s.m_data) + 1];
        strcpy(m_data, s.m_data);
    }
    //赋值函数
    String& operator=(const String& s)
    {
        if (this != &s)
        {
            //这里的空间通过临时对象释放的
            String Tmp(s);  //构建一个临时对象
            char* tmp_data = m_data;
            m_data = Tmp.m_data;
            Tmp.m_data = tmp_data;
        }
        return *this;
    }
    //析构函数
    ~String()
    {
        if (m_data)
        {
            delete[]m_data;
            m_data = nullptr;
        }
    }
private:
    char* m_data;
};

void main()
{
    String s1 = "abc";
    String s2 = "xyz";

    s2 = s1;
}

部分OJ题练习

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

//将字符串转化为统一的大小写
void main()
{
    string str = "ABC";
    transform(str.begin(), str.end(), str.begin(), tolower);
}

//字符串转化为整形
void main()
{
	const char* str = "1230";
	int value = atoi(str);  //通过atoi来转换
}
//字符串反转
void Reverse(string& s)
{
	int start = 0;
	int end = s.size() - 1;
	while (start < end)
	{
		char tmp = s[start];
		s[start] = s[end];
		s[end] = tmp;
		++start;
		--end;
	}
}
void main()
{
	string s = "abcxyz";
	Reverse(s);
	reverse(s.begin(), s.end());   //C++的用法  直接反转
	cout << s << endl;
}
//字符串相加
class Solution
{
public:
    string addStrings(string num1, string num2)
    {
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());

        int i, j;
        i = j = 0;
        int sign = 0;//进位

        string result;
        int sum = 0;

        while (i < num1.size() && j < num2.size())
        {
            sum = num1[i] - '0' + num2[j] - '0' + sign;
            if (sum >= 10)
            {
                sign = 1;
                sum -= 10;
            }
            else
                sign = 0;
            result.push_back(sum + '0');
            i++;
            j++;
        }
        while (i < num1.size())
        {
            sum = num1[i] - '0' + sign;
            if (sum >= 10)
            {
                sum -= 10;
                sign = 1;
            }
            else
                sign = 0;
            result.push_back(sum + '0');
            i++;
        }

        while (j < num2.size())
        {
            sum = num2[j] - '0' + sign;
            if (sum >= 10)
            {
                sum -= 10;
                sign = 1;
            }
            else
                sign = 0;
            result.push_back(sum + '0');
            j++;
        }
        if (sign > 0)
            result.push_back(sign + '0');
        reverse(result.begin(), result.end());
        return result;
    }
};
//字符串中的第一个唯一字符
class Solution {
public:
    int firstUniqChar(string s)   //暴力求解法
    {
        int j;
        for (int i = 0;i < s.size();++i)
        {
            for (j = 0;j < s.size();++j)
            {
                if (j == i)
                    continue;
                if (s[j] == s[i])
                    break;
            }
            if (j >= s.size())
                return i;
        }
        return -1;
    }
};
class Solution {
public:
    int firstUniqChar(string s) //通过hash表来查找
    {
        //0~255 hash[0]~hash[255]
        int hash[256] = { 0 };
        for (int i = 0;i < s.size();++i)
            hash[s[i]]++;

        for (int i = 0;i < s.size();++i)
        {
            if (hash[s[i]] == 1)
                return i;
        }
        return -1;
    }
};
//字符串最后一个单词的长度
int GetLengthLastWord(string& str)
{
    int pos = str.rfind(' ');
    if (pos == string::npos)
        return str.size();
    return str.size() - pos - 1;
}
void main()
{
    string str;
    getline(cin, str);
    cout << GetLengthLastWord(str);
    
}
//判断字符串是否回文
class Solution {
public:
    bool IsLetterOrDig(char ch)
    {
        if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))
            return true;
        return false;
    }
    bool isPalindrome(string s)
    {
        if (s.size() <= 1)
            return true;
        transform(s.begin(), s.end(), s.begin(), toupper);  //将字符串统一转化为大写

        int left = 0;
        int right = s.size() - 1;

        while (left < right)
        {
            while (left < right && !IsLetterOrDig(s[left]))
                left++;
            while (right > left && !IsLetterOrDig(s[right]))
                right--;
            if (s[left] != s[right])
                return false;
            left++;
            right--;
        }
        return true;
    }
};
上一篇:C/C++解OJ题--杨辉三角||(动态规划之搬砖)


下一篇:P1484-种树