Go语言实现位图排序

Go语言提供了byte类型,一个byte对应8个位,所以转换一下就可以实现位图了。

代码:

package main

//author:xcl
//date:2014-1-25

import (
	"fmt"
)

func main() {
	arrInt32 := [...]uint32{5, 4, 2, 1, 3, 17, 13}

	var arrMax uint32 = 20
	bit := NewBitmap(arrMax)

	for _, v := range arrInt32 {
		bit.Set(v)
	}

	fmt.Println("排序后:")
	for i := uint32(0); i < arrMax; i++ {
		if k := bit.Test(i); k == 1 {
			fmt.Printf("%d ", i)
		}
	}
}

const (
	BitSize = 8 //一个字节8位
)

type Bitmap struct {
	BitArray  []byte
	ArraySize uint32
}

func NewBitmap(max uint32) *Bitmap {
	var r uint32
	switch {
	case max <= BitSize:
		r = 1
	default:
		r = max / BitSize
		if max%BitSize != 0 {
			r += 1
		}
	}

	fmt.Println("数组大小:", r)
	return &Bitmap{BitArray: make([]byte, r), ArraySize: r}
}

func (bitmap *Bitmap) Set(i uint32) {
	idx, pos := bitmap.calc(i)
	bitmap.BitArray[idx] |= 1 << pos
	fmt.Println("set()  value=", i, " idx=", idx, " pos=", pos, ByteToBinaryString(bitmap.BitArray[idx]))
}

func (bitmap *Bitmap) Test(i uint32) byte {
	idx, pos := bitmap.calc(i)
	return bitmap.BitArray[idx] >> pos & 1
}

func (bitmap *Bitmap) Clear(i uint32) {
	idx, pos := bitmap.calc(i)
	bitmap.BitArray[idx] &^= 1 << pos
}

func (bitmap *Bitmap) calc(i uint32) (idx, pos uint32) {

	idx = i >> 3 //相当于i / 8,即字节位置
	if idx >= bitmap.ArraySize {
		panic("数组越界.")
		return
	}
	pos = i % BitSize //位位置
	return
}

//ByteToBinaryString函数来源:
// Go语言版byte变量的二进制字符串表示
// http://www.sharejs.com/codes/go/4357
func ByteToBinaryString(data byte) (str string) {
	var a byte
	for i := 0; i < 8; i++ {
		a = data
		data <<= 1
		data >>= 1

		switch a {
		case data:
			str += "0"
		default:
			str += "1"
		}

		data <<= 1
	}
	return str
}

运行结果:

数组大小: 3
set()  value= 5  idx= 0  pos= 5 00100000
set()  value= 4  idx= 0  pos= 4 00110000
set()  value= 2  idx= 0  pos= 2 00110100
set()  value= 1  idx= 0  pos= 1 00110110
set()  value= 3  idx= 0  pos= 3 00111110
set()  value= 17  idx= 2  pos= 1 00000010
set()  value= 13  idx= 1  pos= 5 00100000
排序后:
1 2 3 4 5 13 17

MAIL:  [email protected]

BLOG: http://blog.csdn.net./xcl168

时间: 2024-10-12 04:47:25

Go语言实现位图排序的相关文章

位图排序

在<编程珠玑>上看到的,开篇第一个问题,有很多数,小于一个MAXNUM,没有重复的,怎么排序最快. 答案是位图排序. 如果某一位不为0,那么这一位存代表一个数,位数(在序列中的位置)代表这个数. 比方说这些数都存在数组a,然后利用一个数组b,b初始状态各位都为0,然后读取a,如果a[1]=2,那么b[2]为1,a[3]=6,那么b[6]=1. 实现如下: 1 #include <iostream> 2 #include <fstream> 3 #include<s

[数据结构]利用位图排序

[cpp] view plaincopy #include <stdio.h> #include <stdlib.h> #define INT_BY_BIT 32 #define MASK 0x1F #define SHIFT 5 #define N 1000000 int a[N/INT_BY_BIT+1]; void set_bit(int x) {a[x>>SHIFT] |= 1 << (x & MASK);} void clear_bit(i

【每日算法】计数&amp;基数&amp;桶&amp;位图排序-简介

在前面的文章中,我们介绍的都是基于比较的排序. 对于比较排序,对含n个元素的序列进行排序,在最坏情况下都要用O(n logn)次比较(归并排序和堆排序是渐近最优的). 本文将继续介绍以线性时间运行的排序算法,他们使用的是非比较排序,因此下界O(n logn)对它们不适用. 计数排序 想象下面这种情况: 一个班有k个人,需要排成一条纵队,地面上已经用粉笔按从小到大的顺序标明了1到k个号码,要求按身高从低到高排列,也就是说,最高的站在标号为k的位置,最矮的站在标号为1的位置. 那么对于每个人,如何知

C语言学习_排序_插入排序

1.插入排序 #include <stdio.h> #include <stdlib.h> #define M 100 int main(void) { int i, j, n; int a[M] = {0}; printf("input n:"); scanf("%d", &n); printf("input a:"); for(i = 1; i <= n; i++) //从a[1]开始,也就是第二个数 s

计数排序与位图排序

计数排序(Counting sort)是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置.计数排序不是比较排序,排序的速度快于任何比较排序算法.由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存.计数排序更适合于小范围集合的排序.比如100万学生参加高考,我们想对这100万学生的数学成绩(

位图排序(位图技术应用)

1.  问题描述 给定不大于整数 n 的 k 个互不相等的整数 ( k <n ) , 对这些整数进行排序.本文讨论的内容具体可参见<编程珠玑>(第二版)的第一章. 2.  问题分析 关于排序,已经有多种排序方法了:插入排序,归并排序,快速排序,希尔排序等.每种排序都有不同的用武之地.为什么需要位图排序呢?所有的内部排序(上述所提及)都必须一次性将所有排序元素载入内存.假如有1000,000个整数,每个整数4字节,则意味着,至少需要4000,000B 约为 4MB 的内存空间, 如果仅仅只

【算法思想】位图排序算法

问题的提出 一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7.假设最多只有1M的内存空间可用,在考虑空间和时间的优化的情况下,请问如何对其进行排序? 常规思想 我们假设这些整数都是用整型存储(一般整型的大小为4个字节),那么1M字节可以存储250 000个数据.由于输入文件最大可能有10^7个数据,因此可以通过遍历输入文件40次来完成排序.第一次将在[0,249 999]范围内的整数读入到内存中,第二次将在[250 000,499 999]范围内的整数读入到内存中,依此类推.每读入

C语言基础_排序

一.C语言基础 1)冒泡排序 int array[10] = {1,6,3,4,5,7,7,8,9,10}; for (int j = 0; j < 9; j++) { for (int i=0; i<9-i; i++) { if (array[i] > array[i+1]) { array[i] = array[i] ^ array[i+1]; array[i+1] = array[i] ^ array[i+1]; array[i] = array[i] ^ array[i+1];

C语言常见的排序方法——冒泡法、选择法、插入法

当我们要对C中一组数据进行排序是常见的排序方法有冒泡法.选择法.插入法 冒泡排序法(升序):假设一组数据a[0].a[1].a[2].a[3]...a[n],第一轮:先比较a[0]与a[1].a[1]与a[2]...a[i]与a[i+1]...a[n-1]与a[n]的大小,如果a[i]与a[i+1]不是升序(即a[i] > a[i+1]),那么就将a[i]与a[i+1]的值互换,第一轮过后,a[n]就是最大值:第二轮:运用第一轮同样的方法,比较a[0]与a[1].a[1]与a[2]...a[i]