OJ (Online Judge)使用


 這是一種方式,我們還可使用另外一種方式:

process.stdin.resume();
process.stdin.setEncoding('ascii');

var input = "";
var input_array = "";

process.stdin.on('data', function (data) {
    input += data;
});

process.stdin.on('end', function () {
    
    input_array = input.split("\n");
    var str = input_array[0];
    console.log(str.split(' ').reverse().join(' '));    
});

這種方式比之前的那種方式會更好一些! 即data事件的時候,我們一直處於接受數據的時候,然后一旦觸發了 end 事件,說明我們這次的輸入結束。 然后呢, 得到的 input_array就是輸入的所有行,我們直接使用就可以了。

其實,我們可以知道牛客網的方式應該是每次測試用例每次就調用函數。

 

 

 

說明: 后者為什么好呢? 因為通過后者,我們可以准確地判斷出來到底什么時候結束,而前者在某些情況下,我們是無法判斷函數是何時結束的,如下所示:

 

如果我們不用后者這種方式,那么我們就沒有辦法確定一共有多少個case,就沒法做這道題了。 

 最終ac的代碼如下所示:

       process.stdin.resume();
       process.stdin.setEncoding('ascii');

       var input = "";
       var input_array = '';

       process.stdin.on('data', function (data) {
           input += data;
       });

       process.stdin.on('end', function () {
           // 目前的這個input_array就是輸入的所有行,我們現在的目的就是如果把這兩個case放在一個一個數組中。 
           input_array = input.split("\n");
           var nLine = 0;

           var hhh = [];

           while(nLine < input_array.length){
               var line = input_array[nLine++].trim();
// 這一句非常關鍵有了這一句,因為有時候,這個沒有處理好,可能輸入就會出現問題。         
if(line === ''){             continue;         }
// 這種方式我們就可以把輸入的所有行通過 hhh 這個數組來拿到了。
hhh.push(line);     }
var arr = []; for (var i = 0; i < hhh.length; i++) { // 當輸入是一個數字的時候,就是M或者是N 下面的isNaN(Number(hhh[i]))的判斷非常重要,通過這一句,我們就可以很輕松地來分類了 。 if (!isNaN(Number(hhh[i]))) { arr.push(hhh.slice(i + 1, i + Number(hhh[i]) + 1)); } } // 循環之后,得到的數組就是一個二維數組,一定是偶數個,比如arr數組的第一個元素就是['aaa', 'aaa', 'baa'], 那么arr的第二個元素就是 ['aa', 'ba'] var result = []; // 創建一個用於最后輸出的元素的數組,最終遍歷輸出即可。 for (var j = 0; j < arr.length; j++) { if (j % 2 == 0) { for (var k = 0; k < arr[j + 1].length; k++) { var count = 0; for (var m = 0; m < arr[j].length; m++) {
// 這里也很巧妙,就是對於一個字符串是否是另一個字符串的子串,我們可以通過 indexOf 的方式來解決,這樣就不需要耗時的遍歷的方法或者使用復雜的KMP算法了。
if (arr[j][m].indexOf(arr[j + 1][k]) != (-1)) { count++; } } result.push(count); } } } for (var n = 0; n < result.length; n++) { console.log(result[n]); } });

 

 

 

 





 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第一部分:

1. 360、完美世界等使用的編程環境(OJ系統)

http://oj.acmcoder.com/ExamNotice.html  對於OJ系統進行了說明。

http://oj.acmcoder.com/QA/ 常見問題

下面的代碼輸出的是a+b, line是用於輸入的。

var line;
while(line = read_line()){
    line = line.split(' ');
    print(parseInt(line[0]) + parseInt(line[1]));
}

 

  下面是一個成功運行的題目,如下:

  注意的幾個地方

 

  1.  read_line() 得到的是輸入的字符串,如 "81 4"
  2.  顯然,通過read_line().split(" ")得到的是一個字符串數組(注意: split(" ")中有一個空格),所以如果我們希望使用數字,就應該Number轉換一下
  3.  print()就相當於console.log(somethin); 再加一個<br/>(換行)。
  4.  最好使用上述固定的格式: 即在while循環內調用函數,在調用的函數里輸出。
  5.  對於本題而言,應當注意 toFixed() 是用在最后, 這才是最精確的。

 

 下面的是將輸出使用空格分開,我最后的正確率是88%,不知道具體錯在了哪里...

 

 

 

 

2.網易使用的編程環境(牛客網提供OJ系統)

https://www.nowcoder.com/discuss/276

