赞
踩
E x c e r c i s e 3 − 1 Excercise\quad 3-1 Excercise3−1:输出结果如图1所示,这里故意让二分搜索算法去寻找一个在数组中不存在在的数,然后去看两种二分搜索算法分别所花费的时间的大小,为了使得所花费的时间更具有可分辨性,这里让搜索过程重复执行了 100000000 100000000 100000000次。
/* Solution by Paul Griffiths (mail@paulgriffiths.net) */ /* EX3_1.C ======= Suggested solution to Exercise 3-1 */ #include <stdio.h> #include <time.h> int binsearch(int x, int v[], int n); /* Original K&R function */ int binsearch2(int x, int v[], int n); /* Our new function */ #define MAX_ELEMENT 200000 /* Outputs approximation of processor time required for our two binary search functions. We search for the element -1, to time the functions' worst case performance (i.e. element not found in test data) */ int main(void) { int testdata[MAX_ELEMENT]; int index; /* Index of found element in test data */ int n = -1; /* Element to search for */ int i; clock_t time_taken; /* Initialize test data */ for ( i = 0; i < MAX_ELEMENT; ++i ) testdata[i] = i; /* Output approximation of time taken for 100000000 iterations of binsearch() */ for ( i = 0, time_taken = clock(); i < 100000000; ++i ) { index = binsearch(n, testdata, MAX_ELEMENT); } time_taken = clock() - time_taken; if ( index < 0 ) printf("Element %d not found.\n", n); else printf("Element %d found at index %d.\n", n, index); printf("binsearch() took %lu clocks (%lu seconds)\n", (unsigned long) time_taken, (unsigned long) time_taken / CLOCKS_PER_SEC); /* Output approximation of time taken for 100000000 iterations of binsearch2() */ for ( i = 0, time_taken = clock(); i < 100000000; ++i ) { index = binsearch2(n, testdata, MAX_ELEMENT); } time_taken = clock() - time_taken; if ( index < 0 ) printf("Element %d not found.\n", n); else printf("Element %d found at index %d.\n", n, index); printf("binsearch2() took %lu clocks (%lu seconds)\n", (unsigned long) time_taken, (unsigned long) time_taken / CLOCKS_PER_SEC); return 0; } /* binsearch:find x in v[0] <= v[1] <= ... v[n-1] */ int binsearch(int x, int v[], int n) { int low, mid, high; low = 0; high = n - 1; while ( low <= high ) { mid = (low+high) / 2; if ( x < v[mid] ) high = mid - 1; else if ( x > v[mid] ) low = mid + 1; else return mid; } return -1; } /* binsearch2:find x in v[0] <= v[1] <= ... v[n-1] */ int binsearch2(int x, int v[], int n) { int low, mid, high; low = 0; high = n - 1; mid = (low+high) / 2; while (( low < high ) &&(x != v[mid])) { if ( x < v[mid] ) high = mid - 1; else low = mid + 1; mid = (low+high) / 2; } if ( x == v[mid] ) return mid; else return -1; }
E x c e r c i s e 3 − 2 Excercise\quad 3-2 Excercise3−2:输出结果如图2所示
#include <stdio.h> void escape(char s[], char t[]); void unescape(char s[], char t[]); int main(void) { char text1[100] = "\aHello,\n\tWorld! Mistakee\b was \"Extra 'e'\"!\n"; char text2[100]; char text3[100]; printf("Original string:\n%s\n", text1); escape(text2, text1); printf("Escaped string:\n%s\n", text2); unescape(text2, text3); printf("Unescaped string:\n%s\n", text3); return 0; } /* Copies string t to string s, converting special characters into their appropriate escape sequences. The "complete set of escape sequences" found in K&R Chapter 2 is used, with the exception of: \? \' \ooo \xhh as these can be typed directly into the source code, (i.e. without using the escape sequences themselves) and translating them is therefore ambiguous. */ void escape(char s[], char t[]) { int i=0; int j=0; while ( t[i]!='\0' ) { switch (t[i]) { case '\t': s[j++]='\\'; s[j++]='t'; break; case '\n': s[j++]='\\'; s[j++]='n'; break; case '\a': s[j++]='\\'; s[j++]='a'; break; case '\b': s[j++]='\\'; s[j++]='b'; break; case '\f': s[j++]='\\'; s[j++]='f'; break; case '\r': s[j++]='\\'; s[j++]='r'; break; case '\v': s[j++]='\\'; s[j++]='v'; break; case '\"': s[j++]='\\'; s[j++]='\"'; break; case '\\': s[j++]='\\'; s[j++]='\\'; break; default: s[j++]=t[i]; break; } i++; } s[j]='\0'; } /* Copies string s to string t, converting escape sequences into their appropriate special characters. See the comment for escape() for remarks regarding which escape sequences are translated. */ void unescape(char s[], char t[]) { int i=0; int j=0; while ( s[i]!='\0' ) { switch (s[i]) { case '\\': switch (s[++i]) { case 't': t[j++]='\t'; break; case 'n': t[j++]='\n'; break; case 'a': t[j++]='\a'; break; case 'b': t[j++]='\b'; break; case 'f': t[j++]='\f'; break; case 'r': t[j++]='\r'; break; case 'v': t[j++]='\v'; break; case '\"': t[j++]='\"'; break; case '\\': t[j++]='\\'; break; default: /* We don't translate this escape sequence, so just copy it verbatim */ t[j++] = '\\'; t[j++] = t[i]; } break; default: t[j++]=s[i]; break; } ++i; } t[j]='\0'; }
E x c e r c i s e 3 − 3 Excercise\quad 3-3 Excercise3−3:输出结果如图3所示。
#include <stdio.h> #define MAXIMUM 1000 void expand(char s1[], char s2[]); int is_valid(char c); int main() { char s1[MAXIMUM] = "-A-C-E-I first a-z0-9 second -a-z third 9-2 fourth 6-6- end-"; char s2[MAXIMUM]; printf("%s\n", s1); expand(s1, s2); printf("%s\n", s2); return 0; } void expand(char s1[], char s2[]) { char c, d; int i, j; i = j = 0; while ('\0' != (c = s1[i++])) { if (is_valid(c) && '-' == s1[i] && is_valid(s1[i + 1])) { i++; d = s1[i]; if (c > d) { while (c > d) { s2[j++] = c--; } } else { while (c < d) { s2[j++] = c++; } } } else { s2[j++] = c; } } s2[j] = '\0'; } int is_valid(char c) { if(((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')) || ((c>='0') && (c<='9'))) { return 1; } else { return 0; } }
E x c e r c i s e 3 − 4 Excercise\quad 3-4 Excercise3−4:下面我们首先来看一段代码以及输出,输出结果如图4所示。这里 i n t int int型变量能表示的数的最大范围是 [ − 2147483648 , 2147483647 ] [-2147483648,2147483647] [−2147483648,2147483647],这里我们可以看到 i n t int int型可以表示的最大负数的绝对值要比 i n t int int型可以表示的最大正数的值大一(其它类型的有符号数的类型也是一样的),当我们在尝试使用书中的那个版本的 i t o a itoa itoa接口来将 i n t int int型可以表示的最大负数 − 2147483648 -2147483648 −2147483648转换为字符串的时候会出现问题。书中的那个版本的 i t o a itoa itoa接口会首先将要转换的负数变成正数,但是对于 i n t int int型,它可以表示的最大正数是 2147483647 2147483647 2147483647,因此从图4中我们可以看到 i n t u = − i ; int u=-i; intu=−i;操作之后 u u u的值还是 − 2147483648 -2147483648 −2147483648,因此书中的那个版本的 i t o a itoa itoa接口中的 d o w h i l e do\quad while dowhile循环只会运行一次且就算是这一次对个位数的转换也是错误的,这是因为这一次循环中 n % 10 n\%10 n%10操作的结果是 − 8 -8 −8,因此 n % 10 + ′ 0 ′ n\%10+'0' n%10+′0′操作的结果是 40 40 40(字符 ′ 0 ′ '0' ′0′的 A S C I I ASCII ASCII码值是48,字符 ′ ( ′ '(' ′(′的 A S C I I ASCII ASCII码值是40,),因此这里并没有得到我们所预期的字符 ′ 8 ′ '8' ′8′。为了能够成功实现对 i n t int int型可以表示的最大负数的转换,改进后的程序在判断 d o w h i l e do\quad while dowhile循环的执行的时候改为 w h i l e ( n / = 10 ) ; while ( n /= 10 ); while(n/=10);,而不是 w h i l e ( ( n / = 10 ) > 0 ) ; while( ( n /= 10 )>0); while((n/=10)>0);也就是不为0就可以继续执行循环,且改进后的程序在求余数之后做了绝对值的操作。
#include <stdio.h> #include <limits.h> int main(void) { char c='\0'; printf("sizeof(int)=%d\n",sizeof(int)); printf("Signed int[%d to %d]\n", INT_MIN, INT_MAX); printf("Unsigned int[0 to %u]\n", UINT_MAX); int i=-2147483648; int u=-i; printf("i=%d\n",i); printf("u=%d\n",u); c=(u%10)+'0'; printf("c=%d\n",c); printf("c=%c\n",c); return 0; }
#include <stdlib.h> #include <stdio.h> #include <limits.h> #include <string.h> void itoa_myself(int n, char s[]); void reverse(char s[]); int main(void) { char buffer[100]; printf("INT_MIN: %d\n", INT_MIN); itoa_myself(INT_MIN, buffer); printf("Buffer : %s\n", buffer); return 0; } void itoa_myself(int n, char s[]) { int i, sign; sign = n; i = 0; do { s[i++] = abs(n % 10) + '0'; } while ( n /= 10 ); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } void reverse(char s[]) { int c, i, j; for ( i = 0, j = strlen(s)-1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } }
E x c e r c i s e 3 − 5 Excercise\quad 3-5 Excercise3−5:
#include<stdio.h> #include<string.h> #include<stdlib.h> void itob(int n , char s[], int b); void reverse(char s[]); #define MAXIMUM 100 int main(){ int b = 16; char s[MAXIMUM]; itob(-2147483648,s,b); printf("Base %d = %s\n",b,s); return 0; } void itob(int n, char s[], int b) { int i = 0; int negative=0; if(n<0) { negative=-1; } if((b!=2) && (b!=8) && (b!=16)) { printf("base error\n"); } do { if (abs(n%b)>9) s[i++]= abs(n%b) +'A'-10; else s[i++] = abs(n%b) +'0'; } while ((n/=b)); if(negative==-1) { s[i++]='-'; } s[i] = '\0'; reverse(s); } void reverse (char s[]) { int i , j , c; for (i = 0, j = strlen(s)-1; i < j; i++,j--) c = s[i], s[i]=s[j], s[j]=c; }
E x c e r c i s e 3 − 6 Excercise\quad 3-6 Excercise3−6:
#include <stdlib.h> #include <stdio.h> #include <limits.h> #include <string.h> void itoa_myself(int n, char s[], int minmum); void reverse(char s[]); int main(void) { char buffer[100]; printf("INT_MIN: %d\n", INT_MIN); itoa_myself(INT_MIN, buffer,25); printf("Buffer : %s\n", buffer); return 0; } void itoa_myself(int n, char s[], int minmum) { int i, sign; sign = n; i = 0; do { s[i++] = abs(n % 10) + '0'; } while ( n /= 10 ); if (sign < 0) s[i++] = '-'; while(i<minmum) { s[i++] = ' '; } s[i] = '\0'; reverse(s); } void reverse(char s[]) { int c, i, j; for ( i = 0, j = strlen(s)-1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。