[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; };
類似題目:
參考資料: