程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 位圖排序概要 編程珠玑(第一章)-----學習筆記

位圖排序概要 編程珠玑(第一章)-----學習筆記

編輯:C++入門知識

位圖或者位向量可以表示一系列序列集合,比如:可用一個20位長的字符串來表示一個所有元素都小於20的簡單的非負整數集合。例如可用如下字符串表示集合

{1,2,3,5,8,13}: 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 集合中為1的代表整數集合中的該數。

這種表示有一些限制:輸入數據限制在相對較小的范圍內,數據沒有重復,而且對於每條記錄而言,除了單一整數外,沒有任何其他關聯數據。

分三個自然階段來編寫程序,第一階段講所有為都置為0,從而講集合初始化為空,第二階段通過讀入文件中的每個整數來建立集合,將每個對應位都置為1,第三階段

檢驗每一位,如果該位為1,就輸出對應的整數,由此產生有序的輸出文件。


[cpp] 
#include <stdio.h>  
#define MAX 1000000  
#define SHIFT 5             
#define MASK 0x1F  
#define DIGITS 32  
int a[1+MAX/DIGITS]; 
 
void set(int n)     //將邏輯位置為n的二進制位置為1   

    a[n>>SHIFT]=a[n>>SHIFT]|(1<<(n&MASK));     //n>>SHIFT右移5位相當於除以32求算字節位置,n&MASK相當於對32取余即求位位置,  
}                                              //然後將1左移的結果與當前數組元素進行或操作,相當於將邏輯位置為n的二進制位置1.    
 
void clear(int n) 

    a[n>>SHIFT]=a[n>>SHIFT]&(~(1<<(n&MASK)));   //將邏輯位置為n的二進制位置0,原理同set操作   

 
int test(int n) 

    return a[n>>SHIFT] & (1<<(n&MASK));        //測試邏輯位置為n的二進制位是否為1   

 
int main() 

    int i,n; 
    for(i=1;i<=MAX;i++) 
    { 
        clear(i); 
    }     
    while(scanf("%d",&n)!=EOF) 
    { 
        set(n); 
    } 
    for(i=1;i<=MAX;i++) 
    { 
        if(test(i)) 
            printf("%d ",i); 
    } 
    return 0; 

#include <stdio.h>
#define MAX 1000000
#define SHIFT 5          
#define MASK 0x1F
#define DIGITS 32
int a[1+MAX/DIGITS];

void set(int n)     //將邏輯位置為n的二進制位置為1
{
    a[n>>SHIFT]=a[n>>SHIFT]|(1<<(n&MASK));     //n>>SHIFT右移5位相當於除以32求算字節位置,n&MASK相當於對32取余即求位位置,
}                                              //然後將1左移的結果與當前數組元素進行或操作,相當於將邏輯位置為n的二進制位置1. 

void clear(int n)
{
    a[n>>SHIFT]=a[n>>SHIFT]&(~(1<<(n&MASK)));   //將邏輯位置為n的二進制位置0,原理同set操作
}

int test(int n)
{
    return a[n>>SHIFT] & (1<<(n&MASK));        //測試邏輯位置為n的二進制位是否為1
}

int main()
{
    int i,n;
    for(i=1;i<=MAX;i++)
    {
        clear(i);
    }   
    while(scanf("%d",&n)!=EOF)
    {
        set(n);
    }
    for(i=1;i<=MAX;i++)
    {
        if(test(i))
            printf("%d ",i);
    }
    return 0;
}
這裡是c的實現代碼,每個字節32位,所以需要/32來找到字節位,然後n要和32取余,n%32,轉化為為操作就是n&0x1F。

c++中有現成的數據結構bitset<>可以用,簡單使用:


[cpp] 
#include <iostream>  
#include<bitset>   
#define MAX 1000000  
using namespace std; 
 
bitset<MAX+1> bit;        //聲明一個有(MAX+1)個二進制位的bitset集合,初始默認所有二進制位為0   
 
int main() 

    int n,i; 
    while(cin>>n) 
    { 
        bit.set(n,1);          //將第n位置1                 
    }     
    for(i=0;i<=MAX+1;i++) 
    { 
        if(bit[i]==1) 
            cout<<i<<endl; 
    } 
    return 0; 

#include <iostream>
#include<bitset>
#define MAX 1000000
using namespace std;

bitset<MAX+1> bit;        //聲明一個有(MAX+1)個二進制位的bitset集合,初始默認所有二進制位為0

int main()
{
    int n,i;
    while(cin>>n)
    {
        bit.set(n,1);          //將第n位置1              
    }   
    for(i=0;i<=MAX+1;i++)
    {
        if(bit[i]==1)
            cout<<i<<endl;
    }
    return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved