问题
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