Хранить только альтернативные минимальные и максимальные значения из потока в массив - PullRequest
0 голосов
/ 30 марта 2020

У меня есть поток десятичных значений, поступающих из непрерывного потока. Эти значения начинаются с определенного значения, повышаясь до некоторого максимального значения, а затем уменьшаются до некоторого минимального значения (вроде волны). Максимальные и минимальные значения go не всегда одинаковы, но гарантированная вещь состоит в том, что значения всегда go вверх, затем уменьшаются, затем снова go увеличиваются и уменьшаются и т. Д.

например, Поток значений может выглядеть следующим образом:

  0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.2,
 1.1, 1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0, 0.1,
 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.0, 0.9, 0.8, 0.7, 0.6, 0.5,
 0.4, 0.3, 0.2, 0.1, 0.0 ...

Требование, которое мне нужно, - хранить все чередующиеся самые низкие и самые высокие значения в массиве. Таким образом, в приведенном выше примере, массив окончательных результатов должен быть:

[0.3, 1.3, 0.0, 1.1, 0.0, ...]

Это псевдокод для алгоритма, который я пробовал:

var x;
var arr = [];
//listen to stream
//on stream event
void onEvent(double val) {
  if (x == null) {
    x = val;
  }

  if (val > x) {
    if (arr.lastItem < val) {
      arr.push(val);
    }
  } else {
    if (arr.lastItem > val) {
      arr.push(val);
    }
  }
  x=val;
}

Окончательный результат не равен ожидаемый результат. Какое решение лучше?

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Вы можете сделать что-то вроде этого:

const stream = [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.2,
  1.1, 1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0, 0.1,
  0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.0, 0.9, 0.8, 0.7, 0.6, 0.5,
  0.4, 0.3, 0.2, 0.1, 0.0
];

const output = [];
let prevValue = null;
let isGoingUp = false;

function onEvent(value) {
  if (output.length < 2) {
    output.push(value);
    if (output.length === 2) {
      isGoingUp = output[0] < output[1];
      prevValue = value;
    }
    return;
  }
  if (isGoingUp) {
    if (value > prevValue) {
      output[output.length - 1] = value;
    } else if (value < prevValue) {
      output.push(value);
      isGoingUp = false;
    }
  } else {
    if (value < prevValue) {
      output[output.length - 1] = value;
    } else if (value > prevValue) {
      output.push(value);
      isGoingUp = true;
    }
  }
  prevValue = value;
}

stream.forEach(onEvent);

console.log(output);

Это позволяет отслеживать, идет поток вверх или вниз (текущее значение больше или меньше предыдущего), и заменять последнее значение в выходных данных. массив, когда поток идет вниз, а текущее значение меньше, чем последнее значение на выходе, или поток идет вверх, а текущее значение больше.

0 голосов
/ 30 марта 2020

Надеюсь, это можно сделать гораздо проще, но это решение. Мы просто создаем время l oop, которое продолжается, пока есть доступные значения. Затем мы находим значения min и max и затем удаляем их из списка значений. Затем мы создаем новую пару минимальных и максимальных значений. Когда у нас есть все минимальные и максимальные значения, мы сопоставляем их с массивом двойных значений, как вам нужно.

    public static void main(String[] args) {
        List<Double> values = new ArrayList<>(Arrays.asList(
                0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.2,
                1.1, 1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0, 0.1,
                0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.0, 0.9, 0.8,
                0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0
        ));

        List<Pair> pairs = new ArrayList<>();

        while (!values.isEmpty()) {
            Double min = values.stream().min(Double::compareTo)
                    .orElseThrow(IllegalStateException::new);

            Double max = values.stream().max(Double::compareTo)
                    .orElseThrow(IllegalStateException::new);

            pairs.add(new Pair(min, max));

            values.remove(min);
            values.remove(max);
        }
        double[] valuesSorted = pairs.stream()
                .map(pair -> new double[] { pair.getMin(), pair.getMax() })
                .flatMapToDouble(Arrays::stream)
                .toArray();
    }

    static class Pair {

        private final double min;

        private final double max;

        Pair(double min, double max) {
            this.min = min;
            this.max = max;
        }

        public double getMin() {
            return min;
        }

        public double getMax() {
            return max;
        }

        @Override
        public String toString() {
            return "Pair{" +
                    "min=" + min +
                    ", max=" + max +
                    '}';
        }
    }

Вывод

[0.0, 1.3, 0.0, 1.2, 0.1, 1.2, 0.1, 1.1, 0.1, 1.1, 0.2, 1.1, 0.2, 1.0, 0.2, 1.0, 0.3, 1.0, 0.3, 1.0, 0.3, 0.9, 0.3, 0.9, 0.4, 0.9, 0.4, 0.9, 0.4, 0.8, 0.4, 0.8, 0.5, 0.8, 0.5, 0.8, 0.5, 0.7, 0.5, 0.7, 0.6, 0.7, 0.6, 0.7, 0.6, 0.6]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...