re: 全面整理的C++面試題 chatler 2009-12-13 00:39
4。分析一下
#include<iostream.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef struct AA
{
int b1:5;
int b2:2;
}AA;
void main()
{
AA aa;
char cc[100];
strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");
memcpy(&aa,cc,sizeof(AA));
cout << aa.b1 <<endl;
cout << aa.b2 <<endl;
}
答案: -16和1
首先sizeof(AA)的大小為4,b1和b2分別占5bit和2bit.
經(jīng)過strcpy和memcpy后,aa的4個(gè)字節(jié)所存放的值是:
0,1,2,3的ASC碼,即00110000,00110001,00110010,00110011
所以,最后一步:顯示的是這4個(gè)字節(jié)的前5位,和之后的2位
分別為:10000,和01
因?yàn)閕nt是有正負(fù)之分 所以是-16和1
5。求函數(shù)返回值,輸入x=9999;
int func ( x )
{
int countx = 0;
while ( x )
{
countx ++;
x = x&(x-1);
}
return countx;
}
結(jié)果呢?
答案:知道了這是統(tǒng)計(jì)9999的二進(jìn)制數(shù)值中有多少個(gè)1的函數(shù),且有
9999=9×1024+512+256+15
9×1024中含有1的個(gè)數(shù)為2;
512中含有1的個(gè)數(shù)為1;
256中含有1的個(gè)數(shù)為1;
15中含有1的個(gè)數(shù)為4;
故共有1的個(gè)數(shù)為8,結(jié)果為8。
1000 - 1 = 0111,正好是原數(shù)取反。這就是原理。
用這種方法來求1的個(gè)數(shù)是很效率很高的。
不必去一個(gè)一個(gè)地移位。循環(huán)次數(shù)最少。
6。int a,b,c 請(qǐng)寫函數(shù)實(shí)現(xiàn)C=a+b ,不可以改變數(shù)據(jù)類型,如將c改為long int,關(guān)鍵是如何處理溢出問題
答案:bool add (int a, int b,int *c)
{
*c=a+b;
return (a>0 && b>0 &&(*c
a || *c>b)));
}
這里,第三個(gè)或條件沒看明白,覺得邏輯上出現(xiàn)不了啊。
7。分析:
struct bit
{ int a:3;
int b:2;
int c:3;
};
int main()
{
bit s;
char *c=(char*)&s;
cout< *c=0x99;
cout << s.a < int a=-1;
printf("%x",a);
return 0;
}
輸出為什么是?
答案:4
1
-1
-4
ffffffff
因?yàn)?x99在內(nèi)存中表示為 100 11 001 , a = 001, b = 11, c = 100(在vc環(huán)境中,一般是由右到左進(jìn)行分配的)
當(dāng)c為有符合數(shù)時(shí), c = 100, 最高1為表示c為負(fù)數(shù),負(fù)數(shù)在計(jì)算機(jī)用補(bǔ)碼表示,所以c = -4;同理
b = -1;
當(dāng)c為有符合數(shù)時(shí), c = 100,即 c = 4,同理 b = 3
8。改錯(cuò):
#include
int main(void) {
int **p;
int arr[100];
p = &arr;
return 0;
}
答案:搞錯(cuò)了,是指針類型不同,
int **p; //二級(jí)指針
&arr; //得到的是指向第一維為100的數(shù)組的指針
應(yīng)該這樣寫#include
int main(void) {
int **p, *q;
int arr[100];
q = arr;
p = &q;
return 0;
9。下面這個(gè)程序執(zhí)行后會(huì)有什么錯(cuò)誤或者效果:
#define MAX 255
int main()
{
unsigned char A[MAX],i; //i被定義為unsigned char
for (i=0;i<=MAX;i++)
A[i]=i;
}
答案:死循環(huán)加數(shù)組越界訪問(C/C++不進(jìn)行數(shù)組越界檢查)
MAX=255
數(shù)組A的下標(biāo)范圍為:0..MAX-1,這是其一..
其二.當(dāng)i循環(huán)到255時(shí),循環(huán)內(nèi)執(zhí)行:
A[255]=255;
這句本身沒有問題..但是返回for (i=0;i<=MAX;i++)語句時(shí),
由于unsigned char的取值范圍在(0..255),i++以后i又為0了..無限循環(huán)下去.
11。struct name1{
char str;
short x;
int num;
}
struct name2{
char str;
int num;
short x;
}
sizeof(struct name1)=??,sizeof(struct name2)=??
答案:sizeof(struct name1)=8,sizeof(struct name2)=12
在第二個(gè)結(jié)構(gòu)中,為保證num按四個(gè)字節(jié)對(duì)齊,char后必須留出3字節(jié)的空間;同時(shí)為保證整個(gè)結(jié)構(gòu)的自然對(duì)齊(這里是4字節(jié)對(duì)齊),在x后還要補(bǔ)齊2個(gè)字節(jié),這樣就是12字節(jié)。
1.燒一根不均勻的繩子,從頭燒到尾總共需要 1 個(gè)小時(shí),問如何用燒繩子
的方法來確定半小時(shí)的時(shí)間呢?
2.10 個(gè)海盜搶到了100 顆寶石,每一顆都一樣大小且價(jià)值連城。他們決定
這么分:
(1)抽簽決定自己的號(hào)碼(1~10);
(2)首先,由1 號(hào)提出分配方案,然后大家表決,當(dāng)且僅當(dāng)超過半數(shù)的人
同意時(shí),按照他的方案進(jìn)行分配,否則將被扔進(jìn)大海喂鯊魚;
(3)如果1 號(hào)死后,再由2 號(hào)提出分配方案,然后剩下的4 個(gè)人進(jìn)行表決,
當(dāng)且僅當(dāng)超過半數(shù)的人同意時(shí),按照他的方案進(jìn)行分配,否則將被扔入大海喂鯊
魚;
(4)依此類推??
條件:每個(gè)海盜都是很聰明的人,都能很理智地做出判斷,從而做出選擇。
問題:第一個(gè)海盜提出怎樣的分配方案才能使自己的收益最大化?
3.為什么下水道的蓋子是圓的?
4.中國(guó)有多少輛汽車?
5.你讓工人為你工作7 天,回報(bào)是一根金條,這根金條平分成相連的7 段,
你必須在每天結(jié)束的時(shí)候給他們一段金條。如果只允許你兩次把金條弄斷,你如
何給你的工人付費(fèi)?
6.有一輛火車以每小時(shí)15 公里的速度離開北京直奔廣州,同時(shí)另一輛火車
以每小時(shí)20 公里的速度從廣州開往北京。如果有一只鳥,以30 公里每小時(shí)的速
度和兩輛火車同時(shí)啟動(dòng),從北京出發(fā),碰到另一輛車后就向相反的方向返回去飛,
就這樣依次在兩輛火車之間來回地飛,直到兩輛火車相遇。請(qǐng)問,這只鳥共飛行
了多長(zhǎng)的距離?
7.你有兩個(gè)罐子以及50 個(gè)紅色彈球和50 個(gè)藍(lán)色彈球,隨機(jī)選出一個(gè)罐子,
隨機(jī)選出一個(gè)彈球放入罐子,怎樣給出紅色彈球最大的選中機(jī)會(huì)?在你的計(jì)劃
里,得到紅球的幾率是多少?
8.想像你站在鏡子前,請(qǐng)問,為什么鏡子中的影像可以左右顛倒,卻不能
上下顛倒呢?
9.如果你有無窮多的水,一個(gè)3 公升的提捅,一個(gè)5 公升的提捅,兩只提
捅形狀上下都不均勻,問你如何才能準(zhǔn)確稱出4 公升的水?
10.你有一桶果凍,其中有黃色、綠色、紅色三種,閉上眼睛抓取同種顏色
的兩個(gè)。抓取多少次就可以確定你肯定有兩個(gè)同一顏色的果凍?
11.連續(xù)整數(shù)之和為1000 的共有幾組?
12.從同一地點(diǎn)出發(fā)的相同型號(hào)的飛機(jī),可是每架飛機(jī)裝滿油只能繞地球飛
半周,飛機(jī)之間可以加油,加完油的飛機(jī)必須回到起點(diǎn)。問至少要多少架次,才
能滿足有一架繞地球一周。
參考答案:
1.兩邊一起燒。
2.96,0,1,0,1,0,1,0,1,0。
3.因?yàn)榭谑菆A的。
4.很多。
5.分1,2,4。
6.6/7 北京到廣州的距離。
7.100%。
8.平面鏡成像原理(或者是“眼睛是左右長(zhǎng)的”)。
9.3 先裝滿,倒在5 里,再把3 裝滿,倒進(jìn)5 里。把5 里的水倒掉,把3 里
剩下的水倒進(jìn)5 里,再把3 裝滿,倒進(jìn)5 里,ok!
10.一次。
11.首先1000 為一個(gè)解。連續(xù)數(shù)的平均值設(shè)為x,1000 必須是x 的整數(shù)倍。
假如連續(xù)數(shù)的個(gè)數(shù)為偶數(shù)個(gè),x 就不是整數(shù)了。x 的2 倍只能是5,25,125 才行。
因?yàn)槠骄禐?2.5,要連續(xù)80 個(gè)達(dá)不到。125/2=62.5 是可以的。即62,63,61,
64,等等。連續(xù)數(shù)的個(gè)數(shù)為奇數(shù)時(shí),平均值為整數(shù)。1000 為平均值的奇數(shù)倍。
1000=2×2×2×5×5×5;x 可以為2,4,8,40,200 排除后剩下40 和200 是
可以的。所以答案為平均值為62.5,40,200,1000 的4 組整數(shù)。
12.答案是5 架次。一般的解法可以分為如下兩個(gè)部分:
(1)直線飛行
一架飛機(jī)載滿油飛行距離為1,n 架飛機(jī)最遠(yuǎn)能飛多遠(yuǎn)?在不是兜圈沒有迎
頭接應(yīng)的情況,這問題就是n 架飛機(jī)能飛多遠(yuǎn)?存在的極值問題是不要重復(fù)飛
行,比如兩架飛機(jī)同時(shí)給一架飛機(jī)加油且同時(shí)飛回來即可認(rèn)為是重復(fù),或者換句
話說,離出發(fā)點(diǎn)越遠(yuǎn),在飛的飛機(jī)就越少,這個(gè)極值條件是顯然的,因?yàn)閚 架飛
機(jī)帶的油是一定的,如重復(fù),則浪費(fèi)的油就越多。比如最后肯定是只有一架飛機(jī)
全程飛行,注意“全程”這兩個(gè)字,也就是不要重復(fù)的極值條件。如果是兩架飛
機(jī)的話,肯定是一架給另一架加滿油,并使剩下的油剛好能回去,就說第二架飛
機(jī)帶的油耗在3 倍于從出發(fā)到加油的路程上,有三架飛機(jī)第三架帶的油耗在5
倍于從出發(fā)到其加油的路程上,所以n 架飛機(jī)最遠(yuǎn)能飛行的距離為s=1+1/3+?
+1/(2n+1)這個(gè)級(jí)數(shù)是發(fā)散的,所以理論上只要飛機(jī)足夠多最終可以使一架飛
機(jī)飛到無窮遠(yuǎn),當(dāng)然實(shí)際上不可能一架飛機(jī)在飛行1/(2n+1)時(shí)間內(nèi)同時(shí)給n?1
個(gè)飛機(jī)加油。
(2)可以迎頭接應(yīng)加油
一架飛機(jī)載滿油飛行距離為1/2,最少幾架飛機(jī)能飛行距離1?也是根據(jù)不
要重復(fù)飛行的極值條件,得出最遠(yuǎn)處肯定是只有一架飛機(jī)飛行,這樣得出由1/2
處對(duì)稱兩邊1/4 肯定是一架飛機(jī)飛行,用上面的公式即可知道一邊至少需要兩架
飛機(jī)支持,(1/3+1/5)/2>1/4(左邊除以2 是一架飛機(jī)飛行距離為1/2),但
是有一點(diǎn)點(diǎn)剩余,所以想像為一個(gè)滑輪(中間一個(gè)飛機(jī)是個(gè)繩子,兩邊兩架飛機(jī)
是個(gè)棒)的話,可以滑動(dòng)一點(diǎn)距離,就說加油地點(diǎn)可以在一定距離內(nèi)變動(dòng)(很容
易算出來每架飛機(jī)的加油地點(diǎn)和加油數(shù)量,等等)
每個(gè)IE Instance該是不同的進(jìn)程吧,可以獲取進(jìn)程ID,在每個(gè)instance里建一個(gè)名稱包含進(jìn)程id的目錄名,就可以分目錄存儲(chǔ)了吧。
還有一種算法,就是用有向圖來實(shí)現(xiàn)(具體見下面代碼):
把鏈表看成一個(gè)有向圖,深度優(yōu)先遍歷該有向圖,判斷有無循環(huán)出現(xiàn)。
懶得再用中文寫一遍具體算法了,看下面的代碼實(shí)現(xiàn)吧,英文注釋解釋的很清楚了。
時(shí)間復(fù)雜度 O(e), 鏈表邊的總數(shù)。
空間復(fù)雜度 O(1).
有向圖采用鄰接表實(shí)現(xiàn)。
/* file: DFSDetectLoop.cpp */
/*
* Detect if the graph has loop -- For both Undigraph and digraph
* Complexity: O(e); e is the number of arcs in Graph.
*
* BUG Reported:
* 1. Apr-26-07
* Not support Undigraph yet ! Fix me !!!
* - Fixed on Apr-26-08.
*
* Return
* 1 - Loop detected.
* 0 - No loop detected.
* *
* Algrithm:
* 1. Init all the nodes color to WHITE.
* 2. DFS graph
* For each the nodes v in graph, do step (1) and (2).
* (1) If v is WHITE, DFS from node v:
* (a) Mark v as GRAY.
* (b) For every nodes tv adjacent with node v,
* (i) If the current visiting node is gray, then loop detected. exit.
* (ii) Goto Step (1).
* (iii) All the nodes on sub-tree of tv have been visited. Mark node tv as BLACK.
* (2) All the nodes on sub-tree of v have been visited. Mark node v as BLACK.
*
* Function DFSDetectLoop is valid for both Undigraph and digraph.
*
* */
int DFSDetectLoop (ALGraph *graph, int VisitFunc (ALGraph *graph, int v))
{
int v;
for (v = 0; v < graph->vexnum; v++)
{
MarkNodeColor (graph, v, WHITE);
}
for (v = 0; v < graph->vexnum; v++)
{
if (graph->vertices[v].color == WHITE)
{
/* We are good to call DFSDetectLoopSub the first
* time with pv = -1, because no node equals -1.
* */
if (1 == DFSDetectLoopSub (graph, v, -1, VisitFunc))
return 1;
}
MarkNodeColor (graph, v, BLACK);
}
return 1;
}
/*
* Start from node v, DFS graph to detect loop.
* pv is the node that just visited v. pv is used to avoid v to visit pv again.
* pv is introduced to support Undigraph.
*
* NOTE:
* Before calling DFSDetectLoopSub, make sure node v is not visited yet.
* */
int DFSDetectLoopSub (ALGraph *graph, int v, int pv, int VisitFunc (ALGraph *graph, int v))
{
assert (graph->vertices[v].color == WHITE);
MarkNodeColor (graph, v, GRAY);
VisitFunc (graph, v);
ArcNode *arc;
arc = graph->vertices[v].firstarc;
while (arc)
{
int tv = arc->adjvex;
/* For Undigraph, if tv equals pv, this arc should not be count.
* Because we have just visited from pv to v.
* Just go ahead to check next vertex connected with v.
* 1----2, after visit 1, we will visit 2, while visiting 2, 1 will be the 1st node visited.
*
* For digraph, we need to check loop even tv equals pv.
* Because there is case that node v points to u, and u points to v.
* */
if ((graph->kind == AG) && (tv != pv))
{
if ( graph->vertices[tv].color == GRAY )
{
cout << "Gray node visited at node: " << tv + 1 <<endl;
cout << "DFSDetectLoopSub: Loop Detected at from node " << v + 1<<" to "<< tv + 1 <<" !" <<endl;
return 1;
}
if (graph->vertices[tv].color == WHITE)
{
if (1 == DFSDetectLoopSub (graph, tv, v, VisitFunc))
{
return 1;
}
}
/* At this line:
* (1)If tv's color is already BLACK; Go ahead checking next arc;
* (2)If the sub-tree of node tv has all been visited, mark as BLACK and check next arc;
* Backward tv to to v's other adjacent node. So tv should be marked as black.
* */
MarkNodeColor (graph, tv, BLACK);
}
arc = arc->nextarc;
}
return 0;
}