有點意思的C/C++問題及解答:11-15
阿新 • • 發佈:2019-01-05
問題11:下面這個函式希望完成什麼任務?
[cpp] view plain copy print ?
- int func(int x)
- {
- int countx = 0;
- while
- {
- countx ++;
- x = x&(x-1);
- }
- return countx;
- }
解答:這個函式是求一個整數的二進位制表示中含1的個數。假定x = 9999,該函式返回8。這是道微軟的面試題,在《程式設計之美》一書中給出了若干種方法,用來求二進位制數中1的個數。
問題12:以下三條輸出語句分別輸出什麼?
[cpp] view plain copy print ?
- char
- char str2[] = "abc";
- const char str3[] = "abc";
- const char str4[] = "abc";
- const char* str5 = "abc";
- const char* str6 = "abc";
- cout << boolalpha << ( str1==str2 ) << endl; // 輸出什麼
- cout << boolalpha << ( str3==str4 ) << endl; // 輸出什麼
- cout << boolalpha << ( str5==str6 ) << endl; // 輸出什麼
問題13: 已知String類定義如下,請實現這些函式。
[cpp] view plain copy print ?
- class String
- {
- public:
- String(const char *str = NULL); //預設建構函式
- String(const String &another); //拷貝建構函式
- ~String(); //解構函式
- String & operator =(const String &rhs); //賦值操作符
- private:
- char *m_data; //用於儲存字串
- };
解答:實現中有幾點要注意:(1)預設建構函式中,判斷str是否為空。(2)解構函式中應使用delete [ ] 運算子。(3)賦值操作符應判斷是否是給自身賦值。程式碼如下:
[cpp] view plain copy print ?- String::String(const char *str)
- {
- if(str == NULL)
- {
- m_data = new char[1];
- m_data[0] = '\0';
- }
- else
- {
- m_data = new char[strlen(str) + 1]; //需要加1,strlen返回的字串長度並不包含'\0'
- strcpy(m_data,str);
- }
- }
- String::String(const String &another)
- {
- m_data = new char[strlen(another.m_data) + 1];
- strcpy(m_data,another.m_data);
- }
- String& String::operator=(const String &rhs)
- {
- if(this != &rhs) //防止給自身賦值
- {
- delete [] m_data;
- m_data = new char[strlen(rhs.m_data) + 1];
- strcpy(m_data,rhs.m_data);
- }
- return *this;
- }
- String::~String()
- {
- delete [] m_data; //注意是delete []
- }
解答:用KMP演算法即可。基本策略是預處理子串 P ,獲得其中與模式匹配有關的子字串關係規律,從而當發生匹配失敗時,可以確定繼續與 T 當前位置匹配的 P 的新位置,這樣就不需要在 T 中回溯了。時間複雜度為O(T+P)。
[cpp] view plain copy print ?
- int KMP(char *T, char *P)
- {
- int lenT = strlen(T);
- int lenP = strlen(P);
- int i = 0, j = 0;
- int *next = new int[lenP + 1]; //最後一個元素用不到
- Fail(next, P); //計算失敗函式
- while(i < lenT && j < lenP)
- {
- if(j == -1 || T[i] == P[j])
- {
- i++; j++;
- }
- else
- j = next[j]; //P的下一個比較位置
- }
- delete [] next;
- if(j < lenP || j == 0)
- return -1;
- else
- return i - lenP;
- }
- //仍是一個模式匹配的過程,只不過目標串和模式串是同一串P,所以兩個程式碼的程式很相似
- void Fail(int *next, char *P)
- {
- int lenP = strlen(P);
- int i = -1,j = 0;
- next[0] = -1;
- while(j < lenP)
- {
- if(i == -1 || P[i] == P[j])
- {
- i++; j++;
- next[j] = i;
- }
- else
- i = next[i];
- }
- }
解答:空類同樣可以被例項化,每個例項在記憶體中都有一個獨一無二的地址,為了達到這個目的,編譯器往往會給一個空類隱含的加一個位元組,這樣空類在例項化後在記憶體得到了獨一無二的地址。