主要的注意点就是,有的时候 read4 是短板,有的时候 readN 自己是短板(不需要4个那么多的字符),在写入的时候要注意处理下。
Copy public int read( char [] buf , int n) {
// file has less than n chars
// n is not divisible by 4
boolean EOF = false ;
char [] temp = new char [ 4 ];
int curPtr = 0 ;
while (curPtr < n && ! EOF){
int charCount = read4(temp) ;
EOF = (charCount < 4 );
for ( int i = 0 ; i < charCount && curPtr < n; i ++ ){
buf[curPtr ++ ] = temp[i];
}
}
return curPtr;
}
多次调用之后,这题的难点就变成了 “如何处理剩余字符”。因为一次 call 拿到的字符很可能超过我们实际需要的,这时候就需要依赖外部 buffer 记录下来,每次新 read() call 的时候,先从缓存里拿。
Copy public class Solution extends Reader4 {
char [] leftOver = new char [ 4 ];
int leftCount = 0 ;
int leftPtr = 0 ;
/**
* @param buf Destination buffer
* @param n Maximum number of characters to read
* @return The number of characters read
*/
public int read ( char [] buf , int n) {
int totalLen = 0 ; // always points to next pos to be filled
boolean EOF = false ;
char [] temp = new char [ 4 ];
while ( ! EOF && totalLen < n){
while (leftCount > 0 && totalLen < n){
buf[totalLen ++ ] = leftOver[leftPtr ++ ];
leftCount -- ;
}
if (totalLen < n){
int newLen = read4(temp) ;
EOF = newLen < 4 ;
if (totalLen + newLen <= n){
// did not exceed
for ( int i = 0 ; i < newLen; i ++ ) buf[totalLen ++ ] = temp[i];
} else {
// points to next extra char
int ptr = 0 ;
// write needed char into buffer
while (totalLen < n) buf[totalLen ++ ] = temp[ptr ++ ];
// write extra char into leftover
int size = newLen - ptr;
for ( int i = 0 ; i < size; i ++ ){
leftOver[i] = temp[ptr ++ ];
leftCount = i + 1 ;
}
leftPtr = 0 ;
}
}
}
return totalLen;
}
}
这个写法就巧妙简洁多了,而且原封不动就可以做原来的问题,非常巧妙。
Copy public class Solution extends Reader4 {
/**
* @param buf Destination buffer
* @param n Maximum number of characters to read
* @return The number of characters read
*/
char [] temp = new char [ 4 ];
int bufPtr = 0 ;
int bufCount = 0 ;
int bufEnd = 0 ;
public int read ( char [] buf , int n) {
int curPtr = 0 ;
while (curPtr < n){
if (bufCount == 0 ){
bufCount = read4(temp) ;
bufEnd = bufCount;
bufPtr = 0 ;
}
if (bufCount == 0 ) break ;
while (bufPtr < bufEnd && curPtr < n){
buf[curPtr ++ ] = temp[bufPtr ++ ];
bufCount -- ;
}
}
return curPtr;
}
}