示例#1
0
void RollModel::Roll(int min, int max, int times)
{
    struct occurrence_t{
        int value;
        uint count;
        bool operator < (const occurrence_t &o) const{
            return count > o.count ||
                    (count == o.count && value < o.value);
        }
    };

    beginResetModel();
    m_data.resize(times);
    m_total = 0;
    m_min = GINT32_MAX;
    m_max = GINT32_MIN;
    m_mode.clear();
    m_modeCount = 0;
    m_mean = 0.0;
    m_median = 0.0;
    QHash<int, uint> occurrences;

    for(int i = 0; i < times; i++){
        int X = m_rng.U_Discrete(min, max);
        m_data[i] = X;
        m_total += X;

        if(X < m_min)
            m_min = X;
        if(X > m_max)
            m_max = X;

        if(occurrences.contains(X))
            occurrences[X]++;
        else
            occurrences.insert(X, 1);
    }
    m_mean = (double)m_total/times;
    
    // Compute the median
    vector<int> sorted_data = m_data;
    std::sort(sorted_data.begin(), sorted_data.end());
    int median_index = sorted_data.size() / 2;
    int val1 = sorted_data[median_index];
    int val2 = (sorted_data.size() & 1) ? val1 : sorted_data[median_index - 1];
    m_median = ((double)val1 + val2) / 2;

    // Compute the mode (using heap sort)
    Heap<occurrence_t> heap;
    for(int k : occurrences.keys())
        heap.Push({k, occurrences[k]});

    if(heap.Count()){
        occurrence_t *t = heap.Top();
        uint mode_count = t->count;
        int cnt = 0;
        vector<int> tmp_mode;
        while(t && (mode_count == t->count)){
            tmp_mode.push_back(t->value);
            heap.Pop();
            t = heap.Top();
            cnt++;
        }

        // If every item is the mode, then there is no mode
        if(cnt < occurrences.keys().count()){
            m_modeCount = mode_count;
            m_mode = tmp_mode;
        }
    }
    endResetModel();
}