Another accepted Java solution


  • 76
    public int read(char[] buf, int n) {
      boolean eof = false;      // end of file flag
      int total = 0;            // total bytes have read
      char[] tmp = new char[4]; // temp buffer
      
      while (!eof && total < n) {
        int count = read4(tmp);
        
        // check if it's the end of the file
        eof = count < 4;
        
        // get the actual count
        count = Math.min(count, n - total);
        
        // copy from temp buffer to buf
        for (int i = 0; i < count; i++) 
          buf[total++] = tmp[i];
      }
      
      return total;
    }

  • 1
    T

    I like your solution. Clean and simple.


  • 3
    S

    I know that this is what is accepted by the OJ. But total being always equal or less than n I think is misleading because if the read4 reads from a file, the file pointer could have moved by more than n bytes.


  • 2
    P

    Boolean eof is unecessary. Here is a short AC C++ code:

        int read(char *buf, int n) {
            char buf4[4];
            int nRead = 0, pos = 0;
            while (((nRead = read4(buf4)) > 0) && (pos < n)) { //can read && can write
                for (int i = 0; i < nRead && pos < n; i++) //can write
                    buf[pos++] = buf4[i];
            }
            return pos;
        }
    

  • 6

    Found this short and elegant solution here: https://segmentfault.com/a/1190000003794420. Because I don't have premium account, I'm not sure if it's AC. Just for your reference.

        // Note two edge cases:
        //  1) len + i > N which means we read more than N
        //  2) len + i < N and no more chars
        public int read(char[] buf, int n) {
            for (int i = 0; i < n; i += 4) {
                char[] tmp = new char[4];
                int len = read4(tmp);
                System.arraycopy(tmp, 0, buf, i, Math.min(len, n - i));
                if (len < 4) return Math.min(i + len, n);
            }
            return n; /* i >= n */
        }
    

  • 1

    @cdai Thanks for sharing. It works. There is one place that I think could be better:

    In the code below,

    System.arraycopy(tmp, 0, buf, i, Math.min(len, n - i));
    

    can use len only, because the min is always equal to len.

    System.arraycopy(tmp, 0, buf, i, len);
    
    

  • 1
    S

    @zhugejunwei I'm not sure that's correct. Let's take this case:

    n = 10 //Num chars we want read
    File Size = 12 //Num chars in file we're reading from

    We run through the first two iterations so i = 8. Now, we read in the next 4 chars from the file (because there are 4 remaining [12 - 8]) which leaves us with a len == 4. Notice that n - i == 2.

    When copying, if we just checked len to decide where to finish copying, we'd have placed all 12 chars in our return buffer when only 10 were requested. This is because we'd transfer the entire length (len) of our temporary buffer into our destination buffer.

    However, if we keep the check for n - i, we can see that it would give us 10 - 8 ==> 2 (less than len == 4), so we'd only be placing the final 2 chars giving us a total of 10 chars in our destination buffer.


  • 0

    @SIRHAMY Well, my solution passed all the test cases.


  • 0
    B

    what if buf is smaller than n?


  • 0
    C

    I want to know if the size of buf is fixed or not at beginning?


  • 1
    E

    Thanks for the solution, I do have a question about the code:
    why do we need to do "count = Math.min(count, n - total);" to get the actually number of character that is read? I thought by calling read4 the method will return the actual number of characters that are read even if it's less than 4?


  • 0
    C

    @Enkri_ Hey I just got the same question as yours. I think probably because the length of the file could more than n, so every time you need to make sure that you didn't add more data into your char[].


  • 0
    S

    @zhugejunwei said in Another accepted Java solution:

    ere is one place that I think could be better:

    Yes.. it works !!


  • 0
    A

    @cdai Hi, why do we take Math.min (len, n-i)?


  • 0
    X

    @sculd

    Agree with you. But are we thinking correctly? Have you discussed with others about it?


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.