面试总结之C/C++

source codephp

  • https://github.com/haotang923/interview/blob/master/interview%20summary%20of%20C%20and%20CPP/html

学习笔记之IKM C++ 11 - 浩然119 - 博客园java

  • https://www.cnblogs.com/pegasus923/p/8465745.html

学习笔记之100 TOP Ikm C++ Online Test Questions - 浩然119 - 博客园node

  • https://www.cnblogs.com/pegasus923/p/8533582.html

面试总结之指针 - 浩然119 - 博客园linux


C

C structure,数据结构里有inter,char,float时,数据的内存布局会是怎样ios

  • 数据会以4位或是8位,16位等等方式对齐

为何会有这种对齐c++

  • 这是由于机器寻址就是按照这种方式进行的,这样能够一次而不是屡次读取必定数据

C pointer,指向数据结构与指向char的指针有区别吗git

  • 它们正作+1运算时产生的位移不一样

函数指针,什么是函数指针,有什么用处github

  • 函数指针是指向函数的指针,最大的用处是作回调函数,能够作接口函数,就像系统中断中的中断处理函数

设计一个函数,函数中有一段功能是对相关数据的结理,但具体的处理方式是不定的。面试

  • 将不定的处理方式设定成一个外部传来函数指针。(能够设计成这样 func(int a,int b,某种函数指针) )

如何对消息实现同步响应

  • 使用CALLBACK,回调函数
  • CALLBACK_百度百科
    • https://baike.baidu.com/item/CALLBACK/813549?fr=aladdin

struct和union的区别:

  1. 在存储多个成员信息时,编译器会自动给struct第个成员分配存储空间,struct能够存储多个成员信息,而union每一个成员会用同一个存储空间,只能存储最后一个成员的信息。
  2. 都是由多个不一样的数据类型成员组成,但在任何同一时刻,Union只存放了一个被先选中的成员,而结构体的全部成员都存在。
  3. 对于Union的不一样成员赋值,将会对其余成员重写,原来成员的值就不存在了,而对于struct的不一样成员赋值是互不影响的。
  • http://blog.csdn.net/firefly_2002/article/details/7954458

struct和class的区别:

  • Access Control and Constraints of Structures, Classes and Unions
    • https://msdn.microsoft.com/en-us/library/4a1hcx0y.aspx
Structures Classes Unions
class key is struct class key is class class key is union
Default access is public Default access is private Default access is public
No usage constraints No usage constraints Use only one member at a time
Default inheritance is public Default inheritance is private -
Could not use Template Could use Template -

static关键字至少有下列n个做用:

  1. 函数体内static变量的做用范围为该函数体,不一样于auto变量,该变量的内存只被分配一次,所以其值在下次调用时仍维持上次的值;
  2. 在模块内的static全局变量能够被模块内所用函数访问,但不能被模块外其它函数访问;
  3. 在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
  4. 在类中的static成员变量属于整个类所拥有,对类的全部对象只有一份拷贝;
  5. 在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,于是只能访问类的static成员变量。

const关键字至少有下列n个做用:

  1. 欲阻止一个变量被改变,可使用const关键字。在定义该const变量时,一般须要对它进行初始化,由于之后就没有机会再去改变它了;
  2. 对指针来讲,能够指定指针自己为const,也能够指定指针所指的数据为const,或两者同时指定为const;
  3. 在一个函数声明中,const能够修饰形参,代表它是一个输入参数,在函数内部不能改变其值;
  4. 对于类的成员函数,若指定其为const类型,则代表其是一个常函数,不能修改类的成员变量;
  5. 对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。

#include “filename.h”和#include <filename.h>的区别

  • #include “filename.h”是指编译器将从当前工做目录上开始查找此文件
  • #include <filename.h>是指编译器将从标准库目录中开始查找此文件

用C语言,将一个数字乘以7倍的效率最快的方法是什么? 

 


C++

变量的内存分区

  • C/C++的四大内存分区 - CSDN博客
    • https://blog.csdn.net/K346K346/article/details/45592329

size_t_百度百科

  • http://baike.baidu.com/link?url=sh8RRfasW1QG-PhcWPZhfcZ75Uw-KYLKh443jzpNg36hVk1Fu7WeTh4lEPLCuBx_iT0wglX5MRQUqXJMWV-oUK

什么是深浅拷贝?

  • 浅拷贝是建立了一个对象用一个现成的对象初始化它的时候只是复制了成员(简单赋值)而没有拷贝分配给成员的资源(如给其指针变量成员分配了动态内存); 深拷贝是当一个对象建立时,若是分配了资源,就须要定义本身的拷贝构造函数,使之不但拷贝成员也拷贝分配给它的资源

