EMACS & 程序 编程点滴...

天下难事必作于易,天下大事必作于细

Lastupdated: 2009-10-07

基本算法集合

TOP对字符编码进行hash

字符编码按其区位信息,都是以Block分布的。对其进行简单的hash计算,可以很方便的确认某个编码的索引。能够应用在点阵 字库映射等方面。比如以下几种编码,都是2字节的,其范围参考下表。
编码 第一字节 第二字节
0xFC ~ 0xFE
GB2312 0xB0 ~ 0xF7 0xA0 ~ 0xFE
BIG5 0x81 ~ 0xFE 0x40 ~ 0x7E
0xA1 ~ 0xFE
EUC_JP 0xA1 ~ 0xFE 0xA1 ~ 0xFE
S-JIS 0x81 ~ 0x9F 0x40 ~ 0x7E
0xE0 ~ 0xEF 0x80 ~ 0xFC

TOPGB2312

GB2312编码的范围如右图所示,其中纵坐标是高字节(第一字节),横坐标是低字节(第二字节)。

首先计算纵坐标上0xB0开始到C1的偏移,然后将其结果加上横坐标上C2相对于0xA0的偏移。因为索引是由0开始的,这里我们 不能忘记最后还要减去1。

1
index = (C1 - 0xB0) * (0xFE - 0xA0) + (C2 - 0xA0 - 1);

TOPBIG5

1
2
3
4
5
offset = (0x7E - 0x40 + 1) + (0xFE - 0xA1 + 1);
if 0x40 <= C2 <= 0x7E
   index = ((C1 - 0x81) * offset + (C2 - 0x40)) * 2;
elif 0xA1 <= C2 <= 0xFE
   index = ((C1 - 0x81) * offset + (C2 - 0xA1 + 0x7E - 0x40 + 1)) * 2;

TOPEUC_JP

1
2
3
4
5
6
/* ascII */
if (!ch1) {
    index = ch2;
} else {
    index = ((C1 - 0xA1) * (0xFE - 0xA1) + (C2 - 0xA1 - 1));
}

TOP查找

TOP二分查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
int binarysearch(DataType t)
{
    unsigned int l, u, m;
    l = 0;
    u = n-1; /* n >= 1 */
    while (l <= u) {
        m = (l + u) >> 1;
        /* 如果左值是有符号数,这里就可能溢出,所以左值用无符号数 */
        /* java中用 >>> 1 */

        if (x[m] < t)
            l = m+1;
        else if (x[m] == t)
            return m;
        else /* x[m] > t */
            u = m-1;
    }
    return -1;
}

int binarysearch3(DataType t)
{
    int l, u, m;
    l = -1;
    u = n;
    while (l+1 != u) {
        m = (l + u) >> 1;
        if (x[m] < t)
            l = m;
        else
            u = m;
    }
    if (u >= n || x[u] != t)
        return -1;
    return u;
}

int binarysearch4(DataType t)
{
    int l, p;
    if (n != 1000)
        return binarysearch3(t);
    l = -1;
    if (x[511]   < t) l = 1000 - 512;
    if (x[l+256] < t) l += 256;
    if (x[l+128] < t) l += 128;
    if (x[l+64 ] < t) l += 64;
    if (x[l+32 ] < t) l += 32;
    if (x[l+16 ] < t) l += 16;
    if (x[l+8  ] < t) l += 8;
    if (x[l+4  ] < t) l += 4;
    if (x[l+2  ] < t) l += 2;
    if (x[l+1  ] < t) l += 1;
    p = l+1;
    if (p >= n || x[p] != t)
        return -1;
    return p;
}

TOP排序

TOP快速排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static inline int randint(int l, int u)
{
    #define RAND_MAX  (0x7FFFUL)
    return l + (RAND_MAX*rand() + rand()) % (u-l+1);
    #undef RAND_MAX
}

static void quicksort(int l, int u)
{
    int i,m;
    if (l >= u) return;
    swap(l, randint(l,u));
    m = l;
    for (i = l+1; i <= u; i++) {
        if (x[i] < x[l]) {
            swap(++m, i);
        }
    }
    swap(l,m);
    quicksort(l, m-1);
    quicksort(m+1, u);
}

TOP不用比较的排序方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 求累积度数 f[i]可以用bit位做
for (int i = 0; i <= 800; i++) {
    f[i] = 0;
}

