/////////////////////////////////////////////////////////////////////////////////////////////
// 1.1 题目一:赋值运算符函数
class CMyString
{
public:
// 默认函数
CMyString();
CMyString(const CMyString&);
CMyString& operator=(const CMyString&);
~CMyString();
void SetString(const char\* pszStr)
{
// 释放旧数据
Destroy();
CopyData(pszStr);
}
void Print()
{
if (m\_pszData)
{
cout << m\_pszData << endl;
}
}
void Destroy()
{
if (m\_pszData)
{
delete \[\] m\_pszData;
m\_pszData = NULL;
}
}
void CopyData(const char\* pszStr)
{
if (pszStr)
{
int iLen = strlen(pszStr);
m\_pszData = new char\[iLen + 1\];
strncpy(m\_pszData, pszStr, iLen + 1);
m\_pszData\[iLen\] = '\\0';
}
}
private:
char* m_pszData;
};
// 默认构造函数
CMyString::CMyString()
:m_pszData(NULL)
{
}
//拷贝构造函数
CMyString::CMyString(const CMyString& other)
{
cout << "CMyString Copy Constructor!!!!" << endl;
// 释放旧数据
//Destroy(); // 这里不能释放,因为没有初始化
CopyData(other.m\_pszData);
}
//赋值操作符
CMyString& CMyString::operator=(const CMyString& other)
{
cout << "CMyString Assignment Operator!!!!" << endl;
#if 0 // 初级程序员!!!!
if (this != &other)
{
Destroy();
CopyData(other.m_pszData);
}
#else
//高级程序员 需要考虑异常 --> 内存不足,导致new char 抛出异常
// 实现异常安全性:
// 1.先new分配新内容在使用delete释放旧内容 --> 确保抛出异常时原来的数据不会被改变!!!
// 2.先创建一个临时实例,再交换临时实例和原来的内容 --> 推荐这种方法!!!!
if (this != &other)
{
// 调用拷贝构造函数创建临时实例
CMyString strTmp(other);
char * pTmp = strTmp.m_pszData;
strTmp.m_pszData = m_pszData; // strTmp调用析构函数时,会释放原来实例中的m_pszData!!!!
m_pszData = pTmp;
}
#endif
return *this;
}
//析构函数
CMyString::~CMyString()
{
Destroy();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// 1.2 题目二:单例模式测试
extern CMutex g_stMutex; // 这个在ThreadTest.cpp中定义了,这个声明一下!!!!
class CSingletonTest
{
public:
CSingletonTest() :m_iCount(0){}
~CSingletonTest(){}
void AddCount() { m_iCount++; }
void SubCount() { m_iCount--; }
int GetCount() { return m_iCount; }
private:
int m_iCount;
};
class CSingleton_1
{
protected:
// 禁止外部调用这几个函数
CSingleton_1(){}
~CSingleton_1(){}
CSingleton_1(const CSingleton_1&);
CSingleton_1& operator=(const CSingleton_1&);
};
///////////////////////////////////////////////////////
// 懒汉模式
//类加载进来,没有对象,只有调用了getInstance方法时,才会创建对象。
//延迟加载形式。 并发过程中存在安全隐患。
template
class CSingleton_2 : public CSingleton_1
{
public:
static TYPE* GetInstance()
{
if (NULL == m_pSingleton)
{
cout << "Try Lock --------------->" << endl;
m_pSingleton = new CSingleton_2
}
return &m\_pSingleton->m\_stInstance;
}
private:
static CSingleton_2
TYPE m_stInstance;
private:
// 自动释放内存(不需要定义也可以,程序结束是系统会自动回收)
class CGarbo
{
public:
~CGarbo()
{
if (m_pSingleton)
{
delete m_pSingleton;
m_pSingleton = NULL;
}
}
};
static CGarbo garbo;
};
template
CSingleton_2
typedef CSingleton_2
////////////////////////////////////////////////////////////
// 加锁的懒汉实现
template
class CSingleton_3 : public CSingleton_1
{
public:
static TYPE* GetInstance()
{
if (NULL == m_pSingleton)
{
cout << "Try Lock --------------->" << endl;
CLock lock(g_stMutex);
if (NULL == m_pSingleton)
{
m_pSingleton = new CSingleton_3
}
}
return &m_pSingleton->m_stInstance;
}
private:
static CSingleton_3
TYPE m_stInstance;
};
template
CSingleton_3
typedef CSingleton_3
////////////////////////////////////////////////////////////////
// 饿汉模式
template
class CSingleton_4 : public CSingleton_1
{
public:
static TYPE* GetInstance()
{
//return &(const_cast
return &(const_cast
}
private:
const static CSingleton_4
TYPE m_stInstance;
};
template
const CSingleton_4
typedef CSingleton_4
////////////////////////////////////////////////////////////////////////
// 多线程测试函数
template
class CSingletonThreadTest : public CThread
{
public:
CSingletonThreadTest(const string& str) :m_szThreadName(str) {}
~CSingletonThreadTest(){}
virtual void Run()
{
for (int i = 0; i < 5000; i++)
{
//CLock Lock(g\_stMutex);
TYPE::GetInstance()->AddCount();
//cout << m\_szThreadName << ": " << TYPE::GetInstance()->GetCount() << endl;
}
}
private:
string m_szThreadName;
};
template
void SingletonTestFunc()
{
//double dStart = clock();
// 1.单线程测试
TYPE::GetInstance()->AddCount();
TYPE::GetInstance()->AddCount();
cout << typeid(TYPE::GetInstance()).name() << ": Count = " << TYPE::GetInstance()->GetCount() << endl;
CSingletonThreadTest<TYPE> Test1("Test1");
Test1.Start();
CSingletonThreadTest<TYPE> Test2("Test2");
Test2.Start();
CSingletonThreadTest<TYPE> Test3("Test3");
Test3.Start();
CSingletonThreadTest<TYPE> Test4("Test4");
Test4.Start();
CSingletonThreadTest<TYPE> Test5("Test5");
Test5.Start();
CT\_SLEEP(10);
cout << "SingletonTestFunc : " << TYPE::GetInstance()->GetCount() << endl;
//cout << "花费时间: " << (clock() - dStart) / CONST\_1000 << endl;
}
void SingletonPatternTestFunc()
{
cout << "\n\n --------------- SingletonPatternTestFunc Start -------------->" << endl;
//CSingleton\_2TestFunc();
SingletonTestFunc<SingletonTest2>();
cout << "===================================================>>>" << endl;
SingletonTestFunc<SingletonTest3>();
cout << "===================================================>>>" << endl;
SingletonTestFunc<SingletonTest4>();
cout << "\\n\\n --------------- SingletonPatternTestFunc End -------------->" << endl;
}
//////////////////////////////////////////////////////////////////////////////
// 1.3 题目三:二维数组中的查找
//二位数组查找 题目描述
//在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
//请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
bool FindNum(int target, vector
{
int iRow = vect.size();
int iCol = vect[0].size();
//从左上角开始遍历
int i = 0, j = iCol - 1;
while (i <= iRow - 1 && j >= 0) //保证数组不能越界
{
if (vect\[i\]\[j\] > target)
{
j--;
}
else if (vect\[i\]\[j\] < target)
{
i++;
}
else
{
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
// 1.4 题目四:替换空格
// 请实现一个函数,把字符串中每个空格替换成"%20";例如输入:"We Are Happy!" --> "We%20Are%20Happy!"
//时间复杂度O(n), 空间复杂度O(1)
char* StrReplace(char* pszStr, int iLen, char ch, const char* pszReStr)
{
assert(pszStr != NULL && pszReStr != NULL &&iLen >= 0);
char\* pTmp = pszStr;
int iFindNum = 0;
// 1.查找字符串中ch个数
while (\*pTmp != '\\0')
{
if (\*pTmp++ == ch)
{
iFindNum++;
}
}
// 2.新字符串长度
int iOldLen = strlen(pszStr);
int iReLen = strlen(pszReStr);
int iNewLen = iOldLen + (iReLen - 1)\* iFindNum; // 这里减1 待替换字符串长度 - 原来字符长度
if (iNewLen > iLen)
{
return NULL;
}
// 3.从后往前赋值字符串
// 这里为什么不用 i = iOldLen - 1; --> 复制最后的'\\0';
for (int i = iOldLen; i >= 0 && iNewLen > i; i--)
{
if (pszStr\[i\] == ch)
{
for (int j = iReLen - 1; j >= 0; j--)
{
pszStr\[iNewLen--\] = pszReStr\[j\];
}
}
else
{
pszStr\[iNewLen--\] = pszStr\[i\];
}
}
#if 0
while (iOldLen >= 0 && iNewLen > iOldLen)
{
if (pszStr[iOldLen] == ch)
{
for (int i = iReLen - 1; i >= 0; i--)
{
pszStr[iNewLen--] = pszReStr[i];
}
}
else
{
pszStr[iNewLen--] = pszStr[iOldLen];
}
iOldLen--;
}
#endif
return pszStr;
}
///////////////////////////////////////////////////////////////////
// 7. 与题目四相关题目
// 有两个排序数组A1, A2, A1的末尾有足够多的的空间容纳A2,实现一个函数,把A2中所有数字插入A1中且所有的数字的有序的!
//方法一:从前往后比较,需要额外的空间
//时间复杂度O(2n), 空间复杂度O(n)
void MergeTwoArray1(int aiArrayA[], int iNumA, int aiArrayB[], int iNumB)
{
const int MAX_ARRAY_COUNT = iNumA + iNumB;
vector
int i = 0, j = 0, k = 0;
// 1. 比较两个数组,把较小的加入新的数组
while (i < iNumA &&j < iNumB)
{
if (aiArrayA\[i\] < aiArrayB\[j\])
{
vect\[k++\] = aiArrayA\[i++\];
}
else
{
vect\[k++\] = aiArrayB\[j++\];
}
}
// 2.把剩余的元素加到新数组
while (i < iNumA)
{
vect\[k++\] = aiArrayA\[i++\];
}
while (j < iNumB)
{
vect\[k++\] = aiArrayB\[j++\];
}
// 3.把数据复制到数组A
k = 0;
for (auto it : vect)
{
aiArrayA\[k++\] = it;
}
}
// 方法二:从后往前比较,不需要额外的空间
//时间复杂度O(n), 空间复杂度O(1)
void MergeTwoArray2(int aiArrayA[], int iNumA, int aiArrayB[], int iNumB)
{
int iNewNum = iNumA + iNumB - 1;
int i = iNumA - 1;
int j = iNumB - 1;
// 从数组后往前比较,就不存在重叠的情况了!!!
while (i >= 0 && j >= 0)
{
if (aiArrayA\[i\] > aiArrayB\[j\])
{
aiArrayA\[iNewNum--\] = aiArrayA\[i--\];
}
else
{
aiArrayA\[iNewNum--\] = aiArrayB\[j--\];
}
}
while (i >= 0)
{
aiArrayA\[iNewNum--\] = aiArrayA\[i--\];
}
while (j >= 0)
{
aiArrayA\[iNewNum--\] = aiArrayB\[j--\];
}
}
原文链接:https://codeburst.io/redis-what-and-why-d52b6829813
什么是redis和为什么使用redis?
原文链接:https://blog.csdn.net/FX677588/article/details/70157088
C++11新特性:
- 新增基于范围的for循环;
- 自动类型推断 auto;
- 匿名函数 Lambda;
- 后置返回类型(tailng-return-type);
- 显示重写(覆盖)override和final;
- 空指针常量 nullptr;
- long long int类型;
- 模板的别名;
- 允许sizeof运算符可以再类型数据成员上使用,无需明确对象;
- 线程支持;
最近在学习redis相关知识,分享一个个人觉得比较好的视频教程:
视频链接:https://study.163.com/course/courseMain.htm?courseId=1003806066
手机扫一扫
移动阅读更方便
你可能感兴趣的文章