1. 程式人生 > >考基本功的 10 個簡單程式設計題

考基本功的 10 個簡單程式設計題

一、給一個數 N,判定這個數是否是素數。
1、先讓面試者說素數的定義,如果不知道可以提示素數的定義
2、最差的面試者,會沒有思路,這是很可怕的,大學第一學期學完,應該學會這個題
3、一般的面試者,能比較費勁地寫出正確的程式,但是可能存在邊界、標記等問題。
4、寫出程式出來,可以進一步問,優化的空間,在哪裡,所謂優化,無非就是時間和空間複雜度。
5、只有少數的面試者,能進行幾輪優化
6、有訓練的面試者可能知道一些特定的高效方法

<?php
    check_ss(8);
 
    function check_ss($num) {
        for($i=2; $i < $num ; $i++) {
            if($num % $i == 0) {
                echo $num. '不是素數';
                exit;
            }
        }
        
        echo $num. '是素數';
    }

二、給一個數 N,把 2 到 N 之間的素數輸出出來
1、這個題比上面這個難度加大了一層
2、可以限定,不讓其使用子函式,增加邏輯上的複雜度
3、其他的,同樣一層層考優化的方法

<?php
 
$no=0;//用於標記經檢驗前後是否是素數,0表示是;1不是;
 
for($i=2;$i<=1000;$i++){//迴圈2-1000
 
    for($j=2;$j<$i;$j++){//檢驗當前$i是否是素數
        if($i%$j==0){
            $no=1;//如果取餘得0,不是素數,改值為1
        }
    }
 
if($no==0){echo $i;}//經過檢驗後如果$no仍為0,則$i是素數。
 
}
?>

三、寫出三角狀的 9*9 乘法表
1、這個題目面向基礎比較差的面試者
2、最差的面試者,也會說沒有思路,在學校會寫,現在忘記了
3、比較一般的能寫出來,更進行一步的,可以讓其用幾種迴圈來寫,寫倒三角
4、如果都沒有問題,迴圈思維邏輯值得肯定
<?php

    for($a = 1; $a <10; $a++){
        echo "<table>";
        echo "<tr>";
        for ($b=1; $b <= $a; $b++) {
            echo "<td>";
            echo "$a*$b=".$a*$b;
            echo "</td>";
        }
        echo "</tr>";
        echo "</table>";
    }
?>

四、用遞迴編寫求和或者求階乘的函式
1、可以先讓其不用遞迴寫一遍
2、再讓其遞迴實現
3、最差的面試者同樣無法下手
4、接下來可以探討遞迴的一些優劣之處,在哪些常見演算法中用到了遞迴
5、也可以問問1024的階乘有多少個零這種的問題。

php遞迴的方法求和1+2+3+...+n
function add($n){
  if($n==1) return 1;
else
   return $n+add($n-1);   //沒注意
}

用php實現1+(1+2)+(1+2+3)+...+(1+2+...n) 遞迴求和
function getSum($n) {
  if ($n > 1) {
    $tempSum = $n * (1 + $n) / 2;  // 當然這部分可以拆成另一個遞迴來求和,如果有需要在說
    return $tempSum + getSum(--$n);
  }
  else {
    return $n;
  }
}
$result = getSum(20);

求n的階乘
<?php

function f($n) 

   $out = -1;
   if($n<0)
       echo "輸入不能是負數";
   else if($n==0||$n==1)
       $out=1;
   else $out=f($n-1)*$n; 
   return $out;
}

echo f(6);

?>
五、將字串反轉,比如 “abcdefg” 轉化為 "gfedcba"
1、如果面試者使用 C 語言效果最佳
2、可以進一步考察這種形式的反轉演算法, www.ucai.cn => cn.ucai.www

<?php
    $str = "hello";
 
    function fan($str) {
        //宣告一個臨時的變數
        $n = "";
        //獲取字串長度
        $m = strlen($str)-1;
        for($i=$m; $i >= 0;  $i--) {
            $n .= $str{$i};
        }  
        return $n;
    }
    echo fan($str);
?>

支援中文:
<?PHP
   
    function getRev($str,$encoding='utf-8'){
        $result = '';
        $len = mb_strlen($str);
        for($i=$len-1; $i>=0; $i--){
            $result .= mb_substr($str,$i,1,$encoding);
        }
        return $result;
    }
    $string = 'OK你是正確的Ole';
    echo getRev($string);

?>

六、求出 IPV4 IP地址所對應的整數,比如 192.168.199.1 對應整數 3232286465
1、可以先讓其求字串所對應的整數這個簡單演算法
2、如果面試者使用 C 語言效果最佳

<?php
$ip = gethostbyname('www.sharejs.com');
$out = "The following URLs are equivalent:<br />\n";
$out .= 'http://www.sharejs.com/, http://' . $ip . '/, and http://' . sprintf("%u",

ip2long($ip)) . "/<br />\n";
echo $out;
?>
這是如何計算的,目前我知道有兩個演算法。

其一
<?php
function ip2int($ip){
    //我們先把ip分為四段,$ip1,$ip2,$ip3,$ip4
    list($ip1,$ip2,$ip3,$ip4)=explode(".",$ip);
    //然後第一段乘以256的三次方,第二段乘以256的平方,第三段乘以256
    //這即是我們得到的值
    return $ip1*pow(256,3)+$ip2*pow(256,2)+$ip3*256+$ip4;
}
?>

其二,用位運算
<?php
function ip2int($ip){
    list($ip1,$ip2,$ip3,$ip4)=explode(".",$ip);
    return ($ip1<<24)|($ip2<<16)|($ip3<<8)|($ip4);
}
?>
我們會發現,有些ip轉化成整數後,是負的,這是因為得到的結果是有符號整型,最大值是2147483647.

要把它轉化為無符號的,可以用
sprintf("%u",ip2long($ip);
就能轉換為正整數。而且得到的結果用long2ip也可以正常轉換回原來的ip地址。也可以用ip2long來驗

證一個ip是否是有效的,如
<?php
function chk_ip($ip){
    if(ip2long($ip)=="-1") {
       return false;
    }
    return true;
}
//應用
var_export(chk_ip("10.111.149.42"));
var_export(chk_ip("10.111.256.42"));
?>
將輸出true和false


七、使用最高效的演算法,將一堆100以內的數排序,不能使用排序的庫函式
1、不允許使用現成的各種排序演算法
2、要求一遍遍歷完成即實現排序
3、也可以問:如何對n個數進行排序,要求時間複雜度O(n),空間複雜度O(1)
看上去似乎任何已知的演算法都無法做到,如果誰做到了,那麼所有的排序方法:QuickSort,ShellSort

,HeapSort,BubbleSort等等等等,都可以扔掉了,還要這些演算法幹嗎阿,呵呵。不過實際上,在數字

範圍有限制的情況下,是有一個這樣的演算法的,只需要用一個數組記錄每個數字出現次數就可以了。

假定你的數字範圍在0到65535範圍之內,定義一個數組count[65536](這個空間是常量,和n無關,所以

是O(1) ),初值全部為0。
那麼假設有下面這些數字:
100
200
300
119
0
6
...
那麼對於每個這個數字,都做在count中記錄一下:
100 => count[100]++
200 => count[200]++
300 => count[300]++
119 => count[119]++
0 => count[0]++
6 => count[6]++
...
最後,遍歷一邊所有這些數字就可得到0~65535每個數字的個數(在count陣列中),然後再順序遍歷

count陣列,count[n] = m,則輸出m個n,(比如說有count[3] = 2, 那麼說明有2個數字3),依次輸出

,最後可得結果。第一次遍歷是O(n),第二次遍歷是O(1),為常量,所以最後的時間複雜度為O(n),而

空間複雜度為O(1)

#include
int main()
{
int a[] = {10,6,9,5,2,8,4,7,1,3};
int len = sizeof(a) / sizeof(int);
int temp;
for(int i = 0; i < len; )
{
temp = a[a[i] – 1];
a[a[i] – 1] = a[i];
a[i] = temp;
if ( a[i] == i + 1)
i++;
}
for (int j = 0; j < len; j++)
cout< return 0;
}

這個演算法很簡單,相信大家都會,只是這個題太過於變態了,一般會把面試者嚇住

八、有上千萬個1000萬以內的資料,請排除掉重複的數
1、可以轉化為找出重複的數
2、要求空間最省
3、要求一次遍歷完成整個查詢
4、延伸:如果用 Shell 命令實現怎麼辦?通過awk去除重複行
100萬條,也就是16M而已,記憶體頂得住的。
遍歷一遍,在記憶體裡構造一個該資料的hash表,就搞定了。
參考:
1、怎麼在海量資料中找出重複次數最多的一個?
   方案1:先做hash,然後求模對映為小檔案,求出每個小檔案中重複次數最多的一個,並記錄重複

次數。然後找出上一步求出的資料中重複次數最多的一個就是所求(具體參考前面的題)。
2、上千萬或上億資料(有重複),統計其中出現次數最多的錢N個數據。
  方案1:上千萬或上億的資料,現在的機器的記憶體應該能存下。所以考慮採用hash_map/搜尋二叉樹/

紅黑樹等來進行統計次數。然後就是取出前N個出現次數最多的資料了,可以用第2題提到的堆機制完成

九、如果從1000萬行左右的檔案中,隨機地取出 10萬行左右的樣本資料
1、要求一遍檔案掃描完成資料獲取
2、空間最省,將結果輸出在另外一個檔案中
3、可以要求寫出完整程式,包括 fopen 的使用等

十、字串庫函式的相關實現思路
1、檢測一個字串是否包含在另一個字串中
2、實現 trim 函式、strlen 函式
3、複雜一些的:求出給定字串中最長的迴文字元的長度以及把它們給輸出來。

strpos($a, $b) !== false 如果$a 中存在 $b,則為 true ,否則為 false。
用 !== false (或者 === false) 的原因是如果 $b 正好位於$a的開始部分,那麼該函式會返回int

(0),那麼0是false,但$b確實位於$a中,所以要用 !== 判斷一下型別,要確保是嚴格的 false。
其它的還有 PHP 原生支援的函式,如 strstr(),stristr() 等,直接判斷就可以了。

通過正則表示式替換,功能更強
php去除字串首尾空格(包括全形)
  複製程式碼 程式碼如下:

  <?
$str="          ";
$str = mb_ereg_replace('^( | )+', '', $str);
$str = mb_ereg_replace('( | )+$', '', $str);
echo mb_ereg_replace('  ', "\n  ", $str);
?>


計字串長度:
while ( isset($str{$i}) && ++$i );