我有一个流类,它按升序排序。
class Stream {
boolean hasNext();
int peek();
int next();
}
我需要编写一个程序来合并多个流,并在不重复的流中打印出多次存在的元素而不重复。
这就是我用伪代码设计它的方法:
// print out numbers with occurance greater than (k).
void mergeStreams(List<Stream> streams, int k) {
int minCount = 0;
int min = Integer.MAX_VALUE;
List<Stream> minStreams;
loop through each stream and read in elements on head {
if (streams.size() < k) return;
if (!stream.hasNext()) {
streams.remove(stream); continue;
}
if (stream.peek() <= min) {
if (stream.peek() == min) {
minCount++;
}
else {
minStreams = new ArrayList<Stream>();
min = stream.peek();
minCount = 1;
}
minStreams.add(stream);
}
if last stream in streams {
if (minCount >= k) {
System.out.println(min);
for (Stream s : minStreams) {
if (s.hasNext()) s.next();
else streams.remove(s);
}
}
}
问题是我不知道如何精确地迭代流并一次读取元素,因此伪代码部分。另外,我不确定代码底部的streams.remove(s)
是否真正从原始Streams列表中删除了流s
,因为它已添加到新列表minStreams
中。我真的可以在这里使用一些建议。
答案 0 :(得分:1)
要在迭代列表中删除元素时,应使用Iterator.remove()。你还需要围绕整个事情进行while
循环来检查多个值。
void mergeStreams(List<Stream> streams, int k) {
while (streams.size() >= k) { // each loop checks one value (the current minimum)
int minCount = 0;
int min = Integer.MAX_VALUE;
List<Stream> minStreams = new ArrayList<>();
Iterator<Stream> streamIter = streams.iterator(); // supports remove during iteration
while (streamIter.hasNext()) {
Stream stream = streamIter.next();
if (!stream.hasNext()) {
streamIter.remove(); // remove stream from original list
continue;
}
if (stream.peek() <= min) {
if (stream.peek() == min) {
minCount++;
} else {
minStreams = new ArrayList<>();
min = stream.peek();
minCount = 1;
}
minStreams.add(stream);
}
}
if (minCount >= k) { // runs after iterating over streams
System.out.println(min);
}
for (Stream s : minStreams) { // must advance past the current min value
if (s.hasNext()) {
s.next();
} else {
streams.remove(s);
}
}
}
}
我还修正了一个错误,minStreams
中的流没有超过minCount < k
时的最小值,因此它会卡在该值上。