短小而被频繁调用的程序如何处理?

  • C语言用宏代替。
  • C++用inline,内联函数机制。
  • 内联函数能够获得宏的替换功能,全部可预见的状态和常规函数的类型检查。

指针和引用的初始化区别

  • 引用被建立的同时必须被初始化(指针则能够在任什么时候候被初始化)。
  • 不能有NULL 引用,引用必须与合法的存储单元关联(指针则能够是NULL)。
  • 一旦引用被初始化,就不能改变引用的关系(指针则能够随时改变所指的对象)。

delete数组指针,只delete第一个后果

  • 内存泄漏 

什么是拷贝构造函数?

  • 它是单个参数的构造函数,其参数是与它同属一类的对象的(常)引用;类定义中,若是未提供本身的拷贝构造函数,C++提供一个默认拷贝构造函数,该默认拷贝构造函数完成一个成员到一个成员的拷贝

要在C++ 防止对象被复制,有什么方法

  • 将复制构造函数变成私有函数

虚析构函数

  • 虚析构函数_百度百科
    • https://baike.baidu.com/item/虚析构函数
    • 虚析构函数是为了解决 基类指针指向派生类对象,并用基类的指针删除派生类对象。
    • 若是某个类不包含 虚函数,那通常是表示它将不做为一个基类来使用。当一个类不许备做为基类使用时,使析构函数为虚通常是个坏主意。由于它会为类增长一个 虚函数表,使得对象的体积翻倍,还有可能下降其可移植性
    • 因此基本的一条是:无端的声明虚析构函数和永远不去声明同样是错误的。实际上,不少人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。抽象类是准备被用作基类的,基类必需要有一个虚析构函数,纯虚函数会产生抽象类,因此方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。

函数对象功能

  • 能够用做相似C里的回调函数,也能够用做函数功能的组合

C++虚拟机制

  • 用来实现多态

抽象类能被实例化吗

  • 不能,只能继承抽象类,实现抽象类的函数

Virtual:虚函数:派生类能够覆盖掉的函数,纯虚函数:只是个空函数,没有函数实现体。

C++如何实现JAVA接口

  • java接口_百度百科
    • http://baike.baidu.com/link?url=hoPdmBnxPUNPpyCRPD80NQVbOPS0qT5IoI1jezWUDT4Dz0MdgaVrPEurjtacqy6rJRZxO0CrQCNqDn5czUriNK
  • C++中的抽象类以及接口的区别联系_Linux编程_Linux公社-Linux系统门户网站
    • http://www.linuxidc.com/Linux/2012-10/73243.htm

Object Slicing

  • Object slicing - Wikipedia
    • https://en.wikipedia.org/wiki/Object_slicing
    • In C++ programming, object slicing occurs when an object of a subclass type is copied to an object of superclass type: the superclass copy will not have any of the member variables defined in the subclass. These variables have, in effect, been "sliced off".) More subtly, object slicing can also occur when an object of a subclass type is copied to an object of the same type by the superclass's assignment operator, in which case some of the target object's member variables will retain their original values instead of being copied from the source object.
    • This issue is not inherently unique to C++, but it does not occur naturally in most other object-oriented languages — even C++'s relatives such as D, Java, and C# — because copying of objects is not a basic operation in those languages. (Instead, those languages prefer to manipulate objects via implicit references, such that only copying the reference is a basic operation.) In C++, by contrast, objects are copied automatically whenever a function takes an object argument by value or returns an object by value. Additionally, due to the lack of garbage collection in C++, programs will frequently copy an object whenever the ownership and lifetime of a single shared object would be unclear; for example, inserting an object into a standard-library collection, such as a std::vector, actually involves inserting a copy into the collection.
  • c++对象切割 - CSDN博客
    • https://blog.csdn.net/weiwangchao_/article/details/4702241

异常,异常的功能

  • 保证异常的健壮性,结构化处理出错信息

C++模板

  • 简化对相似函数的设计,好比要设计两个函数 abs(int a), abs(float a),就能够用模板去设计一个函数就能够了

STL containers内部实现的数据结构

  • vector :数组
  • list :链表
  • set / map / multimap / multiset :红黑树
  • unordered_set / unordered_multiset / unordered_map / unordered_multimap :Hash表
  • Containers - C++ Reference
    • http://www.cplusplus.com/reference/stl/
  • STL实现的底层数据结构简介 - CSDN博客
    • http://blog.csdn.net/huangkq1989/article/details/7277282

