前天聽同學說下午百姓網會來學校,有現場筆試,可以直接去。
效率確實好高,到了後準時開始,廢話不多。筆試半個小時,四個開放題。大致如下:
- 給出一種方法,用於精確計算一個不規則形狀的面積。
- 有一種母牛,壽命5年,第二年底會生出一頭同品種母牛,第四年又生出一頭,第五年死去。現有一頭這樣的母牛,問N年後有多少母牛?
- 在你的理解中,for語句有多少種用法/用途?
- 用一種編程語言計算從m乘到n後結果中有多少個0?(m<=n)
第二題好像曾經做過。。。但是下午沒有寫出來,寫了思路:建樹,節點是牛,子節點是父節點生的小牛,權值是間隔的年份,每個節點有個深度值,第一個點深度值爲0。因爲每頭牛隻能生兩胎,所以畫下來就是個二叉樹了。求N年後牛的數目時,建個log(N/2)層的樹,遍歷,深度值在(N-5,N] 的就是活着的牛了。
我比較弱,沒發現規律。其實每頭牛隻能生兩胎,兩胎後下一年就去世了。所以偶數年還活着的要麼是還沒生過,要麼生過一胎,在年底都可以再生一胎;奇數年從5開始,每年都會少一頭。
int f(int n){
if (n==1 || n==0)
return 1;
if(n==3)
return 2;
if(n%2==0)
return f(n-1)*2;
else
return f(n-1)-1;
}
回來後查了下百姓網的筆試題,只看到一個關於判斷查詢子集的討論。
原文:
原題見 百姓網公開筆試題:查詢條件的子集判斷
我的答卷在 http://soulogic.com/subset_test/subset_test.tar.gz
演示地址爲 http://soulogic.com/subset_test/
碰到這道題時才意識到自己的見識淺薄,非等到這種題出來才能明白,高等數學對於程序員而言是多麼重要。其中最難最關鍵的部分是在留言裏看到了 qmigh 的解釋才搞定的。
這道題分三部分:把查詢語句轉成數組結構,然後把層級混亂的條件最終分解成 以 OR 關聯的 AND 合集(也就是 qmigh 所解釋的),以及按規則來讀取並判斷兩個數組。在我的代碼裏,Class TreeStore 負責前兩步,Class SetCheck 負責後一步。
由於我完全說不出任何術語,只能把數組的轉換過程列一下了。
原始語句
a = 1 AND (b = 1 OR (c = 1 AND (e > 1 OR f = 1)))
第一步,循環用正則,從最裏面的括號開始,分解出每一級。這樣每一級裏面都沒括號了
Array
(
[1] => e > 1 OR f = 1
[2] => c = 1 AND _1
[3] => b = 1 OR _2
[4] => a = 1 AND _3
)
按照 AND OR 的優先級進一步分解
Array
(
[AND] => Array
(
[0] => a = 1
[1] => Array
(
[OR] => Array
(
[0] => b = 1
[1] => Array
(
[AND] => Array
(
[0] => c = 1
[1] => Array
(
[OR] => Array
(
[0] => e > 1
[1] => f = 1
)
)
)
)
)
)
)
)
將上述數組最終分解成 OR 下的一堆 AND
Array
(
[OR] => Array
(
[0] => Array
(
[AND] => Array
(
[0] => a = 1
[1] => b = 1
)
)
[1] => Array
(
[AND] => Array
(
[0] => a = 1
[1] => c = 1
[2] => e > 1
)
)
[2] => Array
(
[AND] => Array
(
[0] => a = 1
[1] => c = 1
[2] => f = 1
)
)
)
)
其實就是按 qmigh 說的,做一下轉換,把最開始的表達式轉換爲
(a = 1 AND b = 1) OR (a = 1 AND c = 1 AND e > 1) OR (a = 1 AND c = 1 AND f = 1)
如果只有一個表達式,可以理解爲只有一個元素的 AND
如果
(a > 3) AND (b < 4)
可以用數組表示爲
array(
[0] => a > 3
[1] => b < 4
)
那麼
a > 3
可以用數組表示爲
array(
[0] => a > 3
)
OR 也同理
用來判斷時的數組樣子,也就是 Class TreeStore 的最終輸出
Array
(
[0] => Array
(
[a] => Array
(
[=] => Array
(
[1] => 1
)
)
[b] => Array
(
[=] => Array
(
[1] => 1
)
)
)
[1] => Array
(
[a] => Array
(
[=] => Array
(
[1] => 1
)
)
[c] => Array
(
[=] => Array
(
[1] => 1
)
)
[e] => Array
(
[>] => 1
)
)
[2] => Array
(
[a] => Array
(
[=] => Array
(
[1] => 1
)
)
[c] => Array
(
[=] => Array
(
[1] => 1
)
)
[f] => Array
(
[=] => Array
(
[1] => 1
)
)
)
)
至於判斷,應該不算難,按照上面的數組挨個字段判斷就可以了。以及判斷父集合是否有子集合沒有的字段,如果有,那肯定不是子集關係了。
寫完之後一直沒把握到底做的對不對,要是有類似 ACID 2 或者 Man or boy test 那樣的東西就好了。如果能有人告訴我有什麼複雜條件是我的代碼判斷不了的,實在感激不盡(當然,用 10MB 長的條件語句搞溢出不算……)
看了看 其他人的答案,“從離散數學到編譯原理”,這標題總結得不錯,核心也就是這兩個問題吧。我用正則來把編譯”那部分繞過去了,但從執行效率上講是很蠢的。
看來大家都知道畫蛇添足的故事,所以都只做了滿足要求(“爲了簡單起見,只需要實現最簡單的AND, OR邏輯操作,大於,等於,小於三種比較操作就好”)的最小實現。
如果能有PHP同好的題解能相互學習學習那是最好了,其他語言的看不懂 -_-
原來還自詡爲程序員,被這道題臊的不行,我現在的定義是,沒法獨自實現一個 C Compiler 的人充其量也不過是 coding fans。
————————————————原文終。(表示沒有學過PHP- -)
後記:我太弱了,筆試沒過。。。不過上面這個題目蠻好玩的樣子。看到一個用python實現的:http://www.360doc.com/content/11/0410/20/4825484_108675437.shtml
再記:後來看到有人po了一樣的題目,要是早點看到就好了!(不過水平弱就是弱- -)http://www.fenzhi.com/gsmsh479121.html
以及一個相似的:http://www.chengxuyuans.com/job_interview/64110.html