在面試中面試官常常讓我們寫幾個小的程式,以此來考察我們的編程內功。所以在準備面試的過程中在紙上練習著寫一些程式是很有必要的。
下面是在面試中常考的幾個題,出現頻率非常之高!!!!
1、完整正確的寫出二分尋找的演算法
int binary_search(int arr[],int n,int key){assert(arr!=NULL && n>0);//注意斷言的作用int left=0;int right=n-1;int mid=0;while(left<=right){mid = left + ((right-left)>>1);//不直接用(left+right)/2是防止越界和提高效率if(arr[mid]<key)left=mid+1;else if(arr[mid]>key)right=mid-1;else return mid;}return -1;}
程式中要注意的地方:
//right=n-1 => while(left <= right) => right=middle-1;
//right=n => while(left < right) => right=middle;
middle= (left+right)>>1; 這樣的話 left 與 right 的值比較大的時候,其和可能溢出。
2、寫出你認為效率高且常用的一種排序演算法(快速排序、歸併排序)
void QSort(int arr[],int low,int high){int pivot;while(low<high)//最佳化了遞迴操作{pivot=Partition(arr,low,high);QSort(arr,low,pivot-1);low=pivot+1;}}int Partition(int arr[],int low,int high){assert(arr!=NULL && low<high);int pivotkey=arr[low];//對於關鍵字的選取我們可以採取3數取中法或9數取中法,還可以隨機取數來保證關鍵字正好是數組的接近中間位置。while(low<high){while(low<high && arr[high]>=pivotkey)high--;arr[low]=arr[high];//採用替換而不是交換的操作(最佳化不必要的交換)while(low<high && arr[low]<=pivotkey)low++;arr[high]=arr[low];//採用替換而不是交換的操作}arr[low]=pivotkey;return low;}//3數取中法的代碼int m = low+((high-low)>>1);if(arr[low]>arr[high]) swap(arr[low],arr[high]);if(arr[m]>arr[high]) swap(arr[m],arr[high]);if(arr[m]>arr[low]) swap(arr[m],arr[low]);
3、反轉鏈表
struct ListNode{int m_nValue;ListNode* m_pNext;};//鏈表的結構體ListNode *ReverseList(ListNode *pHead){assert(pHead!=NULL);//防止傳入的是一個null 指標,參數檢查很重要!!!一定不要忘記寫ListNode *pReversedList = NULL; //指向反轉後的鏈表的頭結點ListNode *pNode = pHead; //指向斷開後鏈表的後面一段鏈表的第一個結點ListNode *pPrev = NULL; //指向斷開後鏈表的前面一段鏈表的最後一個結點while(pNode!=NULL){ListNode *pNext = pNode->m_pNext;if(pNext == NULL)pReversedList = pNode;pNode->m_pNext = pPrev;pPrev = pNode;pNode = pNext;}return pReversedList;}
4、題目描述:
要求實現庫函數 strcpy,
原型聲明:extern char *strcpy(char *dest,char *src);
功能:把 src 所指由 NULL 結束的字串複製到 dest 所指的數組中。
說明: src 和 dest 所指記憶體地區不可以重疊且 dest 必須有足夠的空間來容納 src 的字串。
返回指向 dest 的指標。
//得 10 分,基本上所有的情況,都考慮到了 //如果有考慮到源目所指地區有重疊的情況,加 1 分! char * strcpy( char *strDest, const char *strSrc )//將源字串加const,表明其為輸入參數 { if(strDest == strSrc) { return strDest; } assert( (strDest != NULL) && (strSrc != NULL) );//對源地址和目的地址加非0斷言 char *address = strDest; while( (*strDest++ = * strSrc++) != '\0'); return address; //為了實現鏈式操作,將目的地址返回 }類似的我們還可以寫出strlen函數的完美版本int strlen( const char *str ) //輸入參數const{ assert( strt != NULL ); //斷言字串地址非0 int len; while( (*str++) != '\0' ) { len++; } return len;}
關於字串操作的庫函數數有許多,我們可以參照上面的幾點寫出其它的字串操作庫函數的完美版本。
5、。
memmove()函數的實現效率問題,該函數把源字串拷貝到臨時buf裡,然後再從臨時buf裡寫到目的地址,。
void* Memcpy(void *dst, const void *src, size_t size)//size_t它是一個與機器相關的unsigned類型,其大小足以保證儲存記憶體中對象的大小。{ //注意形參類型和返回值類型都是void* char *psrc; char *pdst; if(NULL == dst || NULL == src)//要注意對傳入的形參進行檢查 { return NULL; } if((src < dst) && (char *)src +size > (char *)dst) // 記憶體重疊時要注意自後向前拷貝 { psrc = (char *)src + size - 1; pdst = (char *)dst + size - 1; while(size--) { *pdst-- = *psrc--; } } else { psrc = (char *)src; pdst = (char *)dst; while(size--) { *pdst++ = *psrc++; } } return dst;}
class String
{
public:
String(const char *str = NULL); // 普通建構函式
String(const String &other); // 拷貝建構函式
~ String(void); // 解構函式
String & operate =(const String &other); // 賦值函數
private:
char *m_data; // 用於儲存字串
};
//普通建構函式String::String(const char *str) { if(str==NULL) { m_data = new char[1]; //得分點:對Null 字元串自動申請存放結束標誌'\0'的空 //加分點:對m_data加NULL 判斷 *m_data = '\0'; } else { int length = strlen(str); m_data = new char[length+1]; // 若能加 NULL 判斷則更好 strcpy(m_data, str); }}// String的解構函式String::~String(void) { delete [] m_data; // 或delete m_data;}//拷貝建構函式String::String(const String &other) // 得分點:輸入參數為const型{ int length = strlen(other.m_data); m_data = new char[length+1]; //加分點:對m_data加NULL 判斷 strcpy(m_data, other.m_data); }//賦值函數String & String::operate =(const String &other) // 得分點:輸入參數為const型{ if(this == &other) //得分點:檢查自賦值 return *this; delete [] m_data; //得分點:釋放原有的記憶體資源 int length = strlen( other.m_data ); m_data = new char[length+1]; //加分點:對m_data加NULL 判斷 strcpy( m_data, other.m_data ); return *this; //得分點:返回本對象的引用}
在這個類中包括了指標類成員變數m_data,當類中包括指標類成員變數時,一定要重載其拷貝建構函式、賦值函數和解構函式,這既是對C++程式員的基本要求,也是《Effective C++》中特彆強調的條款。
仔細學習這個類,特別注意加註釋的得分點和加分點的意義,這樣就具備了60%以上的C++基本功!