list v.s. vector

智能指针

  • 智能指针_百度百科
    • http://baike.baidu.com/link?url=-4Fxt6pJdzfT54y9W-fRgMxlSYiedMOkLOxNlQf67rz_wHTOhIvtESgw6s8sEdgGMy2PxyNj0VUNe_IpaSBnbK
    • 当类中有指针成员时,通常有两种方式来管理指针成员:一是采用值型的方式管理,每一个类对象都保留一份指针指向的对象的拷贝;另外一种更优雅的方式是使用智能指针,从而实现指针指向的对象的共享。
    • 智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象的指针指向同一对象。
    • 每次建立类的新对象时,初始化指针并将引用计数置为1;当对象做为另外一对象的副本而建立时,拷贝构造函数拷贝指针并增长与之相应的引用计数;对一个对象进行赋值时,赋值操做符减小左操做数所指对象的引用计数(若是引用计数为减至0,则删除对象),并增长右操做数所指对象的引用计数;调用析构函数时,析构函数减小引用计数(若是引用计数减至0,则删除基础对象)。
    • 实现引用计数有两种经典策略:一是引入辅助类,二是使用句柄类。
    • 为了不方案一中每一个使用指针的类本身去控制引用计数,能够用一个类把指针封装起来。封装好后,这个类对象能够出如今用户类使用指针的任何地方,表现为一个指针的行为。咱们能够像指针同样使用它,而不用担忧普通成员指针所带来的问题,咱们把这样的类叫句柄类。在封装句柄类时,须要申请一个动态分配的引用计数空间,指针与引用计数分开存储。
    • 智能指针是存储指向动态分配(堆)对象指针的类。除了可以在适当的时间自动删除指向的对象外,他们的工做机制很像C++的内置指针。智能指针在面对异常的时候格外有用,由于他们可以确保正确的销毁动态分配的对象。他们也能够用于跟踪被多用户共享的动态分配对象。
    • 事实上,智能指针可以作的还有不少事情,例如处理线程安全,提供写时复制,确保协议,而且提供远程交互服务。有可以为这些ESP (Extremely Smart Pointers)建立通常智能指针的方法,可是并无涵盖进来。
    • 智能指针的大部分使用是用于生存期控制,阶段控制。它们使用operator->和operator*来生成原始指针,这样智能指针看上去就像一个普通指针。
    • 这样的一个类来自标准库:std::auto_ptr。它是为解决资源全部权问题设计的,可是缺乏对引用数和数组的支持。而且,std::auto_ptr在被复制的时候会传输全部权。在大多数状况下,你须要更多的和/或者是不一样的功能。这时就须要加入smart_ptr类。
  •  智能指针(现代 C++)
    • https://msdn.microsoft.com/zh-cn/library/hh279674.aspx
  •  Smart pointer - Wikipedia, the free encyclopedia
    • https://en.wikipedia.org/wiki/Smart_pointer
  •  智能指针:从std::auto_ptr到std::unique_ptr - hanhuili的专栏 - 博客频道 - CSDN.NET
    • http://blog.csdn.net/hanhuili/article/details/8299912

RAII

  • RAII - 维基百科,自由的百科全书
  • RAII_百度百科
    • http://baike.baidu.com/link?url=cZ_EqWVrbxk9AIOFJ-9IrYDMRVaeEtubQlI-JKvquwrTkm9clZshXDLN9WM1Kth0W98ADgTckgMMEAwmQ3gZDq
    • RAII,也称为“资源获取就是初始化”,是c++等编程语言经常使用的管理资源、避免内存泄露的方法。它保证在任何状况下,使用对象时先构造对象,最后析构对象。
  • 对象全部资源 (RAII)
    • https://msdn.microsoft.com/zh-cn/library/hh438480.aspx

RTTI

  • RTTI事指运行时类型识别(Run-time type identification)在只有一个指向基类的指针或引用时肯定一个对象的准确类型。

volatile

  • volatile_百度百科
    •   http://baike.baidu.com/link?url=gPm-SmXKapujjcPjO3COGYDPSvH4VPOMabuV61XG7kM1kMhwX1AnNxF5_VZDiq7fizEaEfpYKLRBVgRt99BxOK
  • volatile (C++)
    •   https://msdn.microsoft.com/zh-cn/library/12a04hfd.aspx

大家要的C++面试题答案来了--基础篇


PROGRAMMING

