running median of constant size array

北战南征 提交于 2020-01-02 16:17:14

问题


I am trying to find median of constant size array. But array is always uptading. I mean new numbers are replaced with old numbers. I call this process running median, or we can say on the fly median.. Here is my code and inside the code, when rand() function generates 78, the code cannot find the correct median. (Before 78; 41, 67, 34, 0, 69, 24 was generated)

#include <iostream>
#include <stdlib.h>
#include <algorithm>

#define MAX_SIZE 5
using namespace std;
bool isOdd( int integer )
{

    if ( integer % 2 == 0 )
        return false;
    else
        return true;
}


int main()
{
    int median;
    int *minArray ;
    int *maxArray ;
    int myArray[MAX_SIZE];

    for(int i=0; i<20; i++)
    {
        int v = rand() %100;
        cout << v << endl;

        myArray[i%MAX_SIZE] = v;
            if(i==0)
            {
                median = v;
            }

            else if (v>median)
            {
                maxArray= new int [MAX_SIZE+1];
                int n;
                for(n=0; n<(MAX_SIZE+1); n++)
                {
                    if ((median<myArray[n])&&(myArray[n]<=v))
                    {
                        maxArray[n] = myArray[n];
                        //cout<<"asda"<<maxArray[n]<<endl;
                    }
                    else
                    {
                        maxArray[n] = 200;
                        //cout<<"asda"<<maxArray[n]<<endl;
                    }

                }
                if(isOdd(i)&&(i<MAX_SIZE))
                    median = (median+(*min_element(maxArray,maxArray+MAX_SIZE+1)))/2;
                else median = (*min_element(maxArray,maxArray+MAX_SIZE+1));
                //cout << ((*min_element(maxArray,maxArray+MAX_SIZE+1))) << endl;
                delete [] maxArray;
            }
            else if (v<median)
            {
                minArray= new int [MAX_SIZE+1];
                int n;
                for(n=0; n<(MAX_SIZE+1); n++)
                {
                    if ((median>myArray[n])&&(myArray[n]>=v))
                    {
                        minArray[n] = myArray[n];
                        //cout<<"asda"<<minArray[n]<<endl;
                    }
                    else
                    {
                        minArray[n] = 0;
                        //cout<<"asda"<<minArray[n]<<endl;
                    }
                }

                if(isOdd(i)&&(i<MAX_SIZE))
                    median = (median+(*max_element(minArray,minArray+MAX_SIZE+1)))/2;
                else median = (*max_element(minArray,minArray+MAX_SIZE+1));

                delete [] minArray;

            }

            cout << "median: "<< median<<endl;
        }
    return 0;
}

If I made some mistakes about explaning my problem, excuse me cus I am so new here.


回答1:


I think there might be an alternative way.

Since you now the boundaries of your data set, as denoted by: int v = rand() %100; you can also keep track of the number of occurrences of each number.

You will need to store the number of occurrences in an array which length 100. You'll also need to keep track of the number that's going 'out' to decrease that number of occurrences.

If you have that in place, just loop from 0... 100 if your occurrence count is bigger then MAX_SIZE/2 your there.

This would be a 0(n) operation but with significant overhead, especially because the numbers 0...100 has a much bigger range than the MAX_SIZE of 5 (the other way round would be better).

Anyhow; I think if you apply this principle you also wont have a problem with your changing array.

If you want I can provide you with a quick example.

EDIT

This sample is not working perfectly, but you can give it a try:

#include <iostream>
#include <stdlib.h>
#include <algorithm>

#define MAX_ELEMENTS 5

#define MAX_VALUE 100

using namespace std;
bool isOdd( int integer )
{

    if ( integer % 2 == 0 )
        return false;
    else
        return true;
}


int main()
{
int median;

int numberOfElements = 0;
int myValueArray[MAX_VALUE];
int myArray[MAX_ELEMENTS];

 //quick n dirty init
 for (int c = 0; c < MAX_VALUE; c++)
    myValueArray[c] = 0;

 for (int c = 0; c < MAX_ELEMENTS; c++)
     myArray[c] = 0;

for(int i=0; i<20; i++)
{
    //generate random number 0...100
    int v = rand() % MAX_VALUE;
    cout << "| " << v << " | "; //incomming value

    myValueArray[v]++;

    int leavingValue = myArray[i%MAX_ELEMENTS]; 
    myArray[i%MAX_ELEMENTS] = v; // just to keep track of leaving value

    if (numberOfElements < MAX_ELEMENTS)
        numberOfElements++;

    else //remove leaving value
    {
        myValueArray[leavingValue]--;
        cout << "| " << leavingValue << " | "; //leaving value
    }

    for (int c = 0, occurances = 0; c < MAX_VALUE; c++)
    {
        occurances += myValueArray[c];

        //(numberOfElements + 1) = dirty indexer correction, but you'll get the point
        if (occurances >= (numberOfElements + 1) / 2)
        {
            if (isOdd(numberOfElements))
                median = c;

            else
                cout << "work to do here...";

            break;
        }
    }

    cout << "array: ";
    //just print the array, to confirm
    for (int c = 0, occurances = 0; c < MAX_VALUE; c++)
    {
        if (myValueArray[c] > 0)
        {
            for (int x = 0; x < myValueArray[c]; x++)
                cout << " {" << c << "}, ";
        }
    }

        cout << " >> median: "<< median<<endl;
    }
   return 0;
}


来源:https://stackoverflow.com/questions/19409820/running-median-of-constant-size-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!