1. 程式人生 > >熱點問題演算法思考(一)

熱點問題演算法思考(一)

最近看了一些技術書籍,覺得大資料分析/儲存以及雲平臺必然會成為未來網際網路發展的方向。

對於大資料思考如下問題:

         快取中快取了一天的搜尋詞條,假設詞條大小為1~255位元組不等,那麼如果最快找出其中最熱門的N個搜尋詞條;

這應該是搜尋公司每天都要做的事情,而且資料量也一定非常巨大。

         那麼怎麼以最節省的方式來統計便是一個可以思考的東西了。

         先假設一個簡化的模型:

         假如我有一個超級大的陣列,那麼我要取出其中最小的k個數,該怎麼做到?

         我的實現思路就是先建立一個大小為K的樹,然後一個一個輸入陣列中的數,用一個函式來維護樹。這樣樹中就記錄著大陣列中最小的k個數。

         假設大陣列總長度為N,這樣整個計算的複雜度就是n+n*k;複雜度與想象中的有點差別。對於演算法與資料結構,接下來再更新。

我目前的實現程式碼如下:


#include <iostream>
#include <string>

#define MAX 9999

//單個樹節點的定義
typedef struct S_NODE
{
    int value;
    S_NODE *m_leftNode;
    S_NODE *m_rightNode;
} *PNODE;

//建立一個大小為k的二叉樹
S_NODE* create(int start, int k)
{
    if (k==0) {
        return NULL;
    }
    
    S_NODE *node = new S_NODE;
    node->value = start;
    k--;
    
    int i=k/2;
    
    node->m_leftNode = create(start-i, k-i);
    node->m_rightNode = create(start+i, i);
    
    return node;
}

//列印樹的資訊
void printnode(S_NODE *node)
{
    if (node==NULL)
        return;
    
    if (node->m_leftNode) {
        printnode(node->m_leftNode);
    }
    
    std::cout<<node->value<<" ";
    
    if (node->m_rightNode) {
        printnode(node->m_rightNode);
    }
}

//不停得讀取新的數,吸取小數,扔掉大數
int input(S_NODE *node, int value)
{
    if (node==NULL) {
        return MAX;
    }
    
    int temp = value;
    
    if (value>node->value) {
        if (node->m_rightNode)
            return input(node->m_rightNode, value);
        else
            return value;
    }
    else
    {
        if (node->m_leftNode)
        {
            temp = input(node->m_leftNode, value);
            value = node->value;
            node->value = temp;
            if (node->m_rightNode)
            {
                temp = input(node->m_rightNode, value);
                value = temp;
            }
        }
        else if(node->m_rightNode)
        {
            temp = input(node->m_rightNode, value);
        }
        else
        {
            temp = node->value;
            node->value = value;
            value = temp;
        }
    }
    
    return temp;
}

//測試函式
int main(int argc, const char * argv[])
{
    int temp;
    S_NODE *root = create(100, 7);
    while (1) {
        
        printnode(root);
        
        std::cout<<"\n";
        
        sleep(1);
        
        temp = rand()%100;
        
        std::cout<<temp<<" -- ";
        
        if (temp<0) {
            break;
        }
        
        input(root, temp);
    }
     
    std::cout << "Hello, World!\n";
    return 0;
}


執行結果: