📜  连续数字流的中位数–(使用Set)

📅  最后修改于: 2021-04-28 18:39:05             🧑  作者: Mango

假定正在从数据流中读取整数。查找从第一个整数到最后一个整数到目前为止已读取的所有元素的中值。这也称为运行整数中位数。
给定的链接已经包含使用优先级队列解决此问题的方法。
但是,以下解决方案使用相同的概念,但是实现是通过使用集来实现的。
在此解决方案中,我们将在长度均匀的情况下打印较小的中位数,而不是取其平均值。

例子:

方法:

  • 按升序创建两个多集g ,将存储上半部分,按降序存储s ,以存储数组arr []的下半部分。
  • 将第一个元素插入s中。并用该值初始化中位数。
  • 对于数组x的每个其他元素。检查两个集合的大小:
    • size(s)> size(g)时:如果x>中位数,则将s的第一个元素插入g从s中删除该元素,然后将x插入s 。否则将x插入g
    • size(s):如果x <中位数,则将g的第一个元素插入s从g中删除该元素,然后将x插入g 。否则将x插入s
    • size(s)= size(g)时:如果x>中位数。将x插入s 。否则将x插入g

下面是上述方法的实现:

// C++ program to find running median for 
// a stream of integers using Set
#include 
using namespace std;
  
// Function to print the running median 
// for the array arr[]
void printRunningMedian(int arr[], int n)
{
    // Multiset is used to handle duplicates
    // Multiset g for storing upper half 
    // (ascending order)
    // The first element will be the smallest)
    multiset g;
  
    // Multiset s for storing lower half 
    // (descending order). The first element 
    // will be the largest
    multiset > s;
  
    s.insert(arr[0]);
  
    // Initialise median with the first element
    int med = arr[0];
    printf("%d ", med);
  
    for (int i = 1; i < n; i++) {
  
        // Only add elements to upper half if 
        // its size less then the size of the
        // lower half (maintain only difference
        // of 1)
        if (s.size() > g.size()) {
            if (arr[i] < med) {
                int temp = *s.begin();
                s.erase(s.begin());
                g.insert(temp);
                s.insert(arr[i]);
            }
            else
                g.insert(arr[i]);
  
            med = *s.begin() > *g.begin() ?
                   *g.begin() : *s.begin();
        }
  
        // Only add elements to lower half if 
        // it's size less then the size of the 
        // upper half (maintain only difference
        // of 1)
        else if (s.size() < g.size()) {
            if (arr[i] > med) {
                int temp = *g.begin();
                g.erase(g.begin());
                s.insert(temp);
                g.insert(arr[i]);
            }
            else
                s.insert(arr[i]);
  
            med = *s.begin() > *g.begin() ? 
                   *g.begin() : *s.begin();
        }
  
        // If sizes are same
        else {
            if (arr[i] > med) {
                g.insert(arr[i]);
                med = *g.begin();
            }
            else {
                s.insert(arr[i]);
                med = *s.begin();
            }
        }
  
        printf("%d ", med);
    }
  
    printf("\n");
}
  
// Driver code
int main()
{
    int arr[] = { -10, 14, 11, -5, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printRunningMedian(arr, n);
    return 0;
}
输出:
-10 -10 11 -5 7