关于循环最后一步特殊处理的算法
2013年10月24日


这是个一般性的问题,算法思路很重要。


问题描述:

直接看下面的代码(以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);
}

 

由于数据源的原因,在循环的最后一步时,读入的字符中有换行符。我想把这个换行符去掉最简易的办法就是 在最后一步读取数据时,直接略过这个换行符

 

所以在最后一次读取数据时,要进行特殊处理

 

而上面的程序,最后一步是breakbreak的上一次循环,才是“最后一次数据的读取”!!

怎么获得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);
	}
}