1
+ /**
2
+ * The read4 API is defined in the parent class Reader4.
3
+ * int read4(char[] buf4);
4
+ */
5
+ /**
6
+ * Problem: Leetcode 158
7
+ */
8
+ public class Solution extends Reader4 {
9
+
10
+ char [] buffer = new char [16 ];
11
+ int writePtr = 0 ;
12
+ int readPtr = 0 ;
13
+
14
+ /**
15
+ * @param buf Destination buffer
16
+ * @param n Number of characters to read
17
+ * @return The number of actual characters read
18
+ */
19
+ public int read (char [] buf , int n ) {
20
+ if (writePtr - readPtr >= n ) {
21
+ // All data is already available in the buffer, read and return
22
+ this .copyRange (buffer , readPtr , n + readPtr , buf , 0 );
23
+ this .readPtr += n ;
24
+ return n ;
25
+ } else {
26
+ // Not enough items are available, try to get more items into the internal buffer.
27
+ this .readInternal (n - (writePtr - readPtr ));
28
+ if (writePtr - readPtr >= n ) {
29
+ // All the n items can be fetched and updated.
30
+ this .copyRange (buffer , readPtr , n + readPtr , buf , 0 );
31
+ this .readPtr += n ;
32
+ return n ;
33
+ } else {
34
+ this .copyRange (buffer , readPtr , writePtr , buf , 0 );
35
+ int itemsRead = writePtr - readPtr ;
36
+ this .readPtr = writePtr ;
37
+ return itemsRead ;
38
+ }
39
+ }
40
+ }
41
+
42
+ private void readInternal (int n ) {
43
+ int readItems = n % 4 == 0 ? n : (n /4 + 1 ) * 4 ;
44
+
45
+ if (this .buffer .length < this .writePtr + readItems ) {
46
+ this .expandInternalBuffer (this .writePtr + readItems );
47
+ }
48
+
49
+ while (readItems > 0 ) {
50
+ char [] buff4 = new char [4 ];
51
+ int newItems = this .read4 (buff4 );
52
+ if (newItems == 0 ) break ;
53
+ this .copyRange (buff4 , 0 , newItems , this .buffer , this .writePtr );
54
+ this .writePtr += newItems ;
55
+ readItems -= newItems ;
56
+ }
57
+ }
58
+
59
+ private void expandInternalBuffer (int length ) {
60
+ int newLength = (length / 16 + 1 ) * 16 ;
61
+ char [] newBuffer = new char [newLength ];
62
+ this .copyRange (buffer , 0 , this .writePtr , newBuffer , 0 );
63
+ this .buffer = newBuffer ;
64
+ }
65
+
66
+ // Copy the items from the input buffer to the output buffer.
67
+ private void copyRange (char [] source ,
68
+ int sourceBeg ,
69
+ int sourceEnd ,
70
+ char [] target ,
71
+ int targetBeg ) {
72
+ // for (int idx = sourceBeg; idx < sourceEnd; idx++) {
73
+ // target[targetBeg++] = source[idx];
74
+ // }
75
+ System .arraycopy (source , sourceBeg , target , targetBeg , sourceEnd - sourceBeg );
76
+ }
77
+ }
0 commit comments