for (int j = 0; j < n; i++) {
    i = d[j].point;
    f[i] = f[i] + 1;
}

for (int i = 1; i <= 800; i++) {
    f[i] = f[i] + f[i-1];
}

// sort
for (j = n-1; j >= 0; j--) {
    i = d[j].point;
    p[f[i]] = j;
    f[i] = f[i] - 1;
}

TOP字符串操作

TOP字符串转换为16进制数

通常我们用od1, 或者其他文本编辑器将二进制文件编辑成为文本本件,或着转换为程序中定义的整形数组。而当我们 想把这样的文本文件还原为二进制文件的话,却没有好的方法。下面介绍的函数讲一个文本格式的二进制字符串转换为实际的 二进制文件(16进制数据)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
typedef unsigned char uint8_t;

uint8_t lookupA[23] = {
    0x00, 0x10, 0x20, 0x30, 0x40,
    0x50, 0x60, 0x70, 0x80, 0x90,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF,
    0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0
};

uint8_t lookupB[23] = {
    0x00, 0x01, 0x02, 0x03, 0x04,
    0x05, 0x06, 0x07, 0x08, 0x09,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF,
    0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};

inline int little_endian(void)
{
    int i = 0x01;
    return *(uint8_t*)&i == 0x01;
}

void txt_to_hex(uint8_t* hex, const uint8_t* txt, int length)
{
#if 0
/* 包含大写字符 */
    int i, a, b;
    if (little_endian()) {
        for (i = 0; i<length; i++) {
            a = (int)txt[i << 1] - '0';
            b = (int)txt[(i << 1) + 1] - '0';
            hex[length-i-1] = lookupA[a] + lookupB[b];
        }
    } else {
        for (i = 0; i<length; i++) {
            a = (int)txt[i << 1] - '0';
            b = (int)txt[(i << 1) + 1] - '0';
            hex[i] = lookupA[a] + lookupB[b];
        }
    }
#else
/* 包含小写字符 */
    int i;
    int slength = strlen((char*)txt);
    if (little_endian()) {
        for (i = 0; i < slength; i+=2) {
            hex[length - i/2 - 1] = txt[i]%87%48 << 4 | txt[i+1]%87%48;
        }
    } else {
        for (i = 0; i < slength; i+=2) {
            hex[i/2] = txt[i]%87%48 << 4 | txt[i+1]%87%48;
        }
    }
#endif
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    uint8_t str[] = "ef1234";
    char tt[32] = {0};
    int temp = 0;
    txt_to_hex((uint8_t*)&temp, str, sizeof(temp));
    sprintf(tt, "----- 0x%X -----\n", temp);
    OutputDebugString(tt);
    return 0;
}

TOP字符串中匹配内容置换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static inline char* strrepl(char *orgstr,
                            uint32_t maxsize,
                            char *oldstr,
                            char *newstr)
{
    int oldlen, newlen;
    char *s, *p;
    s = orgstr;
    oldlen = strlen(oldstr);
    newlen = strlen(newstr);

    while (s) {
        p = strstr(s, oldstr);
        if (p == NULL )
            return orgstr;
        if (orgstr == NULL)
            return NULL;
        if (strlen(orgstr)-oldlen+newlen+1 > maxsize) {
            return NULL;
        }
        memmove(p + newlen, p + oldlen, strlen(p + oldlen) + 1);
        memcpy(p, newstr, newlen);
        s = p + newlen;
    }
    return orgstr;
}

1. linux的命令之一,用来按指定形式输入文件

TOPHash表

程序中经常用到Hash表,它具有插入,查找效率高等特点。这里总结一些hash表的用法。包括Hash List,Hash 红黑树,Hash AVL树等。

TOP一般的Hash Table

特点
插入效率高,查找效率高,不支持有序输出

TOPHash List

特点
除了具有一般hash表的特点外,增加了排序的功能。

TOPHash 红黑树

特点
除了具有hash list的特点以外,还支持模糊查找。 具体:
  • 查找速度: 哈希表 > 红黑树
  • 插入/删除速度: 等于哈希表和红黑树之和
  • 按哈希表查找后可以按红黑树有序输出,避免了哈希表的数据无序,以及红黑树查找慢的不足

TOPHash AVL树

特点
查找/插入/删除的效率都有所提高。如图所示,每个bucket指向的不是list而是一颗AVL树。

© www.yifeiyang.net
net tracking

                                                                                                 stats