1. 程式人生 > >[LeetCode] Read N Characters Given Read4 II

[LeetCode] Read N Characters Given Read4 II

The API: int read4(char *buf) reads 4 characters at a time from a file.

The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file.

By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file.

Note:
The read function may be called multiple times.

這道題是之前那道Read N Characters Given Read4的拓展,那道題說read函式只能呼叫一次,而這道題說read函式可以呼叫多次,那麼難度就增加了,為了更簡單直觀的說明問題,我們舉個簡單的例子吧,比如:

buf = "ab", [read(1),read(2)],返回 ["a","b"]

那麼第一次呼叫read(1)後,從buf中讀出一個字元,那麼就是第一個字元a,然後又呼叫了一個read(2),想取出兩個字元,但是buf中只剩一個b了,所以就把取出的結果就是b。再來看一個例子:

buf = "a", [read(0),read(1),read(2)],返回 ["","a",""]

第一次呼叫read(0),不取任何字元,返回空,第二次呼叫read(1),取一個字元,buf中只有一個字元,取出為a,然後再呼叫read(2),想取出兩個字元,但是buf中沒有字元了,所以取出為空。

但是這道題我不太懂的地方是明明函式返回的是int型別啊,為啥OJ的output都是vector<char>類的,然後我就在網上找了下面兩種能通過OJ的解法,大概看了看,也是看的個一知半解,貌似是用兩個變數readPos和writePos來記錄讀取和寫的位置,i從0到n開始迴圈,如果此時讀和寫的位置相同,那麼我們呼叫read4函式,將結果賦給writePos,把readPos置零,如果writePos為零的話,說明buf中沒有東西了,返回當前的座標i。然後我們用內建的buff變數的readPos位置覆蓋輸入字串buf的i位置,如果完成遍歷,返回n,參見程式碼如下:

解法一:

class Solution {
public:
    int read(char *buf, int n) {
        for (int i = 0; i < n; ++i) {
            if (readPos == writePos) {
                writePos = read4(buff);
                readPos = 0;
                if (writePos == 0) return i;
            }
            buf[i] = buff[readPos++];
        }
        return n;
    }
private:
    int readPos = 0, writePos = 0;
    char buff[4];
};

下面這種方法和上面的方法基本相同,稍稍改變了些解法,使得看起來更加簡潔一些:

解法二:

class Solution {
public:
    int read(char *buf, int n) {
        int i = 0;
        while (i < n && (readPos < writePos || (readPos = 0) < (writePos = read4(buff))))
            buf[i++] = buff[readPos++];
        return i;
    }
    char buff[4];
    int readPos = 0, writePos = 0;
};

類似題目:

參考資料: