Skip to content

Instantly share code, notes, and snippets.

@sunnylost
Last active December 18, 2015 16:39
Show Gist options
  • Save sunnylost/5813161 to your computer and use it in GitHub Desktop.
Save sunnylost/5813161 to your computer and use it in GitHub Desktop.
TCPL 习题集 第二章
//16 进制转 10 进制
#include <stdio.h>
int strlen(char[]);
int htoi(char[]);
int pow(int, int);
int main() {
char s[] = "1.00";
printf("convert %s result= %d\n", s, htoi(s));
//printf("LENGTH = %d\n", strlen("12345"));
}
int htoi(char s[]) {
int len = strlen(s);
int i = 0;
int result = 0;
int c;
while(len--) {
c = s[len];
if(c > 'f' || c < '0' || (c > '9' && c < 'a')) {
printf("The input %s was not a valid hex.\n", s);
return -1;
}
if(c >= 'a') {
c -= 87;
} else {
c -= 48;
}
result += pow(16, i) * c;
i++;
}
return result;
}
int pow(int base, int x) {
int r = 1;
while(x--) {
r *= base;
}
return r;
}
int strlen(char s[]) {
int i = 0;
while(s[i] != '\0')
++i;
return i;
}
//squeeze(s1, s2),将字符串 s1 中任何与字符串 s2 中字符串匹配的字符都删掉
#include <stdio.h>
void squeeze(char[], char[]);
int main() {
char s1[] = "1231ab1c";
char s2[] = "afbe12";
squeeze(s1, s2);
}
void squeeze(char s1[], char s2[]) {
int i, j, k;
for(i = 0; s2[i] != '\0'; i++) {
for(j = k = 0; s1[k] != '\0'; k++) {
if(s1[k] != s2[i]) {
s1[j++] = s1[k];
}
}
s1[j] = '\0';
}
printf("S1 = %s S2 = %s\n", s1, s2);
}
/*
setbits(x, p, n, y)
该函数返回对 x 执行下列操作后的结果值:将 x 中从第 p 位 开始的 n 个(二进制)位设置为 y 中最右边 n 位的值,x 的其余各位保持不变(最右边为第 0 位)。
思路:
比如说 x 为 123,y 为 234,p 为 4,n 为 3;
转为二进制:x 为 1111011,y 为 11101010,最终结果应为 1101011;
x 中第 p 位开始的 n 个位为 110,y 对应值为 010;
先保存 x 的最右 p - n + 1 位,因为这些位是不变的;
将 x 中需要变化的位修改为 0,与 y 的对应位进行异或运算;
最后和前面保存的 x 的后几位做异或运算,得到结果。
*/
#include <stdio.h>
int setbits(unsigned, int, int, unsigned);
int main() {
printf("%d\n", setbits(123, 4, 3, 234));
}
int setbits(unsigned x, int p, int n, unsigned y) {
/**
int base = ~(~0 << n),
remainNum = p + 1 - n,
lastY = y & base,
remainX = x & ~(~0 << remainNum),
preX = (x >> remainNum) & ~base,
processX = preX ^ lastY,
result = processX << remainNum ^ remainX;
*/
return (((x >> (p + 1 - n)) & (~0 << n)) ^ (y & ~(~0 << n))) << (p + 1 - n) ^ (x & ~(~0 << (p + 1 - n)));
}
//invert(x, p, n),将 x 中从第 p 位开始的 n 个二进制位求反,其余各位不变。
#include <stdio.h>
int invert(unsigned, int, int);
int main() {
printf("%d\n", invert(123, 4, 3));
}
int invert(unsigned x, int p, int n) {
int remainNum = p + 1 - n;
int remainX = x & ~(~0 << remainNum);
int lastX = (x >> remainNum);
return (((lastX & (~0 << n)) ^ (lastX & ~(~0 << n)) ^ ~(~0 << n)) << remainNum) ^ remainX;
}
//rightrot(x, n)。该函数返回将 x 循环右移(即从最右端移出的位将从最左端移入) n (二进制)位后所得到的值。
#include <stdio.h>
int rightrot(unsigned, int);
int main() {
printf("%d\n", rightrot(123, 5));
}
int rightrot(unsigned x, int n) {
unsigned int i = 0, y = 0, backUp = x;
while(backUp != 0) {
if(n != 0) {
--n;
y = y | ((x & ~(~0 << 1)) << i);
x >>= 1;
i++;
} else {
y <<= 1;
}
backUp >>= 1;
}
return y | x;
}
//使用 x &= x - 1 来简化 bitcount 函数,注释内是原方法,判断二进制数中有几个 1。
#include <stdio.h>
int bitcount(unsigned);
int main() {
printf("%d\n", bitcount(123));
}
int bitcount(unsigned x) {
int b = 0;
/*
for(b = 0; x != 0; x >>= 1)
if(x & 01)
b++;
*/
while(x != 0) {
b++;
x &= x - 1;
}
return b;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment