Sunday, January 11, 2015

LeetCode 158: Read N Characters Given Read4 II - Call multiple times

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.
/* The read4 API is defined in the parent class Reader4.
      int read4(char[] buf); */

public class Solution extends Reader4 {
    private Queue<Character> extra = new LinkedList<>();
    
    /**
     * @param buf Destination buffer
     * @param n   Maximum number of characters to read
     * @return    The number of characters read
     */
    public int read(char[] buf, int n) {
        // Note: file is not buf array.
        // The program needs to read file dat to buf array.
        // The question is an extension of "Read N Characters Given Read4".
        // However, we should build a Queue 'extra' for storing extra reading characters of 'read(...)'
        char[] buffer = new char[4];
        int readBytes = 0; // Number of total reading characters.
        boolean eof = false; // Flag if it has reached the end of the file.

        // Read extra characters of previous 'read'
        // Note: We should also verify if "readBytes < n" is ture here.
        while (!extra.isEmpty() && readBytes<n)
            buf[readBytes++] = extra.poll();
        
        while (!eof && readBytes<n)
        {
            int sz = read4(buffer);
            
            if (sz < 4)
                eof = true;
            
            // Store extra characters of 'read' function.
            if (sz > n-readBytes)
                for (int i = n-readBytes; i < sz; i++)
                    extra.offer(buffer[i]);
                
            int bytes = Math.min(n - readBytes, sz); 
            System.arraycopy(buffer /* src */, 0 /* srcPos */, buf /* dest */, readBytes /* destPos */, bytes /* length */);
            readBytes += bytes;
        }
        
        return readBytes;        
    }
}

No comments:

Post a Comment