Algorithm - jjin-choi/study_note GitHub Wiki
ref : http://www-igm.univ-mlv.fr/~lecroq/string/
1. Brute Force (BF)
- x : pattern
- y : input
- m : size of pattern
- n : size of input
- O( nm )
#include <stdio.h>
#include <string.h>
#define OUTPUT(x) printf("%d\n", x )
void BF(char *x, int m, char *y, int n) {
int i, j;
/* Searching */
for (j = 0; j <= n - m; ++j) {
for (i = 0; i < m && x[i] == y[i + j]; ++i);
if (i >= m)
OUTPUT(j);
}
}
int main()
{
char y[] = "how are you hello world hello";
char x[] = "hello";
BF( x, strlen(x), y, strlen(y) );
return 0;
}
2. Karp-Rabin (KR)
- data structure : hash
- hash๋ฅผ ์ด์ฉํ๋ฉด์๋ rehash macro๋ฅผ ๊ตฌํํ์ฌ for loop ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก ํ๋ค.
#include <stdio.h>
#include <string.h>
#define OUTPUT(x) printf("%d\n", x )
#define REHASH(a, b, h) ((((h) - (a)*d) << 1) + (b))
void KR(char *x, int m, char *y, int n) {
int d, hx, hy, i, j;
/* Preprocessing */
/* computes d = 2^(m-1) with
the left-shift operator */
for (d = i = 1; i < m; ++i)
d = (d<<1);
for (hy = hx = i = 0; i < m; ++i) {
hx = ((hx<<1) + x[i]);
hy = ((hy<<1) + y[i]);
}
/* Searching */
j = 0;
while (j <= n-m) {
if (hx == hy && memcmp(x, y + j, m) == 0)
OUTPUT(j);
hy = REHASH(y[j], y[j + m], hy);
++j;
}
}
int main()
{
char y[] = "how are you hello world hello";
char x[] = "hello";
KR( x, strlen(x), y, strlen(y) );
return 0;
}
3. Shift Or (SO)
-
bit mask / bit shift ์ฌ์ฉ
-
ASZIE : 256
-
O(nm) โ O(n+m)
-
S[ASIZE][pattern size] : ์ด๊ธฐํ (1111 1111) ํ ๊ฐ ASCII ๊ฐ์ pattern ์ ์กด์ฌํ๋ ์์น ์ ์ฅ
- pattern: hello
- S['h'] = 1111 1110
- S['e'] = 1111 1101
- S['l'] = 1111 0011
- S['o'] = 1110 1111
- lim = 0001 1111 ์์ right shift ํ๋ฒ ํ ~() ์ ๋ถ์ธ๋ค. (lim = ~(lim >>1))
- j๋ 1๋ถํฐ j<<=1 ํ์ฌ m๋ฒ ๋ฐ๋ณต
-
searching ์ฉ bit : state
- state๋ lim ๊ณผ ๋น๊ตํ๊ณ state<<1์ S[y[i]] ์ ๋น๊ตํ๋ค.
- state<<1๊ณผ S[y[i]]๋ฅผ OR ์ฐ์ฐ์ ํ์ฌ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ state์ ์ ์ฅํ๋ค.
- ์ด ๋, ๋๋ค 0์ธ ๋ถ๋ถ๋ง (์ฆ ์ผ์นํ๋ ๋ถ๋ถ) ๋ง 0์ด ๋๋ค.
- pattern์ ์๋ ๊ธ์๋ S[' '] ์์ ๋ชจ๋ 1๋ก ์ด๊ธฐํ ๋์ด์๊ธฐ ๋๋ฌธ์
- pattern์ ์๋ ๊ธ์๋ฅผ ๋ง๋๋ฉด state๋ ๋๋ก์๋ฏธํ๋ถ์ด ๋์ด 1111 1111 (~0) ์ด ๋๋ค.
- pattern์ด ๋ชจ๋ ์ผ์นํ๋ ๊ฒฝ์ฐ์๋ง lim > state๊ฐ ๋๋ค.
-
look-up table ์ ๋ง๋ค์ด์ memory๋ฅผ ๋ ์ฐ๊ธฐ๋ ํ์ง๋ง, momory๋ฅผ ์๋ผ๊ธฐ ์ํด bit ์ฌ์ฉ
-
์ต๋ ํ๊ณ : m์ด WORD (32 bits)๋ณด๋ค ํฐ ๊ฒฝ์ฐ pattern์ ์ ์ฅํ ์ ์์
- ํ์ฅ bit map์ ๋ง๋ค๋ฉด ๋๊ธด ํ๋ค.
-
ํ์ง๋ง ์์ง๋ n ํ์ ์ ํ๋ค. ์ ์ด๋ n-m+1 ๋งํผ for loop ํ๋ค.
#include <stdio.h>
#include <string.h>
#define OUTPUT(x) printf("%d\n", x )
#define ASIZE 256
int preSo(char *x, int m, unsigned int S[]) {
unsigned int j, lim;
int i;
for (i = 0; i < ASIZE; ++i)
S[i] = ~0;
for (lim = i = 0, j = 1; i < m; ++i, j <<= 1) {
S[x[i]] &= ~j;
lim |= j;
}
lim = ~(lim>>1);
return(lim);
}
void SO(char *x, int m, char *y, int n) {
unsigned int lim, state;
unsigned int S[ASIZE];
int j;
/* Preprocessing */
lim = preSo(x, m, S);
/* Searching */
for (state = ~0, j = 0; j < n; ++j) {
state = (state<<1) | S[y[j]];
if (state < lim)
OUTPUT(j - m + 1);
}
}
int main()
{
char y[] = "how are you hello world hello";
char x[] = "hello";
SO( x, strlen(x), y, strlen(y) );
return 0;
}
4. Morris-Pratt (MP)
- example
- pattern : g a g g g a g g
- mpNext : -1 0 0 1 1 1 2 3 4
- mpNext์ ์ฒ์์ -1 default
- mpNext ์ ์๋ฏธ๋, ํ๋ฆฐ ๋ฌธ์์ด์ด ๋ฐ๊ฒฌ๋ ์์น์ ์์ ์ผ์น๋ ๋ฌธ์์ด์์ ์ ๋์ฌ์ ์ ๋ฏธ์ฌ์ ์ผ์น์. ์ฆ, shift = i = mpNext[i] ๊ฐ์ด ๋์ด shift ๋งํผ๋ง ๋ฐ์ด์ฃผ๋ฉด ๋๋ค.
- ๋ฐ์ for loop๋ฅผ ์ค์ผ ์ ์๋ค.
- ์ฆ ์ ๋์ฌ ์ ๋ฏธ์ฌ๊ฐ ์ผ์นํ ๊ฒ์ ๋ํด์ ๋ ๋น๊ต๋ฅผ ํ์ง ์์๋ ๋๋ค.
#include <stdio.h>
#include <string.h>
#define OUTPUT(x) printf("%d\n", x )
void preMp(char *x, int m, int mpNext[]) {
int i, j;
i = 0;
j = mpNext[0] = -1;
while (i < m) {
while (j > -1 && x[i] != x[j])
j = mpNext[j];
mpNext[++i] = ++j;
}
}
void MP(char *x, int m, char *y, int n) {
int i, j, mpNext[256];
/* Preprocessing */
preMp(x, m, mpNext);
/* Searching */
i = j = 0;
while (j < n) {
while (i > -1 && x[i] != y[j])
i = mpNext[i];
i++;
j++;
if (i >= m) {
OUTPUT(j - i);
i = mpNext[i];
}
}
}
int main()
{
//int mpNext[256];
int i;
char y[] = "how are you gagggagg world hello";
char x[] = "gagggagg";
/*
preMp( x, strlen(x), mpNext );
for(i=0; i<(strlen(x)+1); i++ )
printf("%4d", mpNext[i] );
printf("\n");
*/
MP( x, strlen(x), y, strlen(y));
return 0;
}
5. Knuth-Morris-Pratt
- example
- pattern : g a g g g a g g
- kmpNext : -1 0 -1 1 1 0 -1 1 4
- ์ด ์์์์๋ mpNext ์ ๋นํด์ 7 ํ์ ์ด ์ค์ด๋ค๊ฒ ๋๋ค. (2๋ฐฐ ์ด์ ๋น ๋ฅด๋ค!)
- ๋ฏธ๋ฆฌ๋น๊ต๋ฅผ ์ํํ์ฌ x[i] ์ x[j]๋ฅผ ๋จผ์ ๋น๊ตํ๋ค.
#include <stdio.h>
#include <string.h>
#define OUTPUT(x) printf("%d\n", x )
#define ASIZE 256
#define XSIZE 256
void preKmp(char *x, int m, int kmpNext[]) {
int i, j;
i = 0;
j = kmpNext[0] = -1;
while (i < m) {
while (j > -1 && x[i] != x[j])
j = kmpNext[j];
i++;
j++;
if (x[i] == x[j])
kmpNext[i] = kmpNext[j];
else
kmpNext[i] = j;
}
}
void KMP(char *x, int m, char *y, int n) {
int i, j, kmpNext[XSIZE];
/* Preprocessing */
preKmp(x, m, kmpNext);
/* Searching */
i = j = 0;
while (j < n) {
while (i > -1 && x[i] != y[j])
i = kmpNext[i];
i++;
j++;
if (i >= m) {
OUTPUT(j - i);
i = kmpNext[i];
}
}
}
int main()
{
int i;
char y[] = "how are you gagggagg world hello";
char x[] = "gagggagg";
KMP( x, strlen(x), y, strlen(y));
return 0;
}
6. Boyer-Moore
- ๋น๊ต๋ฅผ pattern์ ๋ค์์๋ถํฐ ํ๋ค.
- bad character : bad character ๊ฐ ๋ค์ ๋ง๋ ๋๊น์ง์ ์ต์ ๊ธธ์ด
- ๋งจ ๋ท์นธ์ ๊ธฐ์ค์ผ๋ก ๋ช์นธ ๋จ์ด์ ธ ์๋์ง ๊ธฐ๋กํ table์ด bmBc[] ์ด๋ค. ๋ง์ฝ pattern์ ๊ฐ์ด ์์ผ๋ฉด ?!?!
#include <stdio.h>
#include <string.h>
#define OUTPUT(x) printf("%d\n", x )
#define MAX(a,b) (((a)>(b))?(a):(b))
#define ASIZE 256
#define XSIZE 256
void preBmBc(char *x, int m, int bmBc[]) {
int i;
for (i = 0; i < ASIZE; ++i)
bmBc[i] = m;
for (i = 0; i < m - 1; ++i)
bmBc[x[i]] = m - i - 1;
}
void suffixes(char *x, int m, int *suff) {
int f, g, i;
suff[m - 1] = m;
g = m - 1;
for (i = m - 2; i >= 0; --i) {
if (i > g && suff[i + m - 1 - f] < i - g)
suff[i] = suff[i + m - 1 - f];
else {
if (i < g)
g = i;
f = i;
while (g >= 0 && x[g] == x[g + m - 1 - f])
--g;
suff[i] = f - g;
}
}
}
void preBmGs(char *x, int m, int bmGs[]) {
int i, j, suff[XSIZE];
suffixes(x, m, suff);
for (i = 0; i < m; ++i)
bmGs[i] = m;
j = 0;
for (i = m - 1; i >= 0; --i)
if (suff[i] == i + 1)
for (; j < m - 1 - i; ++j)
if (bmGs[j] == m)
bmGs[j] = m - 1 - i;
for (i = 0; i <= m - 2; ++i)
bmGs[m - 1 - suff[i]] = m - 1 - i;
}
void BM(char *x, int m, char *y, int n) {
int i, j, bmGs[XSIZE], bmBc[ASIZE];
/* Preprocessing */
preBmGs(x, m, bmGs);
preBmBc(x, m, bmBc);
/* Searching */
j = 0;
while (j <= n - m) {
for (i = m - 1; i >= 0 && x[i] == y[i + j]; --i);
if (i < 0) {
OUTPUT(j);
j += bmGs[0];
}
else
j += MAX(bmGs[i], bmBc[y[i + j]] - m + 1 + i);
}
}
int main()
{
int i;
char y[] = "how are you gagggagg world hello";
char x[] = "gagggagg";
BM( x, strlen(x), y, strlen(y));
return 0;
}
1. generic swap
- swap ํจ์๋ call by address๋ก ๊ตฌํํ์ฌ ์ค์ ๊ฐ์ด swap ๋ ์ ์๋๋ก ํ๋ค.
- ์ธ์๋ก ๋ฐ์์ค๋ type์ ๋ชจ๋ ์ง์ํด์ค์ผ ํ๋๋ฐ, c์์๋ ํจ์ ์ค๋ฒ๋ก๋ฉ์ ์ง์ํ์ง ์์ผ๋ฏ๋ก
- ์ด๋ ์ธ์ ์๋ technique ์ด void pointer
- integer 4 byte / double 8 byte / char 4 byte ์ด๊ธฐ ๋๋ฌธ์ int size ์ธ์๋ฅผ ์ถ๊ฐํ๋ค.
void swap (char *a, char *b, int size)
{
int i;
char t;
for (i=0; i<size; i++) {
t = *a[i];
*a[i] = *b[i];
*b[i] = t;
}
}
// main
int a, b;
int ad, bd;
swap (&a, &b, sizeof(a));
swap(&ad, &bd, sizeof(ad);
- caller ์์ warning์ด ๋ง์ด ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ง๊ธฐ ์ํด์ ๋ช ์์ casting์ ํด์ค๋ค.
- ์ฆ &a, &b ๋ก ๋๊ฒจ์ฃผ๋๊ฒ ์๋๋ผ, ํจ์์ ์ธ์ type์ ๋ง๊ฒ casting ํ์ฌ ๋๊ฒจ์ค๋ค.
swap( (char*)&a, (char*)&b, sizeof(a) )
- ํ์ง๋ง ์ด๋ ๊ฒ ๋๋ฉด ์ฌ์ฉํ ๋๋ง๋ค ์บ์คํ ์ ํด์ฃผ๋๋ผ ์ฐ๊ธฐ ๋ถํธํด์ง๋ค.
- ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด void pointer์ ์ฌ์ฉํ์ !
- ํ์ง๋ง void pointer์ ์ธ๋๋ ์ฒจ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค. (ex. *a[i])
- ๋ฐ๋ผ์ ์ค์ ๋ก ์ฃผ์์ ์ ๊ทผํ ๋ casting์ ํ์ฌ ์ปดํ์ผ๋ฌ์๊ฒ ์ผ๋ง๋งํผ ์์ง์ด๋ฉด ๋ ์ง๋ฅผ ์๋ ค์ฃผ์ด์ผ ํ๋ค.
void swap (void *a, void *b, int size)
{
int i;
char t;
char *aa = (char*)a;
char *bb = (char*)b;
for (i=0; i<size; i++) {
t = *aa[i];
*aa[i] = *bb[i];
*bb[i] = t;
}
}
void generic_swap(void *a, void *b, int size)
{
char t;
do {
t = *(char *)a;
*(char *)a++ = *(char *)b;
*(char *)b++ = t;
} while (--size >0);
// ์ค์ generic swap ํจ์
// size๋ฅผ 0๊ณผ ๋น๊ตํ๊ธฐ ๋๋ฌธ์ (์ฐ๋ฆฌ๊ฐ ์ง ์ฝ๋๋ i๊ณผ size ๋น๊ต) ์ข๋ ์ ๋ฆฌํ๋ค
}
2. generic sort
void bubble(int *a, int n)
{
int i, j;
for (i=0; i<n-1; i++)
for (j=0;j<n-1-i; j++)
if (a[j] > a[j+1])
generic_swap(a+j, a=j+1, sizeof(a[0]));
}
int main()
{
int a[] = {4, 3, 5, 2, 7, 1, 6};
int i;
bubble(a, 7);
for (i=0; i<7;t++)
printf("%4d", a[i]);
printf("\n");
return 0;
}
- ๊ฐ์ด ํ์ํ ์๊ณ ๋ฆฌ์ฆ์ ์ผ๋ฐํ ํ ์ ์๋ค.
- ์ฆ, sort์์๋ ๊ฐ์ ๋น๊ตํ๊ธฐ ์ํด ๊ฐ์ด ํ์ํ๋ฏ๋ก sorting, ๊ฒ์ ๋ฑ์ ์ผ๋ฐํ ํ ์ ์๋ค.
- void ํฌ์ธํฐ๋ง์ผ๋ก๋ ์งค ์ ์๋ค. โ ์ผ๋ฐํ๋ฅผ ์ํ ! "๋น๊ต"๋ฅผ ์ ์ ์๊ฒ ์์ํ์.
- ํจ์ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉ
int int_cmp(const void* a, const void* b)
{
return (*(int*)a - *(int*)b) > 0;
}
# ๋ชจ๋ type ์ sort ํ๊ธฐ ์ํด์
# ํ๋์ ์์์ size๋ฅผ size๋ก ๋ฃ์ด์ค๋ค.
void bubble (void *a, int n, int size, int (*cmp)(const void*, const void*))
{
...
# void pointer ๋ฅผ ์ง์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก
# pointer ์๋ ๊ณ์ฐํด์ค๋ค.
if (cmp ((char*)a+j*size, (char*)a+(j+1)*size)>0)
...
}
- qsort (ํต ์ํธ) ๋ ํธํ ๊ฐ๋ฅ
1. find first set
- ๋จ์ํ << shift๋ฅผ ์ด์ฉํด ๋น๊ต๋ฅผ ํ๋ฉด ์ต์ ์ ๊ฒฝ์ฐ O(n) search ํด์ผ ํ๋ค.
- __ffs ํจ์๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด bit๋ฅผ ์ ๋ฐ์ฉ ์ชผ๊ฐ์ bit mask ๋ก ๋น๊ต๋ฅผ ํ๋ฏ๋ก O(log2n) search ๋ง ํ๋ฉด ๋๋ค.
- ํ์ง๋ง ์๋ ์ฝ๋๋ ์ต์์ bit๊ฐ 0์ด๊ฑฐ๋ 1์ผ๋ ๊ฒฐ๊ณผ๊ฐ ๊ฐ์์ง๊ฒ ๋๋ค.
- ๋จผ์ word๊ฐ 0 ์ธ์ง ์๋์ง๋ถํฐ ์ฒดํฌํ๊ณ ffs ํ๋ฉด ๋๋ค.
// for int (32 bit)
14 int __ffs(int word)
15 {
16 int num = 0;
17
18 if ( (word & 0xffff) == 0 ) {
19 // 00000000 00000000 11111111 1111111
20 // if == 0 --> at least 16 bit
21 num += 16;
22 word >>= 16;
23 }
24
25 if ( (word & 0xff) == 0 ) {
26 // 00000000 1111111
27 // if == 0 --> +8
28 num += 8;
29 word >>= 8;
30 }
31
32 if ( (word & 0xf) == 0 ) {
33 // 00001111
34 num += 4;
35 word >>= 4;
36 }
37
38 if ( (word & 0x3) == 0 ) {
39 // 0011
40 num += 2;
41 word >>= 2;
42 }
43
44 if ( (word & 0x1) == 0)
45 num += 1;
46
47 return num;
48 }
if (bitmap != 0)
__ffs
else
error !
2. find next bit
- ํ์ฅ bitmap search
int bitmap[4] = {0, };
bitmap[3] |= 1 << 4;
// bitmap[100/32] |= 1 << 100%32;
// ํ๋ฉด 100๋ฒ์งธ์ ๋ค์ด๊ฐ๋ค.
// 100 = 32 * 3 + 4
-
example
- real time (RT) process : 0 ~ 99
- normal process : 100 ~ 139
- ๋ง์ฝ normal process ๊ตฌ๊ฐ์์๋ง search๋ฅผ ํ๊ณ ์ถ๋ค๋ฉด, ๋ถ๋ถ bit์ด search๋ฅผ ์ํ logic ์ด find_next_bit ๋ผ๊ณ ํ๋ค.
-
find_next_bit ( input, ์ ํจ bit ์, ์ ํจ bit ์์์ )
3.hamming weight
- example
-
input : 0x12345678
-
input : 0001 0010 0011 0100 0101 0110 0111 1000
-
mask1 : 0101 0101 0101 0101 0101 0101 0101 0101
-
(x & m1) + ((x >> 1) & m1) output : 0001 0001 0010 0100 0101 0101 0110 0100
-
compare
- 00 01 00 10 00 11 01 00 01 01 01 10 01 11 10 00 (input)
- 00 01 00 01 00 10 01 00 01 01 01 01 01 10 01 00 (output)
- ์ฆ, 2 bit์ฉ ๋๋ ์ ๋ณด๋ฉด mask1 ์ ๊ฒฐ๊ณผ๋ 2 bit๋ผ๋ฆฌ์ bit์ ๊ฐ์๊ฐ ๊ธฐ๋ก๋๋ค.
-
mask2 : 0011 0011 0011 0011 0011 0011 0011 0011
-
input : 0001 0010 0011 0100 0101 0110 0111 1000
-
out : 0001 0001 0010 0001 0010 0010 0011 0001
- ์ด๋ฒ์๋ 4 bit์ฉ ๋๋ ์ ๋ณด๋ฉด mask2 ์ ๊ฒฐ๊ณผ๋ 4 bit๋ผ๋ฆฌ์ bit ๊ฐ์๊ฐ ๊ธฐ๋ก๋๋ค.
-
3 const int m1 = 0x55555555; // 01010101 ...
4 const int m2 = 0x33333333; // 00110011 ...
5 const int m4 = 0x0f0f0f0f;
6 const int m8 = 0x00ff00ff;
7 const int m16 = 0x0000ffff;
8 const int h01 = 0x01010101;
9
10 int popcount_a(int x)
11 {
12 x = (x & m1) + ((x >> 1) & m1); // 2bit count
13 x = (x & m2) + ((x >> 2) & m2); // 4bit count
14 x = (x & m4) + ((x >> 4) & m4);
15 x = (x & m8) + ((x >> 8) & m8);
16 x = (x & m16) + ((x >> 16) & m8);
17
18 return x;
19 }
-
popcount_a ๊ฐ O(log2n) ์ผ๋ก ๊ณ์ฐ์ ์ค์์ง๋ง, ์ฐ์ฐ์๊ฐ ๋ง๋ค.
- ์ฐ์ฐ์๊ฐ ํ ์ค์ 4๊ฐ๋ ์ฐ์ฌ์ CPU ์๋๊ฐ ๋๋ ค์ง๊ฒ ๋๋ค.
-
popcount_b
- 2bit ์ ๊ฒฝ์ฐ์ ์๋ 00 01 10 11 ๋ฐ์ ์๋ค.
- ์ด ๋์ bit count ์ธ๋ฉด 00 01 01 10 ์ด ๋๋ค.
- popcount_b ์์ m1์ ๋ํ ์์, ์๋ณธ bit์์ ์์ bit์ ๋ฐ์ด์ count ํ๊ฑฐ๋ฅผ ์๋ณธ์์ ๋บ๊ฒ count ๋ผ๋ ๊ฒ
- ์๋ณธ - ์ bit = count
- 00 - 0 = 00
- 01 - 0 = 01
- 10 - 1 = 01
- 11 - 1 = 10
-
popcount_c
- 3๋ฒ์งธ ๊น์ง๋ 8๋ฒ์งธ๊น์ง bit์ count (์ฌ๊ธฐ๊น์ง๋ popcount_b์ ๋์ผ)
- ex) 0x12345678 -> 0x02030404
- h01 ์ ์ด์ฉํ๋ค ! (h01 = 0x01010101)
- h01์ ๊ณฑํ๋ฉด, 0x02030404 * 0x01010101 = ๊ฒฐ๊ณผ ๋ถ๋ถ์์ 0x00 0000 1100 0000 1์ด ์๋ ๋ถ๋ถ์ด, 2bit์ฉ ์๋ผ๋ด์ ๋ํ๊ฒ๊ณผ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ฒ ๋๋ค. ์ด๋ฅผ ๋์ค์ 24๋งํผ ๋ฐ์ด์ค ๊ฒฐ๊ณผ๋ถ๋ถ๋ง ๊ฐ์ ธ์ค๋ฉด ๋๋ค.
- ์์ฆ CPU๋ ๊ณฑ์ ๋นจ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฐ์ฐ์ ์ค์ผ ์ ์๋ค.
- open source __sw_hweight32 ๋ ์ด๊ฑธ ์ด์ฉํ๊ณ ์์
21 int popcount_b(int x)
22 {
23 x -= (x >> 1) &m1;
24 x = (x & m2) + ((x >> 2) & m2);
25 x = (x + (x >> 4)) & m4;
26 x += x >> 8;
27 x += x >> 16;
28
29 return x & 0x7f;
30 }
31
32 int popcount_c(int x)
33 {
34 x -= (x >> 1) &m1;
35 x = (x & m2) + ((x >> 2) & m2);
36 x = (x + (x >> 4)) & m4;
37
38 return (x * h01) >> 24;
39 }
40
- popcount_d
-
x &= x-1;
-
0001 0010 0011 0100 0101 0110 0111 1000
-
0001 0010 0011 0100 0101 0110 0111 0111
-
________________________________________ &
-
0001 0010 0011 0100 0101 0110 0111 0000 -> count = 1
-
1์ด ์ง์์ง๋ ๋งํผ counting ์ด ๋๋ค.
-
ํ์ง๋ง ์ฑ๋ฅ์ด ์ข์๊น? ๋ณดํต์ ๊ฒฝ์ฐ ์ ๋ฆฌํ ๊ฒ์ด ์๋๋ผ, 1์ ๊ฐ์ง bit ์๊ฐ ํ์ ํ ์ ์ ๋ ! ์ ๋ฆฌํ๋ค.
-
32 bits ์ค์์ 2๊ฐ๋ง 1์ผ๋ 2๋ฒ๋ง์ ์ฐพ์๋ผ ์ ์์ด์ ์ ๋ฆฌํ๋ค. log2n ๋ณด๋ค ์ ์๋ ์ ๋ฆฌํ๋ค.
-
ํน๋ณํ ๊ฒฝ์ฐ์๋ง performance๊ฐ ์ข๊ธฐ ๋๋ฌธ์ ์คํ์์ค์์๋ popcount_c๋ฅผ ์ฌ์ฉํ๋ค.
-
32 int popcount_d(int x)
33 {
34 int count;
35 for (count = 0; x; count++)
36 x &= x - 1;
37
38 return count;
39 }
40
4. bit reverse
- lookup table
- 2^8 = 256 ๊ฐ (16 x 16 matrix ๋ฅผ ๋ง๋ค์ด ๋ฏธ๋ฆฌ ๊ณ์ฐํด๋๋ค.)
- 0x12 ๋ฅผ ๋ฃ์ผ๋ฉด 1ํ 2์ด์ ์ฝ์ด์จ๋ค.
- 0x12 โ 0x21 ์ด ์๋๋ผ 0001 0010 โ 0100 1000 ์ฆ 0x48 ์ด ๋๋ค.
- lookup table ์ ๋ฏธ๋ฆฌ ์จ๋๊ณ ์ด์ฉํ๋ค.
- unsigned char (8bit) ์ ๋ํด์ 16x16 = 256 ํฌ๊ธฐ์ table์ ๋ง๋ค์ด ๋๊ณ ์ฌ์ฉํ๋ค.
- ์ต๋ ํ๊ณ๋ 16bit์ ๋ํด์๋ (size 65532) lookup table์ ๋ง๋ค ์ ์๋ค.
- unsigned short (16bit) ๋ฅผ ๊ณ์ฐํ ๋๋, 8bit ์ฉ reverseํ๊ณ ์ ๋ค 8bit๋ฅผ swap ํ๋ค.
- unsigned int (32bit) ๋ 16bit์ฉ reverseํ๊ณ ์ ๋ค 16bit๋ฅผ swap ํ๋ค.
11 u8 bitrev8(u8 x)
12 {
13 return byte_rev_table(x);
14 }
15
16 u16 bitrev16(u16 x)
17 {
18 return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
19 }
20
21 u32 bitrev32(u32 x)
22 {
23 return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16);
24 }
1. parity bit
- ๋คํธ์ํฌ๋ฅผ ํ๊ณ client ์ ์ ์ก์ด ๋์์ ๋, ๋ฐ์ดํฐ ์ค๋ฅ๋ฅผ ๊ฒ์ฆํ ์ฉ๋๋ก ์ฌ์ฉ
- 1์ ๊ฐ์๊ฐ ํ์์ผ๋๋ ๋งจ ์ bit์ 1์ ๋ฃ๊ณ , 1์ ๊ฐ์๊ฐ ์ง์์ผ๋๋ ๋งจ ์ bit์ 0์ ๋ฃ๋๋ค.
- hweight ์ด์ฉํ์ฌ 1์ ๊ฐ์ ํ์
- hweight(data)%2 ์ผ ๊ฒฝ์ฐ data |= 0x80; (1000 0000)
- parity bit๊ฐ ์ ์ฉ๋๋ฉด 1์ ๊ฐ์๊ฐ ํญ์ ์ง์์ด๊ธฐ ๋๋ฌธ์, ๋ฐ๋ ์ชฝ์์๋ hweight ์ด์ฉํ์ฌ 1์ ๊ฐ์ ํ์
- ์ต๋ ํ๊ณ : ์ง์๊ฐ์ bit๊ฐ ๋ณํ๋๋ฉด error๋ฅผ ์ฐพ์ ์ ์๋ค.
2. check sum
- ์ก์ ๋ถ์ ์์ ๋ถ์ ์ฝ๋๊ฐ ๊ฐ๋ค.
์์คํค ์ฝ๋ 128 bit ์ค์์ 7bit (Ex) a 97 0110 0001 ref ) https://github.com/imguru-mooc/opensource-datastructure-algorithm