https://www.nowcoder.com/test/question/0147cbd790724bc9ae0b779aaf7c5b50?pid=2811407&tid=7485771 和網易的題是類似的

var readline = require('readline');
const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
});
rl.on('line', function(line){
   var tokens = line.split(' ');
    console.log(parseInt(tokens[0]) + parseInt(tokens[1]));
});

第一句是指引入了readline文件,第二句是指設定rl的輸入輸出為標准輸入輸出。第三句的意思就是輸入為line的函數,第四句的意思就是將輸入以空格分為數組。 第五句就是使用console.log()輸出。

 它的測試方法是,輸入大量的數據進行測試,並不是說只要有一個成立就行,而是所有的情況都成立才可以。

 

對於單行輸入,使用下面的方法:

即引入readline模塊,然后使用createInterface創建接口,接着使用on監聽line事件。 對於多行輸入的我們可以用一個數組接受多行,等到滿足了長度,就執行主要的函數。

var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on('line', function (line) {
    var str = line;
    var obj = {};
    
    for (var i = 0, len = str.length; i < len; i++) {
        if (!obj[str[i]]) {
            obj[str[i]] = 1;
        }
    }
    var count = 0;
    for (var key in obj) {
        count++
    }
    
    switch (count) {
        case 1:
            console.log(1);
            break;
        case 2: 
            console.log(2);
            break;
        default: 
            console.log(0);
            return;
          
    }
    
});

 

 

下面是一個多行輸入的題目,題目如下:

解答過程如下:

 

 

 

var readline = require('readline');
var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

var inputArr = [];

rl.on('line', function (line) {
    inputArr.push(line.trim());
    if (inputArr.length == 2) {
        var number = parseInt(inputArr[0]);
        var arr = inputArr[1].split(' ');
        // 首先將數組由小到大進行排列,這樣,d只可能是0或者正數。 
        arr.sort(function (a, b) {
            return a - b;
        });
        
        var diff = [];
        
        for (var i = 0, len = arr.length; i < len - 1; i++) {
            diff.push(arr[i + 1] - arr[i]);
        }
        
        var flag = true;
        for (var j = 0, jLen = diff.length; j < jLen - 1; j++) {
            if (diff[j + 1] !== diff[j]) {
                flag = false;
                break;
            }
        }
        
        if (flag) {
            console.log('Possible')
        } else {
            console.log('Impossible');
        }
    }
});

即在readline.on('line', function (line) {})函數中使用inputArr.length來判斷是否等於輸入的行數,等於的時候,再執行主要邏輯。

 

 看到了下面這種方式,其實也是蠻不錯的:

   

 即處理好輸入之后,調用一個函數,這樣,我們在本地調試的時候,直接copy這個函數過去就可以了, 非常清楚明了。

 

 

 

 

 

 

3.牛客網上的劍指offer方法又略有不同:(OJ系統)

https://www.nowcoder.com/practice/4060ac7e3e404ad1a894ef3e17650423?tpId=13&tqId=11155&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

例: 這里實現的是將一個字符串中的空格使用%20替換。

function replaceSpace(str)
{
    // write code here
     str = str.split(' ').join('%20');
 
         
      return str;
 
         
}
module.exports = {
    replaceSpace : replaceSpace
};

這里最后只要在函數內return 出希望返回的值即可。

 

 

 

第二部分: 答題需要的基本知識

 http://nodejs.cn/api/readline.html#readline_class_interface

 

一、nodejs中readline模塊的使用

  一般,我們在使用系統進行答題時,都是需要使用readline模塊的,這個模塊可以進行讀取行,然后就可以由系統進行檢測了。 

  readline模塊一般有一個interface類,這個類對應了一些事件和方法。readline還有一些其他的方法,但是最重要的還是interface類,下面我們簡單的講解、學習。

 

require('readline') 模塊提供了一個接口,用於從可讀流(如 process.stdin)讀取數據,每次讀取一行。 它可以通過以下方式使用:

const readline = require('readline')

例子,readline 模塊的基本用法:

const readline = require('readline')

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})

rl.question('你認為nodejs怎么樣?', (answer) => {
//對answer進行處理
console.log(`多謝你的反饋:${answer}`);

rl.close();
})

如下所示:

可以看到: 我們首先引入了readline模塊,然后創建了接口類,接着,我們調用了接口的question方法,第一個參數是一個字符串,第二個是回調函數,參數就是在命令行中輸入的,我們可以對之進行操作。

最后,我們必須使用rl.close()來關閉,否則,node程序不會自動關閉。 

 

 

 

