0

I'm working on this problem on LeetCode:

https://leetcode.com/problems/read-n-characters-given-read4/

The question reads:

Given a file and assume that you can only read the file using a given method read4, implement a method to read n characters.

Method read4:

The API read4 reads 4 consecutive characters from the 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.

Definition of read4:

Parameter:  char[] buf4
Returns:    int

Note: buf4[] is destination not source, the results from read4 will be copied to buf4[]

...

Method read:

By using the read4 method, implement the method read that reads n characters from the file and store it in the buffer array buf. Consider that you cannot manipulate the file directly.

The return value is the number of actual characters read.

Definition of read:

Parameters:   char[] buf, int n
Returns:  int

Note: buf[] is destination not source, you will need to write the results to buf[]

I put together the following simple solution:

"""
The read4 API is already defined for you.

    @param buf4, a list of characters
    @return an integer
    def read4(buf4):

# Below is an example of how the read4 API can be called.
file = File("abcdefghijk") # File is "abcdefghijk", initially file pointer (fp) points to 'a'
buf4 = [' '] * 4 # Create buffer with enough space to store characters
read4(buf4) # read4 returns 4. Now buf = ['a','b','c','d'], fp points to 'e'
read4(buf4) # read4 returns 4. Now buf = ['e','f','g','h'], fp points to 'i'
read4(buf4) # read4 returns 3. Now buf = ['i','j','k',...], fp points to end of file
"""

class Solution:
    def read(self, buf, n):
        """
        :type buf: Destination buffer (List[str])
        :type n: Number of characters to read (int)
        :rtype: The number of actual characters read (int)
        """
        buf4 = ['']*4
        c = 1
        
        while n > 0 and c > 0:
            c = read4(buf4)
            if c:
                if n >= c:
                    buf += buf4
                elif n < c:
                    buf += buf4[:n]
            
            n -= c
        
        return len(buf)

When I use "+=" to add the contents of buf4 to buf I get a newline character in my output, as in the following example:

"
abc"

If I instead write buf = buf + buf4, I get just the newline character, like so:

"
"

Does anyone know what might be going on here? I know I could solve this problem by using for loops instead. I'm just curious to know what's going on.

I found this article that explains that "+=" and "c = c + b" use different special methods:

Why does += behave unexpectedly on lists?

However I don't think this explains the unexpected newline character. Does anyone know where this newline character is coming from?

spheroidic
  • 199
  • 7
  • Is there a difference in the length of the list for the two cases? – Andrew Morton Feb 02 '21 at 20:33
  • If by the "two cases" you're referring to the "+=" and "= +" approaches, then yes. They were both run using the same test case – spheroidic Feb 02 '21 at 21:26
  • Unclear where/how you are printing anything, but `repr(buf)` should show you newline characters, but using `+=` (or `.append()`) on a list doesn't add a newline character... If you are reading from a file, then files can have newlines, of course, – OneCricketeer Feb 03 '21 at 20:52
  • I'll try repr() to try and debug it, thanks. I don't think the test cases contain newlines based on the input they show on LC, but I could be wrong. – spheroidic Feb 03 '21 at 21:03

0 Answers0