zoukankan      html  css  js  c++  java
  • 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.
    
    Show Tags
    Have you met this question in a real interview?

    这道题跟I不一样在于,read函数可能多次调用,比如read(buf,23)之后又read(buf, 25), 第一次调用时的buffer还没用完,还剩一个char在buffer里,第二次拿出来接着用,这样才能保证接着上次读的地方继续往下读。

    1. 所以应该设置这4个char的buffer为instance variable(实例变量),这样每次调用read函数后buffer还剩的元素可以被保存下来,供给下一次读取

    2. 那么下一次调用read函数时候,怎么知道上一次buffer里面还剩不剩未读元素呢?我们有oneRead(一次读到buffer里的char数),actRead(实际被读取的char数),oneRead-actRead就是还剩在buffer里的char数。通常oneRead == actRead, 只有当n-haveRead < oneRead时,才不等,这就是上一次调用read结束的时候。所以只要调用read函数发现oneRead != 0 时,就说明上一次调用read还剩了元素在buffer里,先读完这个,再调用read4读新的。oneRead也需要是instance varaible

    3. 还需要设置一个offset: Use to keep track of the offset index where the data begins in the nextread call. The buffer could be read partially (due to constraints of reading upto n bytes) and therefore leaving some data behind.

                          |<--buffer-->|   
        // |_________________________|
        // |<---offset---> |<----oneRead--->

    上图所示为一次read最后的情况,offset部分其实就是actRead的部分,oneRead = oneRead - actRead, 就剩下了右边一部分在buffer里没有读,下一次read函数调用,发现oneRead>0, 说明上一次read还剩了一部分没有读。oneRead表示的其实就是上一次读剩下的char数,offset表示这一次读应该开始的位置

    其实上图的oneRead不一定会充满整个右边部分的,有可能上一次读oneRead根本没有读满整个buffer。 所以oneRead+offset并不一定等于整个buffer。这也就是为什么我们一定要用两个变量oneReadoffset的原因,因为oneRead并不一定=4-offset

     1 /* The read4 API is defined in the parent class Reader4.
     2       int read4(char[] buf); */
     3 
     4 public class Solution extends Reader4 {
     5     /**
     6      * @param buf Destination buffer
     7      * @param n   Maximum number of characters to read
     8      * @return    The number of characters read
     9      */
    10      private char buffer = new char[4];
    11      private int oneRead = 0;
    12      private int offset = 0;
    13      
    14      public int read(char[] buf, int n) {
    15          boolean lessthan4 = false;
    16          int haveRead = 0;
    17          while (!lessthan4 && haveRead < n) {
    18              if (oneRead == 0) {
    19                  oneRead = read4(buffer);
    20                  lessthan4 = oneRead < 4;
    21              }
    22              int actRead = Math.min(n-haveRead, oneRead);
    23              for (int i=0; i<actRead; i++) {
    24                  buf[haveRead+i] = buffer[offset+i];
    25              }
    26              oneRead -= actRead;
    27              offset = (offset + actRead) % 4;
    28              haveRead += actRead;
    29          }
    30          return haveRead;
    31      }
    32 }
  • 相关阅读:
    ORACLE PL/SQL 实例精解之第七章 迭代控制之二
    ORACLE PL/SQL 实例精解之第六章 迭代控制之一
    ORACLE PL/SQL 实例精解之第五章 条件控制:CASE语句
    ORACLE PL/SQL 实例精解之第四章 条件控制:if 语句
    sql中用JOIN USING 简化JOIN ON
    ORACLE PL/SQL 实例精解之第三章 PL/SQL中的SQL
    ORACLE PL/SQL 实例精解之第二章 通用编程语言基础
    删除文件时提示“找不到该项目”,怎么解决? 转摘自:http://jingyan.baidu.com/article/e4d08ffdf5ab470fd2f60df4.html
    C#获取文件夹/文件的大小以及占用空间 转摘自:http://www.cnblogs.com/chenpeng-dota/articles/2176470.html
    git update-index --assume-unchanged on directory 转摘自:http://stackoverflow.com/questions/12288212/git-update-index-assume-unchanged-on-directory
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/4240616.html
Copyright © 2011-2022 走看看