Computer >> Máy Tính >  >> Lập trình >> C ++

Trung bình của dòng số chạy trong C ++

Trong bài toán này, chúng ta được cung cấp một luồng dữ liệu liên tục đọc các số nguyên. Nhiệm vụ của chúng tôi là tạo một chương trình sẽ đọc các phần tử và tính toán các giá trị trung bình cho các phần tử này.

Trung vị của một mảng là phần tử giữa của một chuỗi đã được sắp xếp (nó có thể tăng dần hoặc giảm dần).

Tính giá trị trung bình

Đối với số lẻ, trung vị là phần tử ở giữa

Đối với số chẵn, giá trị trung bình là giá trị trung bình của hai phần tử ở giữa

Hãy lấy một ví dụ để hiểu vấn đề,

Đầu vào - 3, 65, 12, 20, 1

Ở mỗi đầu vào,

Input - 3 : sequence -(3) : median - 3
Input - 65 : sequence -(3, 65) : median - 34
Input - 12 : sequence -(3, 12, 65) : median - 12
Input - 20 : sequence -(3, 12, 20, 65) : median - 16
Input - 1 : sequence -(1, 3, 12, 20, 65) : median - 12

Chúng tôi đã sử dụng trình tự được sắp xếp ở đây để giúp việc tính toán trung bình trở nên dễ dàng.

Để giải quyết vấn đề này, chúng tôi có nhiều giải pháp sử dụng sắp xếp ở mỗi bước và sau đó tìm giá trị trung bình, tạo BST tự cân bằng hoặc sử dụng đống. Heap dường như là giải pháp hứa hẹn nhất để tìm ra trung tuyến. Cả max-heap hoặc min-heap đều có thể cung cấp cho chúng tôi giá trị trung bình ở mỗi lần chèn và cũng là một giải pháp hiệu quả.

Ví dụ

Chương trình cho thấy việc triển khai giải pháp của chúng tôi,

#include <iostream>
using namespace std;
#define MAX_HEAP_SIZE (128)
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
void swap(int &a, int &b){
   int temp = a;
   a = b;
   b = temp;
}
bool Greater(int a, int b){
   return a > b;
}
bool Smaller(int a, int b){
   return a < b;
}
int Signum(int a, int b){
   if( a == b )
      return 0;
   return a < b ? -1 : 1;
}
class Heap{
   public:
      Heap(int *b, bool (*c)(int, int)) : A(b), comp(c)
      { heapSize = -1; }
      virtual bool Insert(int e) = 0;
      virtual int GetTop() = 0;
      virtual int ExtractTop() = 0;
      virtual int GetCount() = 0;
      protected:
      int left(int i) {
         return 2 * i + 1;
      }
      int right(int i) {
         return 2 * (i + 1);
      }
      int parent(int i) {
         if( i <= 0 ){
            return -1;
         }
         return (i - 1)/2;
      }
      int *A;
      bool (*comp)(int, int);
      int heapSize;
      int top(void){
         int max = -1;
         if( heapSize >= 0 )
            max = A[0];
         return max;
      }
      int count() {
         return heapSize + 1;
      }
      void heapify(int i){
         int p = parent(i);
         if( p >= 0 && comp(A[i], A[p]) ) {
            swap(A[i], A[p]);
            heapify(p);
         }
      }
      int deleteTop(){
         int del = -1;
         if( heapSize > -1){
            del = A[0];
            swap(A[0], A[heapSize]);
            heapSize--;
            heapify(parent(heapSize+1));
         }
         return del;
      }
      bool insertHelper(int key){
         bool ret = false;
         if( heapSize < MAX_HEAP_SIZE ){
            ret = true;
            heapSize++;
            A[heapSize] = key;
            heapify(heapSize);
         }
         return ret;
      }
};
class MaxHeap : public Heap {
   private:
   public:
      MaxHeap() : Heap(new int[MAX_HEAP_SIZE], &Greater) { }
      int GetTop() {
         return top();
      }
      int ExtractTop() {
         return deleteTop();
      }
      int GetCount() {
         return count();
      }
      bool Insert(int key) {
         return insertHelper(key);
      }
};
class MinHeap : public Heap{
   private:
   public:
      MinHeap() : Heap(new int[MAX_HEAP_SIZE], &Smaller) { }
      int GetTop() {
         return top();
      }
      int ExtractTop() {
         return deleteTop();
      }
      int GetCount() {
         return count();
      }
      bool Insert(int key) {
         return insertHelper(key);
      }
};
int findMedian(int e, int &median, Heap &left, Heap &right){
   switch(Signum(left.GetCount(), right.GetCount())){
      case 0: if( e < median ) {
         left.Insert(e);
         median = left.GetTop();
      }
      else{
         right.Insert(e);
         median = right.GetTop();
      }
      break;
      case 1: if( e < median ){
         right.Insert(left.ExtractTop());
         left.Insert(e);
      }
      else
         right.Insert(e);
         median = ((left.GetTop()+right.GetTop())/2);
      break;
      case -1: if( e < median )
         left.Insert(e);
      else {
         left.Insert(right.ExtractTop());
         right.Insert(e);
      }
      median = ((left.GetTop()+right.GetTop())/2);
      break;
   }
   return median;
}
void printMedianStream(int A[], int size){
   int median = 0;
   Heap *left = new MaxHeap();
   Heap *right = new MinHeap();
   for(int i = 0; i < size; i++) {
      median = findMedian(A[i], median, *left, *right);
      cout<<"Median of elements : ";
      for(int j = 0; j<=i;j++) cout<<A[j]<<" ";
      cout<<"is "<<median<<endl;
   }
}
int main(){
   int A[] = {12, 54, 9, 6, 1};
   int size = ARRAY_SIZE(A);
   printMedianStream(A, size);
   return 0;
}

Đầu ra

Median of elements : 12 is 12
Median of elements : 12 54 is 33
Median of elements : 12 54 9 is 12
Median of elements : 12 54 9 6 is 10
Median of elements : 12 54 9 6 1 is 9