首頁  >  問答  >  主體

javascript - 編程,演算法的問題

前天面試了一個問題
請使用js,python,java,c,c 之類的語言,在10秒內計算出100億的數據,並且(只能在3秒內)完成,偶數在奇數前
格式如下
1,2,3,4,5
輸出結果是
2,1,4,3,6,5,
問題2:在1的程式碼之上,要求不能使用for while關鍵字,從100億裡面取所有的質數(時間不能超過3秒)
這個怎麼搞?

PHP中文网PHP中文网2709 天前923

全部回覆(4)我來回復

  • 我想大声告诉你

    我想大声告诉你2017-06-12 09:27:56

    第一個問題沒看懂,是說2個數字為一對,然後偶數在奇數前面?

    第二個問題簡單啊,不能用循環,那就用陣列迭代唄。

    回覆
    0
  • 代言

    代言2017-06-12 09:27:56

    話說 phpforeach 算麼(笑

    我覺得面試官的意圖是讓你寫一個遞歸函數?嗯估計是。

    回覆
    0
  • PHP中文网

    PHP中文网2017-06-12 09:27:56

    前天面試了一個問題
    請使用js,python,java,c,c++之類的語言,在10秒內計算出100億的數據,並且(只能在3秒內)完成,偶數在奇數前
    格式如下
    1,2,3,4,5
    輸出結果是
    2,1,4,3,6,5,
    問題2:在1的程式碼之上,要求不能使用for while關鍵字,從100億裡面取所有的質數(時間不能超過3秒)
    這個怎麼搞?


    既然不能用 for while

    那麼遞歸性能就不太夠。 。 。但是我還是用了一些。 。 For Performance

    可能有很巧妙的辦法

    。 。 。 100億 的量值 應該是有的。 我還沒發現。

    代碼

    100 億有點大啊 我先 10 萬了

    var n = 1000 * 1000; 
    var test = new Array(n).fill(n).map((e, idx) => idx); 

    這樣可以得到 10 萬長度的陣列 自然數。


    Next

    1. 偶數在前 奇數在後

    觀察之後發現,奇數 + 1偶數 - 1 就可以了

    var isEven = n => n % 2 === 0; 
    
    var res001 = test.map((e, idx) => {
        if (isEven(e)){
            return e - 1; 
        } else {
            return e + 1; 
        }
    }); 

    完成第一個問題

    ScreenShot One

    Next

    下一個問題是在上面的基礎上取得質數 即從 zs 裡取得所有質數

    查了一下關於質數的問題,別人說 質數分佈在 6 的倍數的左邊或者右邊 那麼我只要遍歷 每一個6的倍數的左邊和右邊 並判斷他們是不是質數即可。

    連結: 判斷一個數字是否為質數/質數-從普通判斷演算法到高效率判斷演算法思路

    // 剔除第一个负数 
    var zs = res001.slice(1); 
    
    var is6x = n => n % 6 === 0; 
    
    
    var isPrime = n => {
         let temp = Math.sqrt(n);  
         
         for(let i = 2; i <= temp; i++){
             if(n % i === 0){
                 return false; 
             }
         }
         
         return true;  
    }  
    
    
    var lasts = zs.filter(is6x).reduce((acc, cur) => {
        let left = cur - 1, right = cur + 1; 
        if (isPrime(left)) acc.push(left); 
        if (isPrime(right)) acc.push(right); 
        
        return acc; 
    }, []); 
    
    console.log(lasts); 

    ScreenShot Two

    不知道對不對 ...

    不過還需要把 小於 6 的質數 1 2 3 5 單獨拼回去。 (這裡沒拼)

    性能

    把上面寫的程式碼黏起來

    var isEven = n => n % 2 === 0; 
    
    
    var is6x = n => n % 6 === 0; 
    
    var isPrime = n => {
         let temp = Math.sqrt(n);  
         
         for(let i = 2; i <= temp; i++)
            if(n %i== 0){
                return false; 
            }
         return true;  
    }  
    
    
    function timeTest(n){
        var test = new Array(n).fill(n).map((e, idx) => idx); 
        var res001 = test.map((e, idx) => {
            if (isEven(e)){
                return e - 1; 
            } else {
                return e + 1; 
            }
        }); 
        var zs = res001.slice(1); 
        
        var lasts = zs.filter(is6x).reduce((acc, cur) => {
            let left = cur - 1, right = cur + 1; 
            if (isPrime(left)) acc.push(left); 
            if (isPrime(right)) acc.push(right); 
            
            return acc; 
        }, []); 
        
        return lasts; 
    }

    test

    var n = 1000 * 10000; 
    
    console.time('1000 万')
    timeTest(n); 
    console.timeEnd('1000 万');
    

    1000 萬 結果如圖


    花了 13.8 秒 不可能做到 10 + 3 秒內完成 100億 的體積。

    我的電腦是 i5-4210M 12G Chrome 58

    JavaScript 做不到這樣的效能: 100億 個數字 13 秒內 ....

    好幾個 G 的資料 ......

    按照上面的思路來做,即使是 C/C++ 估計也很難13秒跑完100億。

    解決問題為主。

    Links

    判斷一個數是否為質數/素數-從普通判斷演算法到高效率判斷演算法思路

    回覆
    0
  • PHP中文网

    PHP中文网2017-06-12 09:27:56

    首先感謝樓上的求質數的演算法,我貼下我的結果和程式碼(只有1000萬,一億瀏覽器直接炸掉了,而且求質數那裡不能用遞歸(我測試的結果),不然也得炸,只能迭代)。

    瀏覽器裡面的結果:

    node裡面的結果:

    var arr = [];
    
    console.time("1000万");
    for( var i = 1; i <= 10000000; i++ ){
        arr.push(i);
    }
    
    for( var j = 0, len = arr.length;j < len; j+=2 ){
        arr[j]++;
        arr[j+1]--;
    }
    
    function isPrime(num,sqrt){
         if(num == 1)
         return false;
         if(num == 2 || num == 3 )  
         return true;  
         if(num % 6 != 1 && num % 6 != 5)  
         return false;  
         var tmp = sqrt(num);  
         for(var i= 5;i<=tmp; i+=6 )  
            if(num % i == 0 || num % ( i + 2) == 0 )  
            return false ;  
    
         return true;  
    };
    
    function getPrime(sourceArray,array,isPrime,sqrt){
    
        sourceArray.map(function(num,idx){
            if(isPrime(num,sqrt)){
                array.push(num);
            }
        });
    
        return array;
    };
    
    var result = getPrime(arr,[],isPrime,Math.sqrt);
    
    console.timeEnd("1000万");

    回覆
    0
  • 取消回覆