// 題目:如下為型別cmystring的宣告,請為該型別新增賦值運算子函式。
class cmystring ;
注意點:
1. 返回值是否為該型別的引用。如果為該型別引用則可連續賦值。如果返回void,則無法通過編譯;
2. 傳入引數是否宣告為常量引用。如果傳入引數不是常量引用,則會有一次非必要的拷貝構造函式呼叫;
3. 是否釋放例項自身的記憶體
4. 是否判斷引數與自身是否相等
// 注意點1,2
cmystring& cmystring::operator =(const cmystring& str)
// 注意點3
delete m_pdata;
m_pdata = null;
m_pdata = new
char[strlen(str.m_pdata) + 1];
strcpy(m_pdata, str.m_pdata);
return *this;
}
上述解法存在乙個問題,如果new char的時候記憶體不足,則會丟擲異常,但此時例項本身的記憶體已經被釋放了,那麼則容易導致程式崩潰。因此我們選擇先分配記憶體,只有分配記憶體成功了才釋放原來的記憶體。
cmystring& cmystring::operator =(const cmystring& str)
return *this;
}
上述解法中先宣告了乙個中間物件strtemp,而且這個中間變數是乙個區域性變數,當程式退出if (this != &str)
這個作用域之後就會釋放這個臨時變數的記憶體。而當程式退出上述作用域時,該臨時變數指向的記憶體是原來mystring例項的記憶體,因此就實現了自動記憶體釋放,同時保證了當記憶體不足丟擲異常的時候,原來物件的資料不變。
在未宣告成員函式或者成員變數的訪問許可權級別時,struct中預設的是public,而class中預設的是private
注意點:
1. 不能只使用與單執行緒;
2. 使用同步鎖來使類只能建立乙個例項時,是否高效(加鎖是乙個十分耗時的操作);
3. 是否按需建立例項;
class singleton
static singleton* singleton::getinstance()
}return instance;
}
在乙個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。二維陣列示例:
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
解題思路:從右上角或者左下角的元素開始與目標元素對比,如果元素與目標元素相等則返回true,否則可以根據元素與目標元素的大小關係,排除掉一行或者一列。可以嘗試從陣列右上角的元素開始尋找7,走一遍尋找的過程就大概能夠理解。**如下:
bool found(int* matrix, int rows, int cols, int target)
bool found = false;
int row = 0;
int col = cols - 1;
while row < rows && col >= 0 else
if (matrix[row * cols + col] < target) else
}return found;
}
void replaceblank(char
string, int length)
++i}
int newlength = originlength + 2 * numofblank;
if (newlength > length) return;
int indexoforigin = originlength;
int indexofnew = newlength;
while (originlength >= 0 && indexofnew > indexoforigin) else
-- indexoforigin;
}}
根據二叉樹的前序遍歷陣列以及中序遍歷陣列重構二叉樹。
解題思路:由前序遍歷陣列的第乙個元素,可以確定二叉樹的根節點。在二叉樹的中序遍歷陣列中找到根節點的值,也就確定了中序遍歷中根節點的位置。那麼在根節點位置以前的則是左子樹的中序遍歷陣列,根節點以後的則是右子樹的中序遍歷陣列。再根據左右子樹的中序遍歷陣列的長度,可以確認左右子樹的前序遍歷陣列。然後通過遞迴,即可重構二叉樹。實現**如下:
struct node
node* construct(int* preorder, int* inorder, int
length)
return contructcore(preorder, preorder + length - 1, inorder, inorder + length - 1);
}node* constructcore(int* startpreorder, int* endpreorder, int* startinorder, int* endinorder) else
}int* rootinorder = startinorder;
while (rootinorder <= endinorder && *rootinorder != rootvalue) ++rootinorder;
if (rootinorder == endinorder && *rootinorder != rootvalue) throw std::exception("invalide input");
int leftlength = rootinorder - startinorder;
int* leftpreorderend = startpreorder + leftlength;
if (leftlength > 0)
if (leftlenght < endpreorder - startpreorder)
用兩個棧實現佇列
解題思路:兩個棧分別記為stack1和stack2。當向佇列中壓入物件a時,我們將a壓入stack1中。依次向佇列壓入b、c、d,此時stack1中的物件為[d,c,b,a],其中d為棧首。當要從佇列中刪除乙個元素的時候,我們將stack1中的元素依次彈出並壓入stack2中,以實現翻轉。經過翻轉後stack1為空,stack2的內容為[a, b, c, d],其中棧首元素為a。此時從stack2中pop出乙個元素,則是第乙個被壓入佇列的元素。此時stack2中的元素順序和壓入順序是相等的,因此如果要繼續刪除元素,則繼續從stack2中pop元素即可,直至stack2再次為空,我們再將stack1中的元素依次彈出並壓入stack2。**如下:
template
class cqueue ;
template
stack1.push(element);
}template
void cqueue::deletehead()
}if (stack2.size() == 0) throw
new exception("queue is empty");
t head = stack2.top();
stack2.pop();
return head;
}
常見面試題整理1
面試題整理1 相同點 都是繼承collection介面 不同點 1.list 元素存放有順序,元素可重複 set 元素存放無順序,元素不可重複 2.list 支援for迴圈,也可以用迭代器 set 只能用迭代器,因為它是無序的,無法通過下標獲取元素 3.list和陣列相似,查詢元素效率高,插入刪除元...
C 常見面試題整理
最小堆pop最小的,最大堆pop最大的 設計乙個演算法,找出陣列中最小的k個數。以任意順序返回這k個數均可 最大堆 class solution while maxheap.empty return out 在未排序的陣列中找到第k個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,...
C C 常見面試題整理
事情皆有因果。卻有未必好因造好果,看你是短看還是長看。從概率和從極長遠來看,當然是好人好報,但是具體短期的隨機性就無法 了。在該函式前新增extern c 宣告。由於編譯後的名字不同,c 程式不能直接呼叫c 函式。a c 中的類預設的成員是私有的,struct預設的是共有的。b c 中的類可以定義成...