面試題目搜集(5)


本博客的《面試題目搜集系列不錯》

(1)面試題目搜集1

(2)面試題目搜集2

(3)面試題目搜集3

(4)面試題目搜集4

(5)面試題目搜集5

(6)面試題目搜集6


1.反着打印鏈表(遞歸實現)

#include<iostream>
#include <cstdio>
using namespace std;

typedef int Elem;

struct ListNode{
Elem nData;
ListNode *pNext;
ListNode(int data,ListNode *next=NULL):nData(data),pNext(next){}
};

void PrintReverseList(ListNode *root)
{
if(!root)
return;
PrintReverseList(root->pNext);
cout<<root->nData<<" ";
};
int main()
{
ListNode *list3 = new ListNode(3,NULL);
ListNode *list2 = new ListNode(2,list3);
ListNode *list1 = new ListNode(1,list2);
ListNode *pHead = new ListNode (0,list1);

PrintReverseList(pHead);
system("pause");
return 0;
}


2.求最大連續字符串 (如“ ads3s1456789DF3456ld345AA ”,結果為“456789”)

#include <iostream>
#include <string>
using namespace std;

typedef int StartIndex;
typedef int StrLenght;
typedef pair<StartIndex,StrLenght> Result;

Result FindContinuousSubStr(const string& str)
{
int start = 0;
int maxLen = 1;
int length = 1;

for(int i=1; i<str.size();++i){
if(str[i] == str[i-1] + 1){
++length;
}
else{
if(length > maxLen){
maxLen = length;
start = i - length;
}
length = 1;
}
}

return make_pair(start,maxLen);
}

int main()
{
string str = "ads3s1456789DF3456ld345AA";
Result ret = FindContinuousSubStr(str);

for(int i=0; i<ret.second; ++i){
cout<<str[ret.first+i];
}

system("pause");
return 0;
}


3.編寫CString類

class CString{
public:
CString(const char *pStr = NULL){
if(pStr == NULL){
pData = new char;
*pData = '\0';
}
else{
pData = new char[strlen(pStr)+1];
assert(pData != NULL);
strcpy(pData,pStr);
}
}
CString(const CString& other){
pData = new char[strlen(other.pData)+1];
assert(pData != NULL);
strcpy(pData,other.pData);
}
CString& operator=(const CString& other){
if(&other == this){
CString strTemp(other);

char *pTemp = strTemp.pData;
strTemp.pData = pData;
pData = pTemp;
}
return *this;
}
~CString(){
if(!pData)
delete[] pData;
}
private:
char *pData;
};


4.百度的一道筆試題目: 下面這段代碼是把中英文混合字符串(漢字用兩個字節表示,特點是第一個字節的最高位為1)中的大寫字母轉化為小寫字母,請找出其中的bug,注意各種異常情況。 
for (char *piterator = szWord; *piterator != 0; piterator++) 

if (*piterator & 0x80 != 0) 

piterator++; 

else if (*piterator >= 'A' && *piterator <= 'Z') 

piterator += 32; 

上面有兩個bug,答案更正如下:

#include <iostream>

using namespace std;

void Convert(char *szWord)
{
for (char *piterator = szWord; *piterator != '\0'; piterator++)
if ((*piterator & 0x80) != 0)
piterator++;
else if (*piterator >= 'A' && *piterator <= 'Z')
*piterator += 32;

cout<<szWord<<endl;
}


int main()
{
char str[] = "我是LSJ,請把我ZHUANHuan為小XIE";
Convert(str);
system("pause");
return 0;
}

5.百度2012年實習得一道招聘題目。

        相信大家都使用過百度搜索框的suggestion功能(如下圖所示)。百度搜索框中的suggestion提示功能如何實現的?請給出實現思路和主要的數據結構、算法。有什么優化思路可以使得時間和空間效率最高?
如下圖所示:


答:統計搜索引擎查詢日志,統計各個查詢詞出現的次數。然后統計查詢串中可能出現的各個前綴子串,然后統計以各個前綴子串開頭的查詢串的頻率。對各個子串,取以其作為前綴的前K個最高頻查詢串。再以各個子串為KEY,建立倒排索引(或trie樹)。定期更新倒排索引(或trie樹),即可依據查詢頻率給出一個比較合理的提示內容。當用戶輸入時,去倒排索引(或trie樹)中進行匹配,然后取其出現頻率最高的前K個。

注:應用字典樹來求前綴和TOP K對熱詞進行統計排序,求前綴用trie樹(o(nle),le表示字符串的平均長度)


6.析構函數不能拋出異常

(1)構造函數可以拋出異常。

(2)c++標准指明析構函數不能、也不應該拋出異常。

more effective c++關於第2點提出兩點理由:

1)如果析構函數拋出異常,則異常點之后的程序不會執行,如果析構函數在異常點之后執行了某些必要的動作比如釋放某些資源,則這些動作不會執行,會造成諸如資源泄漏的問題。

2)通常異常發生時,c++的機制會調用已經構造對象的析構函數來釋放資源,此時若析構函數本身也拋出異常,則前一個異常尚未處理,又有新的異常,會造成程序崩潰的問題。

解決辦法:

1)永遠不要在析構函數拋出異常。

2)通常第一點有時候不能保證。可以采取如下的方法:

~ClassName()

{

  try{

      do_something();

  }

  catch(){  //這里可以什么都不做,只是保證catch塊的程序拋出的異常不會被扔出析構函數之外。

   }

}





注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com