关于循环最后一步特殊处理的算法
这是个一般性的问题,算法思路很重要。
问题描述:
直接看下面的代码(以Java为例):
while ((p =in.readLine(buf, 0, len)) != -1) { isBreakStr = new String(buf, 0, p); if ( isBreakStr.indexof(breakStr)!=-1 ){ // 遇到分隔符则终止读取 break; } out.write(buf, 0, p); }
由于数据源的原因,在循环的最后一步时,读入的字符中有换行符。我想把这个换行符去掉,最简易的办法就是 在最后一步读取数据时,直接略过这个换行符。
所以在最后一次读取数据时,要进行特殊处理。
而上面的程序,最后一步是break。break的上一次循环,才是“最后一次数据的读取”!!
怎么获得break的上一次循环呢?因为我不知道循环要进行多少步,不知道什么时候break,所以我不知道何时才是“最后一次数据的读取”。
基本思路:延迟一步写入,循环一次不立即写入。
思路一:延迟一步写入,循环一次不立即写入。待下次循环时再判断是否为最后一次,如果是最后一次,再做特殊处理。
(思路一)实践总结:这种思路看似简单,实现起来相当麻烦,最后我还是没搞定。
思路二:延迟一步写入,循环一次不立即写入。弄一个队列(或者List)作为缓存容器,将原本写入流的地方,换成add到队列中。而循环时,延迟写入,只写入上一次的数据。
(思路二)实践总结:这种方法实现起来非常简洁,而且不但可以延迟一步,还可以延迟几步,能很好的满足我的需求。具体实现方法如下(以Java为例):
Queue<ByteBufferInfo> queue = new LinkedList<ByteBufferInfo>(); ByteBufferInfo tempbb = null; while ((p = in.readLine(buffer, 0, len)) != -1) { if(queue.size()>1){ tempbb = queue.poll(); //出队 out.write(tempbb.buffer, 0, tempbb.size); } isBreakStr = new String(buffer, 0, p); if( isBreakStr.indexof(breakStr)!=-1 ){ // 遇到分隔符则终止读取 break; } queue.offer( new ByteBufferInfo(buffer,p) ); //入队 } int qs = queue.size(); int tint = qs-1; for(int i=0; i<qs; i++){ tempbb = queue.poll(); if(i<tint) { outputStream.write(tempbb.buffer, 0, tempbb.size); }else{ outputStream.write(tempbb.buffer, 0, tempbb.size-2); } }