剑指offer的练习和总结(1)

面试题1

题目:为类型CMyString的声明添加赋值运算符
书本答案

class CMYString
{
public:
 CMYString& operator=(const CMYString& str);
private:
 char* m_data;
};
CMYString& CMYString::operator=(const CMYString &str)//这个赋值运算符的高级改法
{
 if (this != &str)//原来的那种先删在new如果new出异常,这个实例就会出错。
 {
  CMYString strTemp(str);
  char* pTemp = strTemp.m_data;
  strTemp.m_data = m_data;
  m_data = pTemp;
 }
 return *this;
}

虽然我的第一写法是书本的第一种写法,可是那种写法作者认为delete掉再new如果new失败会抛出异常,容易引起崩溃。

这里之前我不解,delete掉后内存不是直接回归到堆里面了吗?再new的话内存再不济也会有delete掉的内存量吧。
查阅过资料才知道,这个和操作系统有关,操作系统是根据它的内部算法调度什么时候回收的,可能立即回收,也可能很迟再回收。所以还是会可能产生异常的。

还有就是这个类名可知是仿写string类,应该只有一个变量,如果很多变量,就得一个一个写,浪费效率。
其实还可以改进,使用C++11的移动语义。就会更加节省效率。

面试题2

没什么好讲的,单例模式是C++/Java程序员必会的吧。

面试题3

找出数字重复的数字

int main()
{
 int a[10] = { 1,4,2,4,4,0,7,9,2,9 };
 vector<int>b;
 set<int>c;
 for(auto i:a)
 {
  b.push_back(i);
 }
 sort(b.begin(), b.end());
 for (auto i = 1;i < b.size();i++)
 {
  if (b[i] == b[i - 1]||b[i]==b[i+1])
  {
   c.insert(b[i]);
  }
 }
 for (auto i : c)
 {
  cout << i << " ";
 }
 return 0

我的思路就是先排序,因为排序过后,如果一个数字重复的话,那么这个数字的前面或者后面都是一样的,所以一样的就放在set上,set会把重复的删除,再输出set。
这样写的时间复杂度是(n)。就是需要使用到STL的函数了。

41页题目2

int main()//41页题目2
{
 int a[8]{ 2, 3, 5, 4, 3, 2, 6, 7 };
 set<int>b;
 for (int i = 1;i < 8;i++)
 {
  for (int j = i-1 ;j < 8;j++)
  {
   if (a[i] ==a[j])
   {
    b.insert(a[i]);
   }
  }
 }
 for (auto i : b)
 {
  cout << i << " ";
 }
 return 0;
}

不改变数组,就得建立其他的数据结构,关于重复的题目,set就是神器,这里类似于冒泡的方法拿每一个数都遍历一遍数组,这些数再放进set里面萃取出来就是重复的数。

面试题4

这道题在原来准备蓝桥杯的时候好像练过,那时候不会就把这道题背下来了,就差不多像像地写下来了。下面是

bool Find(int* martix, int rows, int columns, int number);
int main03()//44页面试题4
{
 int a[4][4] = { 1,2,8,9,2,4,9,12,4,7,10,13,6,8,11,15 };
 bool aa = Find(*a, 4, 4, 1);
 if (aa)
 {
  cout << "有" << endl;
 }
 else
 {
  cout << "没有" << endl;
 }
 return 0;
}
bool Find(int* martix, int rows, int columns, int number)
{
 bool found = false;
 if (martix != nullptr && rows > 0 && columns > 0)
 {
  int row = 0;
  int column = columns-1;
  while (row<rows&&column>=0)
  {
   if (martix[row * columns + column] == number)
   {
    found = true;
    break;
   }
   else if (martix[row * columns + column] > number)
   {
    column--;
   }
   else
   {
    row++;
   }
  }
 }
 return found;
}

面试题5

题目:替换空格,把“We are happy”里面的空格改成“%20”

int main()
{
 string a = "We are happy,";
 string b="";
 int q=0;
 for (int i = 0;i < a.size();i++)
 {
  if (a[i] == ' ')
  {
   a[i] = '%';
    string tmp(a.begin() + q, a.begin() + i);
    b += tmp;
    b += "20";
    q = i;     
  }
 }
 string tmp(a.begin() + q, a.end());
 b += tmp;
 cout << b;
 return 0;
}

我这里的思路是找出空格的位置,把空格置换成%,再把前面到空格位置的段提取出来放在空串里面,再加上剩下的字符串20;然后while循环继续这样做,while循环结束后,加上最后一个空格到最后一个字符的字符串。
时间复杂度就是(n),好像这样的写法比较巧妙,依托STL这种奇技淫巧可以很快写出代码,但是练不成那种算法思维,还是只靠原生的写法比较练吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值