Problem
Problem ID: 158
Title: Read N Characters Given read4 II - Call Multiple Times
Difficulty: Hard
Description:
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 four consecutive characters from file, then writes those characters into the buffer array buf4.
The return value is the number of actual characters read.
Note that read4() has its own file pointer, much like FILE *fp in C.
Thoughts
I found this question quite interesting but I think Leetcode could have written a better problem description as it seems much more complicated than what it actually is. I strongly advise attempting Read N Characters Given Read4 first.
Solution
**Challenge:
read4will always read 4 characters. This could result in separate calls toreadsharing the same chunk of characters fromread4(ie read(buf, 2) then read(buf,2))
General Idea: Instead of writing to read’s buffer directly, we will store the results from read4 into a
separate buffer. This would let us to easily share the same chunk of characters from read4.
State:
read_buf: An array of 4 characters. Act as a buffer to store the result for all calls toread4.size: Asread4could read less than 4 characters at the end of the file. We will need to store the number of characters that are inread_bufptr: Pointer to the next character in the buffer. This would let us to keep track of the current character inread_buf
Solution
- While the return buffer size is less than
n- If
ptrsize equals to size ofread_buf, signifies than we have reached the end of the buffer. Callread4and reset the valueptrandsize - Break from while loop if
size == 0(reached the end of file). - Copy over the character from
read_bufinto the returnbufand incrementptr
- If
Implementation
/**
* The read4 API is defined in the parent class Reader4.
* int read4(char *buf4);
*/
class Solution {
private:
char read_buf[4];
bool read_empty;
int size;
int ptr;
public:
Solution() : read_empty(false), size(0), ptr(0) {}
/**
* @param buf Destination buffer
* @param n Number of characters to read
* @return The number of actual characters read
*/
void refresh_buf() {
size = read4(read_buf);
ptr = 0;
if (size == 0) read_empty = true;
}
int read(char *buf, int n) {
int buf_size = 0;
for (;buf_size < n; buf_size++) {
if (ptr == size) {
refresh_buf();
}
if (read_empty) break;
if (ptr < size) {
buf[buf_size] = read_buf[ptr];
ptr++;
}
}
return buf_size;
}
};