一道关于Iterator的面试题
2015-06-01 20:34
531 查看
这是一道Google电面题:
实现一个InterleavingIterator的class,其输入是Iterator<Iterator<T>>,包含hasNext()和Next()两个方法,要求是调用next()时能够交替输出输入的数据,比如:
假设输入是:
a1, a2, a3, a4, ..., an;
b1, b2, b3, b4, ..., bm;
c1, c2, c3, c4, ..., co;
通过调用next()使输出结果为:
a1, b1, c1, a2, b2, c2, ......
所以class的结构是这样的:
class InterleavingIterator<T>{
public InterleavingIterator(Iterator<Iterator<T>> iit){
}
public boolean hasNext(){
}
public T next(){
}
}
拿到这个题目的第一反应是,输入是多行数据,输出是要实现逐列输出,那能否直接从Iterator<Iterator<T>>中逐列读取呢,没有什么思路,后来想到先把每一行的Iterator读出来放到一个iterator的buffer里,然后每次输出一行最前面的元素,接下来的问题就是使用什么样的数据结构来作为这个iterator的buffer,最初的想法是用ArrayList,如果使用ArrayList需要记录行的index,显然不是最优解,所以就想到可以用Queue,每输出一行数据的首个元素之后,如果这一行还有数据没有输出,则将该行的Iterator放入队尾;所以用来实现这个Iterator的java代码如下:
class InterleavingIterator<T>{
private Queue<T> lineBuffer = null;
private T buffer = null;
//将输入数据逐行读入到lineBuffer中;
private void initLineBuffer(Iterator<Iterator<T>> iit){
if(iit == null){
return;
}
while(iit.hasNext()){
Iterator<T> line = iit.next();
if(line != null){
lineBuffer.offer(line);
}
}
}
public InterleavingIterator(Iterator<Iterator<T>> iit){
lineBuffer = new LinkedList<Iterator<T>>();
initLineBuffer(iit);
}
public boolean hasNext(){
if(buffer != null){
return true;
}
boolean stop = false;
while((lineBuffer.peek() != null)&&(!stop)){
Iterator<T> line = lineBuffer.poll();
if(line.hasNext()){
buffer = line.next();
stop = true;
}
if(stop){
if(line.hasNext()){
lineBuffer.offer(line);
}
}
}
return stop;
}
public T next(){
T ret = null;
if(buffer == null){
if(hasNext()){
ret = buffer;
}
}
ret = buffer;
buffer = null;
return ret;
}
}
验证代码的正确性时需要考虑:
1.调用hasNext()然后调用next()来遍历所有的元素;
除此之外,还需要考虑一些可能出错的情况,比如:
1.用户反复调用hasNext();
2.直接反复调用next();
3.输入数据中有的行为空;
实现一个InterleavingIterator的class,其输入是Iterator<Iterator<T>>,包含hasNext()和Next()两个方法,要求是调用next()时能够交替输出输入的数据,比如:
假设输入是:
a1, a2, a3, a4, ..., an;
b1, b2, b3, b4, ..., bm;
c1, c2, c3, c4, ..., co;
通过调用next()使输出结果为:
a1, b1, c1, a2, b2, c2, ......
所以class的结构是这样的:
class InterleavingIterator<T>{
public InterleavingIterator(Iterator<Iterator<T>> iit){
}
public boolean hasNext(){
}
public T next(){
}
}
拿到这个题目的第一反应是,输入是多行数据,输出是要实现逐列输出,那能否直接从Iterator<Iterator<T>>中逐列读取呢,没有什么思路,后来想到先把每一行的Iterator读出来放到一个iterator的buffer里,然后每次输出一行最前面的元素,接下来的问题就是使用什么样的数据结构来作为这个iterator的buffer,最初的想法是用ArrayList,如果使用ArrayList需要记录行的index,显然不是最优解,所以就想到可以用Queue,每输出一行数据的首个元素之后,如果这一行还有数据没有输出,则将该行的Iterator放入队尾;所以用来实现这个Iterator的java代码如下:
class InterleavingIterator<T>{
private Queue<T> lineBuffer = null;
private T buffer = null;
//将输入数据逐行读入到lineBuffer中;
private void initLineBuffer(Iterator<Iterator<T>> iit){
if(iit == null){
return;
}
while(iit.hasNext()){
Iterator<T> line = iit.next();
if(line != null){
lineBuffer.offer(line);
}
}
}
public InterleavingIterator(Iterator<Iterator<T>> iit){
lineBuffer = new LinkedList<Iterator<T>>();
initLineBuffer(iit);
}
public boolean hasNext(){
if(buffer != null){
return true;
}
boolean stop = false;
while((lineBuffer.peek() != null)&&(!stop)){
Iterator<T> line = lineBuffer.poll();
if(line.hasNext()){
buffer = line.next();
stop = true;
}
if(stop){
if(line.hasNext()){
lineBuffer.offer(line);
}
}
}
return stop;
}
public T next(){
T ret = null;
if(buffer == null){
if(hasNext()){
ret = buffer;
}
}
ret = buffer;
buffer = null;
return ret;
}
}
验证代码的正确性时需要考虑:
1.调用hasNext()然后调用next()来遍历所有的元素;
除此之外,还需要考虑一些可能出错的情况,比如:
1.用户反复调用hasNext();
2.直接反复调用next();
3.输入数据中有的行为空;
相关文章推荐
- 面试题30:最小的K个数
- 面试题29:数组中出现次数超过一半的数字
- 黑马程序员——java基础----集合框架知识点总结(一)
- 黑马程序员_java语言_StringBuffer,Array以及Integer分析
- java求职宝典
- 黑马程序员--Java基础Day01
- 黑马程序员——银行业务调度系统
- 黑马程序员——交通灯管理系统
- 黑马程序员——反射
- 黑马程序员——IO流(三)
- 《经验分享收集》 一:10+年程序员总结的20+条经验教训
- Java面试题-并发工具
- Java面试题-Java中的锁
- Java面试题-并发容器和框架
- Java面试题-线程安全
- Java面试题-并发框架
- Java面试题-锁
- Java面试题-多线程
- 面试题28:求字符的全排列
- 面试题27:二叉搜索树转换为有序双向链表