每日一題6:位元影像向量排序,位元影像向量排序

來源:互聯網
上載者:User

每日一題6:位元影像向量排序,位元影像向量排序

位元影像向量排序有三大優點:1)速度快,複雜度為O (n);2)記憶體需要少;3)排序時間與輸入元素資料無關,但它也有三個很嚴苛的限制:1)整數;2)元素值在一定範圍之內(與機器記憶體有關)3)沒有重複。它的本質是使用位元組的下標來記錄元素值,而數組的值表示該元素下標是否存在,因此達到節省記憶體、加快速度的目標(節省記憶體是針對元素比較密集的情況,過於稀疏的情況未必就節省記憶體)。
比如說要表示包含1-5範圍內的整數的一個集合,只需要一個位元組(8位),而不是20個位元組。但是需要把這八個位看作是一個具有八個元素的數組,如果某個元素為1,那麼表示這個元素的下標在整數集裡,如果為0則表示不存在下標表示的整數。因此1-5的整數可以表示為:
0 1 1 1 1 1 0 0
表示完成後,就可以掃描數組,輸出排序結果。
但是當前的程式語言(除了一些庫)中並沒有bit資料類型,所以需要找到一種方法,進行bit位與選用的資料類型的轉換,為了簡單,可以使用unsigned char類型來表示bit位,每個unsigned char元素c有八位,要判斷第a位是否為1,可以使用該元素與一個只在第a位上為1而在其他位上都為0的數b(八位表示的數)相與,結果為0,表示a位為0,非0,則a位為1。要設定某一位的值,只需將a與b相或即可(原理嘛,用筆在紙上寫寫就知道了)。數b如何求呢,第一位為1其他位為0的數是128,其它位為1的數就可以通過對128進行右移位元運算得到。準備工作完成:

#include "stdafx.h"#include <iostream>using namespace std;//為了使演算法對負數也有效,所以將最小值和最大值也作為輸入void sort(int *array,int value_count,int min_value,int max_value){    if(min_value >= max_value) return;    //bit向量的大小,並不是由輸入數組的大小決定,而是由輸入數組    //的元素範圍決定,所以先max_value - min_value + 1計算出    //表示這個範圍需要多少個bit位,但是為了保證分配到的記憶體足夠    //且最少,所以再加7,然後用得到的和除以8,從而計算出表示位元影像    //向量數組的大小    int bit_map_count = (max_value - min_value + 1 + 7) / 8;    unsigned char* bit_map  = new unsigned char[bit_map_count];    //必須將位元影像向量先初始化為0    memset(bit_map,0,bit_map_count*sizeof(unsigned char));    int* p = array;    for (int i = 0; i < value_count; ++i,++p)    {         //保證value非負,因為數組下標是非負的        int value = *p - min_value;        //元素值除以8,得到表示該元素的位元影像向量所在位元組的下標        int index = value >> 3;        //求摸則得到元素在位元組中所處的位置        int pos_in_byte = value % 8;        //設定相應的位為1        bit_map[index] = bit_map[index] | (128>>pos_in_byte);    }    p = array;    for (int i = 0; i < bit_map_count; ++i)    {        unsigned char c = bit_map[i];        for (int j = 0; j < 8; ++j)        {            //判斷相應位是否為1            if( c & (128>>j))            {                //恢複輸入元素的原值,並將其添加到輸出數組中                *p = (i<<3) + j + min_value;                ++p;            }        }    }}int _tmain(int argc, _TCHAR* argv[]){    int n = 10;    int array[] = {0,-1,-2,-3,-4,-5,-6,-7,-8,-9};    for (int i = 0; i < n; ++i)    {        cout<<array[i]<<' ';    }    cout<<endl;    sort(array,n,-9,98);    for (int i = 0; i < n; ++i)    {        cout<<array[i]<<' ';    }    cout<<endl;}


程式正確運行,sort函數還有可以改進的地方:將b的值先計算出來,然後就可以把與b相關迴圈展開。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.