zoukankan      html  css  js  c++  java
  • [LeetCode] 158. 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.

    157. Read N Characters Given Read4 的拓展,之前只能调用一次,而这里可以调用多次,又多了一些corner case:

    第一次调用时,如果read4读出的多余字符我们要先将其暂存起来,这样第二次调用时先读取这些暂存的字符

    第二次调用时,如果连暂存字符都没读完,那么这些暂存字符还得留给第三次调用时使用

    所以,难点就在于怎么处理这个暂存字符。因为用数组和指针控制对第二种情况比较麻烦,且这些字符满足先进先出,所以我们可以用一个队列暂存这些字符。这样,只要队列不为空,就先读取队列。

    Java: Time: O(n), Space: O(1)

    public class Solution extends Reader4 {
        Queue<Character> remain = new LinkedList<Character>();
        
        public int read(char[] buf, int n) {
            int i = 0;
            // 队列不为空时,先读取队列中的暂存字符
            while(i < n && !remain.isEmpty()){
                buf[i] = remain.poll();
                i++;
            }
            for(; i < n; i += 4){
                char[] tmp = new char[4];
                int len = read4(tmp);
                // 如果读到字符多于我们需要的字符,需要暂存这些多余字符
                if(len > n - i){
                    System.arraycopy(tmp, 0, buf, i, n - i);
                    // 把多余的字符存入队列中
                    for(int j = n - i; j < len; j++){
                        remain.offer(tmp[j]);
                    }
                // 如果读到的字符少于我们需要的字符,直接拷贝
                } else {
                    System.arraycopy(tmp, 0, buf, i, len);
                }
                // 同样的,如果读不满4个,说明数据已经读完,返回总所需长度和目前已经读到的长度的较小的
                if(len < 4) return Math.min(i + len, n);
            }
            // 如果到这里,说明都是完美读取,直接返回n
            return n;
        }
    }
    

    Python:

    class Solution(object):
        def __init__(self):
            self.__buf4 = [''] * 4
            self.__i4 = 0
            self.__n4 = 0
    
        def read(self, buf, n):
            """
            :type buf: Destination buffer (List[str])
            :type n: Maximum number of characters to read (int)
            :rtype: The number of characters read (int)
            """
            i = 0
            while i < n:
                if self.__i4 < self.__n4:  # Any characters in buf4.
                    buf[i] = self.__buf4[self.__i4]
                    i += 1
                    self.__i4 += 1
                else:
                    self.__n4 = read4(self.__buf4)  # Read more characters.
                    if self.__n4:
                        self.__i4 = 0
                    else:  # Buffer has been empty.
                        break
    
            return i
    
    if __name__ == "__main__":
        global file_content
        sol = Solution()
        buf = ['' for _ in xrange(100)]
        file_content = "ab"
        print(buf[:sol.read(buf, 1)])
        print(buf[:sol.read(buf, 2)]) 

    Python:

    from Queue import Queue
    
    class Solution(object):
        def __init__(self):
            #self.curTotal = 0
            self.buffer = Queue()
            self.endOfFile = False
        def read(self, buf, n):
            """
            :type buf: Destination buffer (List[str])
            :type n: Maximum number of characters to read (int)
            :rtype: The number of characters read (int)
            """
            if n == 0:
                return 0
            
            total = 0
            while self.buffer.qsize() < n and not self.endOfFile:
                temp = [""] * 4
                r = read4(temp)
                if r < 4:
                    self.endOfFile = True
                for i in range(r):
                    self.buffer.put(temp[i])
                
            for i in range(min(self.buffer.qsize(), n)):
                buf[i] = self.buffer.get()
                total += 1
            
            return total
    

    C++:

    int read4(char *buf);
    
    class Solution {
    public:
        /**
         * @param buf Destination buffer
         * @param n   Maximum number of characters to read
         * @return    The number of characters read
         */
        int read(char *buf, int n) {
            if(n == 0)
                return 0;
                
            int total = 0;
            while(this->buffer.size() < n && !this->endOfFile) {
                char* temp = new char[4];
                int r = read4(temp);
                if(r < 4)
                    this->endOfFile = true;
                for(int i = 0; i < r; i++)
                    this->buffer.push(temp[i]);
            }
    
            int l = min((int)this->buffer.size(), n);
            for(int i = 0; i < l; i++) {
                buf[i] = this->buffer.front();
                this->buffer.pop();
                total++;
            }
            return total;
        }
        
    private:
        queue<char> buffer;
        bool endOfFile = false;
    };
    

      

       

    相关题目:

    [LeetCode] 157. Read N Characters Given Read4 用Read4来读取N个字符 

  • 相关阅读:
    用学习逃避成长,听新知缓解焦虑
    谈谈“人”和“技能”
    SpringMVC的工作原理
    Spring MVC 处理静态资源文件
    nrpe的安装设置
    Maatkit工具使用&lt;一&gt;之mysql主从数据校验工具
    phpcgi占用cpu100%的一次排障之旅
    nginx支持cgi
    如何查看服务器RAID卡信息的SHELL脚本和命令介绍
    Mysql的一次经典故障
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8481800.html
Copyright © 2011-2022 走看看