LeetCode 158 - Read N Characters Given Read4 II
喜刷刷: [LeetCode新题] Read N Characters Given Read4
https://discuss.leetcode.com/topic/18289/another-accepted-java-solution
http://yuanhsh.iteye.com/blog/2186425
Read full article from 喜刷刷: [LeetCode新题] Read N Characters Given Read4
喜刷刷: [LeetCode新题] Read N Characters Given Read4
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
由于每次只能读进4个字符,而n未必是4的倍数。所以一直读到len+4>n时停止。剩下m = n-len < 4 个字符。建立一个新的缓存remain读入4个字符,然后将其中的m个写入buff尾部。要注意在整个读入过程中的每个阶段判断是否已经读完文件。The
read
function will only be called once for each test case.https://discuss.leetcode.com/topic/18289/another-accepted-java-solution
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;
}
https://discuss.leetcode.com/topic/6400/accepted-clean-java-solutionhttp://yuanhsh.iteye.com/blog/2186425
每次只能读如4个字符,但是n不一定是n的整数倍。直接一个while循环,然后在里面判断读出来的buff长度是不是小于4。另外,文件的字符数可能少于n。所以需要有eof变量在循环体中做判断。
[注意事项]
1)最后一次读出来的buff长度有可能等于4,所以在while循环的判断条件中,需要加上 readBytes < n
1)最后一次读出来的buff长度有可能等于4,所以在while循环的判断条件中,需要加上 readBytes < n
- public int read(char[] buf, int n) {
- char[] buffer = new char[4];
- int readBytes = 0;
- boolean eof = false;
- while (!eof && readBytes < n) {
- int sz = read4(buffer);
- if (sz < 4) eof = true;
- int bytes = Math.min(n - readBytes, sz);
- System.arraycopy(buffer /*src*/, 0 /*srcPos*/, buf /*dest*/, readBytes /*destPos*/, bytes /*length*/);
- readBytes += bytes;
- }
- return readBytes;
- }
public int read(char[] buf, int n) { boolean eof = false; //end of file char[] temp = new char[4]; int total = 0; while(!eof && total < n){ int count = read4(temp); if(count < 4){ eof = true; } // get the actual count count = Math.min(count, n - total); for(int i = 0; i< count; i++){ buf[total++] = temp[i]; } } return total; }
public int read(char[] buf, int n) {
char[] buffer = new char[4];
int idx = 0;
while (true) {
int curr = read4(buffer);
int currLen = Math.min(curr, n - idx);
for (int i = 0; i < currLen; i++) {
buf[idx + i] = buffer[i];
}
idx += currLen;
if (currLen != 4 || idx == n) return idx;
}
}
int read(char *buf, int n) { int len = 0; int m = INT_MAX; while(len+4<=n) { m = read4(buf+len); len += m; if(m<4) break; } if(len==n || m<4) return len; char *remain = new char[5]; m = min(read4(remain),n-len); for(int i=0; i<m; i++) buf[len++] = remain[i]; delete remain; return len; }http://segmentfault.com/a/1190000003794420
- 如果本次读到多个字符,但是我们只需要其中一部分就能完成读取任务时,我们要拷贝的长度是本次读到的个数和剩余所需个数中较小的
- 如果read4没有读满4个,说明数据已经读完,这时候对于读到的数据长度,因为也可能存在我们只需要其中一部分的情况,所以要返回总所需长度和目前已经读到的长度的较小的
public int read(char[] buf, int n) {
for(int i = 0; i < n; i += 4){
char[] tmp = new char[4];
// 将数据读入临时数组
int len = read4(tmp);
// 将临时数组拷贝至buf数组,这里拷贝的长度是本次读到的个数和剩余所需个数中较小的
System.arraycopy(tmp, 0, buf, i, Math.min(len, n - i));
// 如果读不满4个,说明已经读完了,返回总所需长度和目前已经读到的长度的较小的
if(len < 4) return Math.min(i + len, n);
}
// 如果循环内没有返回,说明读取的字符是4的倍数
return n;
}
Related: [LeetCode] Read N Characters Given Read4 IIRead full article from 喜刷刷: [LeetCode新题] Read N Characters Given Read4