如何迭代一堆流并一次读取一个元素?

时间:2017-07-11 16:30:57

标签: java sorting iterator

我有一个流类,它按升序排序。

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中。我真的可以在这里使用一些建议。

1 个答案:

答案 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时的最小值,因此它会卡在该值上。