Interface類

  readline.Interface 類的實例是使用 readline.createInterface() 方法構造的。 每個實例都關聯一個 input 可讀流和一個 output 可寫流。 output 流用於為到達的用戶輸入打印提示,且從 input 流讀取。

 

 

'close' 事件

當以下之一發生時,觸發 'close' 事件:

  • rl.close() 方法被調用,且 readline.Interface 實例已撤回對 input 流和 output 流的控制;
  • input 流接收到 'end' 事件
  • input 流接收到表示結束傳輸的 <ctrl>-D
  • input 流接收到表示 SIGINT 的 <ctrl>-C且 readline.Interface 實例上沒有注冊 SIGINT 事件監聽器。

監聽器函數被調用時不傳入任何參數。

當 'close' 事件被觸發時,readline.Interface 實例應當被視為已結束。

 

'line' 事件

每當 input 流接收到接收行結束符(\n\r 或 \r\n)時觸發 'line' 事件。 通常發生在用戶按下 <Enter> 鍵或 <Return> 鍵。

監聽器函數被調用時會帶上一個包含接收的那一行輸入的字符串。

 

rl.on('line', (input) => {
  console.log(`接收到:${input}`);
});

 即用戶按下了回車時就會觸發line事件,然后,我們就可以使用一個回調函數就收到輸入

 

 

 

'pause' 事件

當以下之一發生時觸發 'pause' 事件:

  • input 流被暫停。
  • input 流不是暫停的,且接收到 SIGCONT 事件。(詳見 SIGTSTP 事件和 SIGCONT 事件)

 

監聽器函數被調用時不傳入任何參數。

 

'resume' 事件

 

每當 input 流被恢復時觸發 'resume' 事件。

監聽器函數被調用時不傳入任何參數。

例子:

rl.on('resume', () => {
  console.log('Readline 被恢復。');
});

 

'SIGCONT' 事件

當一個 Node.js 進程使用 <ctrl>-Z(也就是 SIGTSTP)移入后台之后再使用 fg(1p) 移回前台時,觸發 'SIGCONT' 事件。

如果 input 流在 SIGTSTP 請求之前被暫停,則事件不會被觸發。

監聽器函數被調用時不傳入任何參數。

例子:

rl.on('SIGCONT', () => {
  // `prompt` 會自動恢復流
  rl.prompt();
});

 

rl.close()

rl.close() 方法會關閉 readline.Interface 實例,且撤回對 input 和 output 流的控制。 但被調用時,'close' 事件會被觸發。

 

rl.promp

rl.prompt() 方法會在 output 流中新的一行寫入 readline.Interface 實例配置后的 prompt,用於為用戶提供一個可供輸入的新的位置。

當被調用時,如果 input 流已被暫停,則 rl.prompt() 會恢復 input 流。

如果 readline.Interface 被創建時 output 被設為 null 或 undefined,則提示不會被寫入。

rl.pause()

rl.pause() 方法會暫停 input 流,且稍后需要時可被恢復。

調用 rl.pause() 不會立刻暫停其他事件(包括 'line')被 readline.Interface 實例觸發。

 

rl.question(query, callback)

 

  • query <string> 一個在提示符之前、要寫入 output 的敘述或詢問。
  • callback <Function> 一個回調函數,它會被調用並帶上用戶響應 query 的輸入。

rl.question() 方法通過寫入到 output 來展示 query,並等待用戶提供到 input 的輸入,然后調用 callback 函數並傳入提供的輸入作為第一個參數。

 

rl.question('你最喜歡的食物是什么? ', (answer) => {
console.log(`你最喜歡的食物是 ${answer}`);
});

 

 

rl.resume()

查看英文版 / 參與翻譯

如果 input 流已被暫停,則 rl.resume() 方法會恢復 input 流。

 

readline.createInterface(options)

 

  • input <Readable> 要監聽的可讀流。該選項是必需的。
  • output <Writable> 要寫入逐行讀取數據的可寫流

 

 

簡單的命令行界面

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: '請輸入> '
});

rl.prompt();

rl.on('line', (line) => {
  switch (line.trim()) {
    case 'hello':
      console.log('world!');
      break;
    default:
      console.log(`你輸入的是:'${line.trim()}'`);
      break;
  }
  rl.prompt();
}).on('close', () => {
  console.log('再見!');
  process.exit(0);
});

 

 

例子:逐行地讀取文件流

 

const readline = require('readline');
const fs = require('fs');

const rl = readline.createInterface({
  input: fs.createReadStream('sample.txt')
});

rl.on('line', (line) => {
  console.log(`文件的單行內容:${line}`);
});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM