1. 程式人生 > >一道國外前端面試題引發的Coding...

一道國外前端面試題引發的Coding...

觀察 inf log 微信公眾 param aar i++ 不用 一次

剛剛看到CSDN微信公眾號一篇文章,關於國外程序員面試前端遇到的一道測試題,有點意思,遂寫了下代碼,並記錄一下~

題目是這樣的:

[‘Tokyo‘, ‘London‘, ‘Rome‘, ‘Donlon‘, ‘Kyoto‘, ‘Paris‘]
// YOUR ALGORITHM
[
    [‘Tokyo‘, ‘Kyoto‘],
    [‘London‘, ‘Donlon‘],
    [‘Rome‘],
    [‘Paris‘]
]

也就是說給定一個字符串數組:

[‘Tokyo‘, ‘London‘, ‘Rome‘, ‘Donlon‘, ‘Kyoto‘, ‘Paris‘]

經過自己寫的算法變換後,要得到下面這個數組:

[
    [‘Tokyo‘, ‘Kyoto‘],
    [‘London‘, ‘Donlon‘],
    [‘Rome‘],
    [‘Paris‘]
]

經過觀察,原來題目要求把原數組中“相關”的元素組成新的數組,並作為最終答案數組的一個元素。

“相關”的意思是指:如果一個長度為 N 的字符串 A,依次將最左邊的字符挪到最右邊,重復 N-1 遍,得到 N 個(包含原字符串)字符串中的任意一個,跟字符串 B 相同(不考慮大小寫),則認為 A 跟 B “相關”。

於是,先來一個比較函數:

/**
 * 匹配函數 compareString
 * @param strA 要比較的字符串
 * @param strB 要比較的另一個字符串
 * @return 0: 表示匹配, -1: 表示不匹配
 
*/ function compareString(strA, strB) { if(strA.length !== strB.length)return -1;//長度不相等肯定不會匹配,立即返回 var a = strA.toLowerCase();//先將要比較的字符串轉換成小寫,下同 var b = strB.toLowerCase(); var i = 0; do{ if(a === b)return 0;//匹配,返回 0 b = b.substr(1) + b.substr(0, 1);//將第一個字符轉移至尾部 i++; }
while(i < b.length); return -1;//360 度檢查還沒認出來,那 A、B 兩個是無緣了~ }

假設原數組是:

var dataArr = [‘Tokyo‘, ‘London‘, ‘Rome‘, ‘Donlon‘, ‘Kyoto‘, ‘Paris‘]; 

結果存入:

var result = [];

那麽可以如下處理:

while(dataArr.length > 1) {
    var str = dataArr.shift();//取數組第一個元素,與後續元素逐個對比
    var newArr = [];//本輪匹配結果存儲的數組
    newArr.push(str);//先將要對比的 str 存入數組
    var i = 0;
    
    //為什麽不用 for 循環呢?
    //因為在循環體內可能“剪切”元素導致數組長度變小,所以不能用固定次數循環
    while(i < dataArr.length) {
        if(compareString(str, dataArr[i]) == 0) {//匹配
            newArr.push(dataArr[i]);//將匹配元素加入新數組
            //從原數組中移除當前元素
            //當前元素移除後,後面的元素依次往前移動一格,因此下一次遍歷的下標不變
            dataArr.splice(i, 1);
        }else{
            i++;//本輪循環沒有匹配上,下一輪匹配輪到後面一個元素,因此下標要加 1
        }
    }
    
    result.push(newArr);//將本次匹配數組加入 result 數組
}

if(dataArr.length > 0)result.push(dataArr);//落單的跟上

用 node 執行,結果如下圖:

技術分享圖片

完整代碼如下:

/*
[‘Tokyo‘, ‘London‘, ‘Rome‘, ‘Donlon‘, ‘Kyoto‘, ‘Paris‘]
// YOUR ALGORITHM
[
    [‘Tokyo‘, ‘Kyoto‘],
    [‘London‘, ‘Donlon‘],
    [‘Rome‘],
    [‘Paris‘]
]
*/

//======================================

/**
 * Coding by Jaffray Tan
 * 2018.07.03
 */
var dataArr = [‘Tokyo‘, ‘London‘, ‘Rome‘, ‘Donlon‘, ‘Kyoto‘, ‘Paris‘]; 
console.log(‘\nInit array:\n‘, dataArr);//先輸出原數組
var result = [];

while(dataArr.length > 1) {
    var str = dataArr.shift();//取數組第一個元素,與後續元素逐個對比
    var newArr = [];//本輪匹配結果存儲的數組
    newArr.push(str);//先將要對比的 str 存入數組
    var i = 0;
    
    //為什麽不用 for 循環呢?
    //因為在循環體內可能“剪切”元素導致數組長度變小,所以不能用固定次數循環
    while(i < dataArr.length) {
        if(compareString(str, dataArr[i]) == 0) {//匹配
            newArr.push(dataArr[i]);//將匹配元素加入新數組
            //從原數組中移除當前元素
            //當前元素移除後,後面的元素依次往前移動一格,因此下一次遍歷的下標不變
            dataArr.splice(i, 1);
        }else{
            i++;//本輪循環沒有匹配上,下一輪匹配輪到後面一個元素,因此下標要加 1
        }
    }
    
    result.push(newArr);//將本次匹配數組加入 result 數組
}

if(dataArr.length > 0)result.push(dataArr);//落單的跟上

console.log(‘\n\nResult array:\n‘, result);//輸出結果

//=====================================

/**
 * 匹配函數 compareString
 * @param strA 要比較的字符串
 * @param strB 要比較的另一個字符串
 * @return 0: 表示匹配, -1: 表示不匹配
 */
function compareString(strA, strB) {
    if(strA.length !== strB.length)return -1;//長度不相等肯定不會匹配,立即返回
    
    var a = strA.toLowerCase();//先將要比較的字符串轉換成小寫,下同
    var b = strB.toLowerCase();
    var i = 0;
    
    do{
        if(a === b)return 0;//匹配,返回 0
        b = b.substr(1) + b.substr(0, 1);//將第一個字符轉移至尾部
        i++;
    }while(i < b.length);
    
    return -1;//360 度檢查還沒認出來,那 A、B 兩個是無緣了~
}

一道國外前端面試題引發的Coding...