面試總結之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++開發工程師面試題大合集

相關文章
相關標籤/搜索