Given a file and assume that you can only read the file using a given method read4
, implement a method read
to read n characters. Your method read
may be called multiple times.
Method read4:
The API read4
reads 4 consecutive characters from the file, then writes those characters into the buffer array buf
.
The return value is the number of actual characters read.
Note that read4()
has its own file pointer, much like FILE *fp
in C.
Definition of read4:
Parameter: char[] buf Returns: int Note: buf[] is destination not source, the results from read4 will be copied to buf[]
Below is a high level example of how read4
works:
File file("abcdefghijk"); // File is "abcdefghijk", initially file pointer (fp) points to 'a'
char[] buf = new char[4]; // Create buffer with enough space to store characters
read4(buf); // read4 returns 4. Now buf = "abcd", fp points to 'e'
read4(buf); // read4 returns 4. Now buf = "efgh", fp points to 'i'
read4(buf); // read4 returns 3. Now buf = "ijk", fp points to end of file
Method read:
By using the read4
method, implement the method read
that reads n characters from the file and store it in the buffer array buf
. Consider that you cannot manipulate the file directly.
The return value is the number of actual characters read.
Definition of read:
Parameters: char[] buf, int n Returns: int Note: buf[] is destination not source, you will need to write the results to buf[]
Example 1:
File file("abc"); Solution sol; // Assume buf is allocated and guaranteed to have enough space for storing all characters from the file. sol.read(buf, 1); // After calling your read method, buf should contain "a". We read a total of 1 character from the file, so return 1. sol.read(buf, 2); // Now buf should contain "bc". We read a total of 2 characters from the file, so return 2. sol.read(buf, 1); // We have reached the end of file, no more characters can be read. So return 0.
Example 2:
File file("abc"); Solution sol; sol.read(buf, 4); // After calling your read method, buf should contain "abc". We read a total of 3 characters from the file, so return 3. sol.read(buf, 1); // We have reached the end of file, no more characters can be read. So return 0.
Note:
- Consider that you cannot manipulate the file directly, the file is only accesible for
read4
but not forread
. - The
read
function may be called multiple times. - Please remember to RESET your class variables declared in Solution, as static/class variables are persisted across multiple test cases. Please see here for more details.
- You may assume the destination buffer array,
buf
, is guaranteed to have enough space for storing n characters. - It is guaranteed that in a given test case the same buffer
buf
is called byread
.
這道題是之前那道 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,參見代碼如下:
解法一:
// Forward declaration of the read4 API. int read4(char *buf); 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]; };
下面這種方法和上面的方法基本相同,稍稍改變了些解法,使得看起來更加簡潔一些:
解法二:
// Forward declaration of the read4 API. int read4(char *buf); 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; };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/158
類似題目:
參考資料:
https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/