What will be printed, and why?

 1 class A
 2 {
 3 public:
 4     A () : data (0) { SetData (); printf ("data=%d", data); }
 5     virtual void SetData () { data = 1; }
 6 protected:
 7     int data;
 8 };
 9 
10 class B : public A
11 {
12 public:
13     B () {}
14     virtual void SetData () { data = 2; }
15 };
16 
17 int main(int argc, char* argv[])
18 {
19     B b;
20     return 0;
21 }
View Code
  • data=1.
  • Because class B inherits class A, it would call constructor of A and B when constructing b. When calling the constructor of A, A::SetData() was called, so data was set to 1.

What's wrong, and how to fix?

1 class TryConst
2 {
3 public:
4     TryConst () {}
5 private:
6     const int aaa;
7 };
View Code
  • Const variable aaa should be initialized when being defined.
  • To fix it, we could take any one action as below.
    • 1) Initialize aaa in construct function
    • 2) Assign a value in this statement const int aaa;
    • 3) Remove keyword const

What's wrong, and how to fix?

1 class TryStatic
2 {
3 public:
4     TryStatic () : aa (0) {}
5 private:
6     static int aa;
7 };
View Code
  • Static variable could not be initialized inside the class.
  • To fix it, we could initialize it outside the class, e.g. int aa = 0. 

What will be printed, and why?

 1 class TestSize1
 2 {
 3 public:
 4     TestSize1 () : a (0) {}
 5     virtual void F () = 0;
 6 private:
 7     int a;
 8 };
 9 class TestSize2 : public TestSize1
10 {
11 public:
12     TestSize2 () : b (1) {}
13     virtual void F () { b = 3; }
14 private:
15     int b;
16 };
17 int main(int argc, char* argv[])
18 {
19     printf ("size of TestSize2 = %d", sizeof (TestSize2));
20     return 0;
21 }
View Code
  • In 32-bit environment, size of TestSize2 = 12.
  • 12 = TestSize2 virtual table pointer(4) + TestSize2::b(4) + TestSize1::a(4)

What's wrong, and how to fix?

 1 class P1
 2 {
 3 public:
 4     P1 () { p = new char [10]; }
 5     ~P1 () { delete [] p; }
 6 private:
 7     char * p;
 8 };
 9 class P2 : public P1
10 {
11 public:
12     P2 () { q = new char [20]; }
13     ~P2 () { delete [] q; }
14 private:
15     char * q;
16 };
17 
18 int main(int argc, char* argv[])
19 {
20     P1 * pp = new P2;
21     ...
22     delete pp;
23     return 0;
24 }
View Code
  • ~P2 would not be executed, which would cause memory leak.
  • To fix it, define ~P1() as virtual ~P1().

What's wrong, and how to fix?

 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 #include <iostream>
 9 using namespace std;
10 
11 class Thing {
12 public:
13     void    doSomething() { cout << __func__ << endl; }
14     Thing*    next;
15 };
16 
17 class Things {
18 public:
19     Things(Thing *myThing) : head(myThing), current(myThing) {}
20     
21     Thing*  First() {
22         return head;
23     }
24     
25     Thing*  Next() {
26         current = current->next;
27         return current;
28     }
29     
30     bool OK() {
31         if (current != nullptr)
32             return true;
33         else
34             return false;
35     }
36     
37 private:
38     Thing *head, *current;
39 };
40 
41 int main()
42 {
43     Thing*   myThing = new Thing;
44     Things myThings(myThing);
45     
46     // This is how we do with class Things
47     /*
48      doSomething
49      */
50     for (Thing *ptr = myThings.First(); myThings.OK(); myThings.Next()) {
51         ptr->doSomething();
52     }
53     
54     return 0;
55 }
View Code
  • When multiple access, the Next function will make the current pointer behave unexpected. E.g. A is calling doSomething(), and B issues Next(). When A issues Next(), actually the current node is not current->next but current->next->next.
  • To fix it, add a parameter for Next() => Next(Thing *currentNode) so that it could make sure that the next node would not be changed by others.

strcpy,使用strcpy需注意什么,为何,有什么更安全的函数

  • 注意源字符串是是以‘\0'结束的,strcpy就是拷到源字符串中‘\0'才结束,可能使用strncpy来替换。
  • assert(编程术语)_百度百科(https://baike.baidu.com/item/assert/10931289?fr=aladdin#4)
 1 #include <assert.h>
 2 
 3 //    为了实现链式操做,将目的地址返回
 4 char * strcpy(char *strDest, const char *strSrc)
 5 {
 6     // 对原地址和目的地址加非0断言
 7     assert(strDest != NULL && strSrc != NULL);
 8 
 9     char *address = strDest;
10     
11     while ((*strDest++ = *strSrc++) != '\0');
12     
13     return address;
14 }
View Code

strlen

 1 #include <assert.h>
 2 
 3 // 入参const
 4 int strlen(const char *str)
 5 {
 6     // 断言字符串地址非0
 7     assert(str != NULL);
 8     
 9     int len = 0;
10     
11     while ((*str++) != '\0') len ++;
12     
13     return len;
14 }
View Code

struct数组定义和初始化,以及for循环第一次循环会执行哪些语句,比较tricky,注意i--语句执行前后顺序。

 1 //
 2 //  main.c
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/11/22.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 
 9 #include <stdio.h>
10 
11 // Calculate the number of elements in x
12 #define myMacro(x) sizeof((x)) / sizeof((x[0]))
13 
14 // Definition and initialization of array of struct
15 struct structTest {
16     int   digit;
17     char *number;
18 } strTest[] = { {1, "one"},     {2, "two"},
19                 {3, "three"},   {4, "four"},
20                 {5, "five"},    {6, "six"},
21                 {7, "seven"},   {8, "eight"},
22                 {9, "nine"},    {10, "ten"} };
23 
24 int getNumber1(char *number)
25 {
26     int i;
27     
28     printf("Before for-loop : i = %d\n\n", i);
29 
30     for (i = myMacro(strTest); i --;) // i -- will be executed at the BEGINNING of the first loop
31     {
32         printf("Loop i = %d\n", i);
33         printf("[%d : %s]\n", strTest[i].digit, strTest[i].number);
34         if (strcmp(strTest[i].number, number)) // return value 0 only if the contents of both strings are equal
35         {
36             printf("Before continue : %d\n", i);
37             continue;
38         }
39         printf("Before break : %d\n", i);
40         break;
41     }
42     
43     printf("\nAfter for-loop : %d\n\n", i);
44     return i;
45 }
46 
47 int getNumber2(char *number)
48 {
49     int i;
50     
51     printf("Before for-loop : i = %d\n\n", i);
52     
53     for (i = myMacro(strTest); ; i --) // i -- will be executed at the END of the first loop
54     {
55         printf("Loop i = %d\n", i);
56         printf("[%d : %s]\n", strTest[i].digit, strTest[i].number);
57         if (strcmp(strTest[i].number, number))
58         {
59             printf("Before continue : %d\n", i);
60             continue;
61         }
62         printf("Before break : %d\n", i);
63         break;
64     }
65     
66     printf("\nAfter for-loop : %d\n\n", i);
67     return i;
68 }
69 
70 int main()
71 {
72     printf("myMacro(strTest) = %d\n\n", myMacro(strTest));
73     
74     printf("getNumber1(\"zero\") = %d\n\n", getNumber1("zero"));
75 
76     printf("getNumber1(\"nine\") = %d\n\n", getNumber1("nine"));
77     
78     printf("getNumber2(\"zero\") = %d\n\n", getNumber2("zero"));
79     
80     printf("getNumber2(\"nine\") = %d\n\n", getNumber2("nine"));
81     
82     return 0;
83 }
View Code
  • 执行结果能够看到getNumber1的第一次循环开始时已经执行i--,而getNumber2并无,缘由就在于i--位于不一样位置。
myMacro(strTest) = 10

Before for-loop : i = 0

Loop i = 9
[10 : ten]
Before continue : 9
Loop i = 8
[9 : nine]
Before continue : 8
Loop i = 7
[8 : eight]
Before continue : 7
Loop i = 6
[7 : seven]
Before continue : 6
Loop i = 5
[6 : six]
Before continue : 5
Loop i = 4
[5 : five]
Before continue : 4
Loop i = 3
[4 : four]
Before continue : 3
Loop i = 2
[3 : three]
Before continue : 2
Loop i = 1
[2 : two]
Before continue : 1
Loop i = 0
[1 : one]
Before continue : 0

After for-loop : -1

getNumber1("zero") = -1

Before for-loop : i = 0

Loop i = 9
[10 : ten]
Before continue : 9
Loop i = 8
[9 : nine]
Before break : 8

After for-loop : 8

getNumber1("nine") = 8

Before for-loop : i = 0

Loop i = 10
[0 : (null)]
(lldb)
View Code

编写类String的构造函数、析构函数、拷贝构造函数和赋值函数。

  • 类String的构造函数、析构函数和赋值函数 - dazhong159的专栏 - CSDN博客(http://blog.csdn.net/dazhong159/article/details/7894384)
  • 输入输出运算符必须是普通非成员函数,而不能是类的成员函数。不然,它们的左侧运算对象将是咱们的类的一个对象。假设输入输出运算符是某个类的成员,则它们也必须是istream或ostream的成员。然而,这两个类属于标准库,而且咱们没法给标准库中的类添加任何成员。固然,IO运算符一般须要读写类的非公有数据成员,因此IO运算符通常被声明为友元。
  • 注意delete释放资源以前,最好先判断是否nullptf,不然释放为nullptr的指针会报错。此处拷贝构造与赋值函数中,由于m_data不会为nullptr,因此能够不判断。
  1 #include <iostream>
  2 #include <string>
  3 using namespace std;
  4 
  5 class String {
  6 public :
  7     String (const char *str = NULL); // default initial value
  8     String (const String &other);
  9     ~ String (void);
 10     String & operator=(const String &other);
 11     friend ostream &operator<<(ostream &os, const String &str);
 12     friend istream &operator>>(istream &is, String &str);
 13 private :
 14     char *m_data;
 15 };
 16 
 17 // 普通构造函数
 18 String::String(const char *str)
 19 {
 20     if (str == NULL) { // empty string
 21         m_data = new char[1];
 22         *m_data = '\0';
 23     } else {
 24         int length = strlen(str);
 25         m_data = new char[length + 1];
 26         strcpy(m_data, str);
 27     }
 28 }
 29 
 30 // 析构函数
 31 String::~String(void)
 32 {
 33     delete[] m_data;
 34 }
 35 
 36 // 拷贝构造函数
 37 String::String(const String &other)
 38 {
 39     int length = strlen(other.m_data);
 40     m_data = new char[length + 1];
 41     strcpy(m_data, other.m_data);
 42 }
 43 
 44 // 赋值函数
 45 String & String::String::operator=(const String &other)
 46 {
 47     // 检查自赋值
 48     if (this == &other)
 49         return *this;
 50     
 51     // 释放原有的内存资源
 52     delete[] m_data;
 53 
 54     int length = strlen(other.m_data);
 55     m_data = new char[length + 1];
 56     strcpy(m_data, other.m_data);
 57 
 58     return *this;
 59 }
 60 
 61 ostream &operator<<(ostream &os, const String &str)
 62 {
 63     os << str.m_data;
 64     
 65     return os;
 66 }
 67 
 68 istream &operator>>(istream &is, String &str)
 69 {
 70     char *sTemp = new char[1000];
 71     
 72     is >> sTemp;
 73     
 74     // Must check if input succeeds
 75     if (is) {
 76         delete[] str.m_data;
 77         
 78         int length = strlen(sTemp);
 79         str.m_data = new char[length + 1];
 80         strcpy(str.m_data, sTemp);
 81     } else
 82         str = String(); // if fail, set to the default value
 83     
 84     delete[] sTemp;
 85     
 86     return is;
 87 }
 88 
 89 int main()
 90 {
 91     String s1;
 92     String s2("Test");
 93     String s3 = s2;
 94     
 95     cout << s1 << endl;
 96 
 97     s1 = s2;
 98     
 99     cout << s1 << endl;
100     
101     cin >> s1;
102     
103     cout << s1 << endl;
104     cout << s2 << endl;
105     cout << s3 << endl;
106     
107     return 0;
108 }
View Code

删除字符串的首尾多余空格

  • 利用STL方法,记得处理string::npos。
  • 注意对空格字符串输入“ ”,输出还是“ ”,只删除首尾多余空格。
  • string::find_first_not_of - C++ Reference
    • http://www.cplusplus.com/reference/string/string/find_first_not_of/
  • string::npos - C++ Reference
    • http://www.cplusplus.com/reference/string/string/npos/
 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 #include <string>
11 #include <cstddef>        // std::size_t
12 using namespace std;
13 
14 class Solution
15 {
16 public:
17     void TrimSpaces(string& ioStr)
18     {
19         size_t  startPos = ioStr.find_first_not_of(" ");
20         size_t  endPos = ioStr.find_last_not_of(" ");
21         
22         cout << startPos << "\n" << endPos << endl;
23 
24         // npos is a static member constant value with the greatest possible value for an element of type size_t.
25         // This constant is defined with a value of -1, which because size_t is an unsigned integral type, it is the largest possible representable value for this type.
26         if (startPos == string::npos)
27             startPos = 0;
28         if (endPos == string::npos)
29             endPos = 0;
30         
31         cout << startPos << "\n" << endPos << endl;
32         
33         ioStr = ioStr.substr(startPos, endPos - startPos + 1);
34     }
35 };
36 
37 int main ()
38 {
39     Solution testSolution;
40 
41     string  str[5] = {"  abc     ", "abc     ", "    abc", " ", ""};
42     
43     for (auto i = 0; i < 5; i ++)
44     {
45         testSolution.TrimSpaces(str[i]);
46         cout << "\"" << str[i] << "\"" << "\n" << endl;
47     }
48 
49     return 0;
50 }
View Code
  • 执行结果注意string::npos的值。
4
4
"abc"
2
2
"abc"
6
6
"abc"
18446744073709551615
0
" "
18446744073709551615
0
""

Program ended with exit code: 0
View Code

输出Fibonacci数列的第N项

  • 注意解法有递归,非递归和数学方法。
  • 输入N最好用unsigned int类型。
 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 using namespace std;
11 
12 class Solution
13 {
14 public:
15     int Fibonacci(const int& n)
16     {
17         if (n == 0)
18             return 0;
19         else if (n == 1)
20             return 1;
21         else {
22             int t, f0 = 0, f1 = 1;
23             
24             for (int i = 2; i < n + 1; i ++)
25             {
26                 t = f1;
27                 f1 = f0 + f1;
28                 f0 = t;
29             }
30             
31             return f1;
32         }
33     }
34     
35 };
36 
37 int main(int argc, char* argv[])
38 {
39     Solution    testSolution;
40     
41     for (auto i = 0; i < 10; i ++)
42         cout << testSolution.Fibonacci(i) << endl;
43     
44     return 0;
45 }
Fibonacci.cpp
0
1
1
2
3
5
8
13
21
34
Program ended with exit code: 0
View Result

判断一个字符串是否是回文串

 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 #include <string>
11 #include <algorithm>    // reverse
12 #include <cctype>       // toupper, isalnum
13 using namespace std;
14 
15 class Solution
16 {
17 public:
18     // Reverse the whole string
19     int isPalindrome(const string& str)
20     {
21         if (str.empty()) return false;
22         
23         string sTemp = str;
24         
25         cout << sTemp << endl;
26         
27         // STL algorithm
28         reverse(sTemp.begin(), sTemp.end());
29         
30         cout << sTemp << endl;
31         
32         return (sTemp == str);
33     }
34     
35     // Considering only alphanumeric characters and ignoring cases
36     int isPalindrome2(const string& str)
37     {
38         if (str.empty()) return false;
39         
40         size_t start = 0, end = str.size() - 1;
41         
42         while (start < end)
43         {
44             if (! isalnum(str.at(start)))
45                 ++ start;
46             else if (! isalnum(str.at(end)))
47                 -- end;
48             else if (toupper(str.at(start)) != toupper(str.at(end)))
49                 return false;
50             else {
51                 ++ start;
52                 -- end;
53             }
54         }
55         
56         return true;
57     }
58 };
59 
60 int main(int argc, char* argv[])
61 {
62     Solution    testSolution;
63     
64     auto words = {"A man, a plan, a canal: Panama", "race a car", "", "a b a"};
65     
66     for (auto word : words)
67         cout << testSolution.isPalindrome(word) << endl;
68 
69     cout << endl;
70     
71     for (auto word : words)
72         cout << testSolution.isPalindrome2(word) << endl;
73 
74     return 0;
75 }
isPalindrome.cpp
A man, a plan, a canal: Panama
amanaP :lanac a ,nalp a ,nam A
0
race a car
rac a ecar
0
0
a b a
a b a
1

1
0
0
1
Program ended with exit code: 0
View Result

 判断一个数是否是10的幂

  • 细心,注意判断条件。
 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 
 9 #include <iostream>
10 using namespace std;
11 
12 class Solution
13 {
14 public:
15     bool isPowerOfTen(int n)
16     {
17         if (n < 1)
18             return false;
19         
20         while (n % 10 == 0) {
21             n /= 10;
22         }
23         
24         return n == 1;
25     }
26 };
27 
28 int main(int argc, char* argv[])
29 {
30     Solution    testSolution;
31     
32     int result = 1;
33     
34     result = result && testSolution.isPowerOfTen(1);
35     result = result && testSolution.isPowerOfTen(10);
36     result = result && testSolution.isPowerOfTen(10000000);
37     result = result && !testSolution.isPowerOfTen(0);
38     result = result && !testSolution.isPowerOfTen(-1);
39     result = result && !testSolution.isPowerOfTen(110);
40 
41     if (result)
42         cout << "ALl tests pass!" << endl;
43     
44     return 0;
45 }
isPowerOfTen

找出最长重复字符子串

  • 考察字符串基本功,从头至尾扫描一遍,注意判断字符指针结束符。
 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 
 9 #include <stdio.h>
10 #include <string.h>
11 
12 typedef struct substr {
13     int start, length;
14 } substr;
15 
16 substr longest_uniform_substring(char * input)
17 {
18     if (input == nullptr || strlen(input) == 0)
19         return (substr){ -1, 0 };
20     
21     int st = 0, len = 1, resSt = 0, maxLen = 1, cur = 0;
22     char cTemp = *input;
23 
24     ++ input;
25     cur += 1;
26 
27     while (*input != '\0')  // pay attention to the terminator '\0'
28     {
29         if (*input == cTemp) {
30             len += 1;
31         } else {
32             cTemp = *input;
33             st = cur;
34             len = 1;
35         }
36         
37         if (len > maxLen) {
38             resSt = st;
39             maxLen = len;
40         }
41         
42         ++ input;
43         cur += 1;
44     }
45     
46     return (substr){ resSt, maxLen };
47 }
48 
49 int main(int argc, char* argv[])
50 {
51     int result = 1;
52     
53     substr test = longest_uniform_substring("");
54     result = result && (test.start == -1 && test.length == 0);
55 
56     test = longest_uniform_substring("10000111");
57     result = result && (test.start == 1 && test.length == 4);
58 
59     test = longest_uniform_substring("aabbbbbCdAA");
60     result = result && (test.start == 2 && test.length == 5);
61 
62     if (result)
63         printf("ALl tests pass!\n");
64     
65     return 0;
66 }
View Code

按照几率输出determined rate result 01,例如rate = 0.25,00010001。

  • 几率题。累加几率到1则输出。注意对double跟1的比较要用精度控制。
 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 #include <iostream>
 9 #include <vector>
10 #include <cmath>
11 using namespace std;
12 
13 class Rate {
14 public:
15     Rate(double rate) : m_rate(rate), m_total(rate) {}  // inialization
16     
17     bool keep() {
18 //        cout << m_total << " ";
19 
20         if (m_total < 1 - 1e-10) {  // pay attention to the double precision control. Actually 1 is 0.999...9 in memory.
21             m_total += m_rate;
22             return false;
23         } else {    // reset the rate
24             m_total = m_total - 1 + m_rate;
25             return true;
26         }
27     }
28 
29 private:
30     double m_rate, m_total;
31 };
32 
33 int main()
34 {
35     vector<Rate>    myRates{Rate(0.3), Rate(0.25)};
36     
37     /*
38      0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1
39      0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
40      */
41     for (auto & myRate : myRates) {
42         for (int i = 0; i < 20; i ++) {
43             if (myRate.keep())
44                 cout << "1 ";
45             else
46                 cout << "0 ";
47         }
48         cout << endl;
49     }
50 
51     return 0;
52 }
View Code

Write a program that creates a standard deck of cards, shuffles them and returns the top card from the deck. (This is a standalone program, you are not passed in any data.)

  • Fisher–Yates shuffle - Wikipedia
    • https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
  • 洗牌算法汇总以及测试洗牌程序的正确性 - tenos - 博客园
    • http://www.cnblogs.com/TenosDoIt/p/3384141.html  
 1 //
 2 //  main.cpp
 3 //  LeetCode
 4 //
 5 //  Created by Hao on 2017/3/16.
 6 //  Copyright © 2017年 Hao. All rights reserved.
 7 //
 8 #include <iostream>
 9 #include <vector>
10 using namespace std;
11 
12 int main()
13 {
14     vector<int> cards;
15     int         n = 54;
16     
17     for (int i = 0; i < n; i ++) {
18         cards.push_back(i + 1);
19     }
20     
21     for (int i = n - 1; i > 0; i --) {
22         int j = rand() % (i + 1);
23         swap(cards[i], cards[j]);
24     }
25   
26     // STL for reference
27 //    random_shuffle(cards.begin(), cards.end());
28     
29     /*
30      13 10 15 43 9 22 33 5 3 52 36 35 51 49 46 34 41 24 23 48 32 50 16 2 44 7 53 40 30 11 42 54 8 4 18 17 19 12 27 28 47 1 45 29 20 26 38 25 21 31 39 6 37 14
31      */
32     for (auto card : cards) {
33         cout << card << " ";
34     }
35     
36     return 0;
37 }
View Code

2019 C++开发工程师面试题大合集

相关文章
相关标签/搜索