一些算法练习题
1. 句子反转
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 void reverse_word(char *string, int len); 6 void reverse_sentense( char *string); 7 8 int main(int argc, char* argv[]) 9 { 10 char str[1000]; 11 printf("please input reverse string:\n"); 12 gets(str); 13 //scanf("%s",str); 14 printf("before = %s\n",str); 15 reverse_sentense(str); 16 printf("after = %s\n",str); 17 return 0; 18 } 19 20 void reverse_sentense( char *string) 21 { 22 int temp = 0; 23 int j; 24 int i = strlen(string); 25 if((string==NULL)||(i>1000)) 26 printf("input sentense string not valid\n"); 27 for(j=0;j<i+1;j++) 28 { 29 if((*(string+j)==0x20)||(*(string+j)==0x0)) 30 { 31 //printf("find pos j = %d, temp=%d\n",j,temp); 32 reverse_word((char*)string+temp, j-temp); 33 temp=j+1; 34 } 35 36 } 37 reverse_word(string,strlen(string)); 38 39 } 40 41 void reverse_word(char *string, int len) 42 { 43 char temp; 44 int j; 45 if((string==NULL)||(len>1000)) 46 printf("input word string not valid\n"); 47 for(j=0;j<len/2;j++) 48 { 49 temp = *(string+j); 50 *(string+j) = *(string+len-1-j); 51 *(string+len-1-j) = temp; 52 } 53 return; 54 }
1. 编译存在警告:warning: 'gets' is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations] 。gets在新版的编译器中一般认为是危险的,因为有可能导致越界访问,可以忽略这样的警告。
如果使用scanf接收字符串的话,在串首遇到空格的话,跳过,继续寻找下一个非空格字符,在串中遇到空格时,会结束字符串的输入,因此实现比较困难。
向缓冲区读取字符时
1.scanf()用%c,%s空格键,Tab键,回车键结束一次输入,不会舍弃最后的回车符或空格或Tab(即还在缓冲区中),可使用getchar来吸收scanf()执行之后的换行符。
2.getchar()以回车键结束,也不会舍弃回车符(即存入缓存区)
3.gets()以换行符结束,但之后会舍弃换行符并以'\0',代替(意思是'\n'不会被代入到字符数组中,也不会将换行符存入到缓存区)也就是说:gets()函数读取到\n(我们输入的回车)于是停止读取,但是它不会把\n包含到字符串里面去。然而,和它配合使用的puts函数,却在输出字符串的时候自动换行。
2. 29行字符比较,可以使用ASCII值比较,也可以直接比较字符:
if((*(string+j)==' ')||(*(string+j)=='\0'))
对于字符串,不能直接使用==进行比较,需要使用strcmp等函数
3.
char *str = "2356 7890"; reverse_sentense(str); printf("reverse_sentense = %s\n",str);
str指向text段,程序运行会出错(segment fault);
char str[] = "2356 7890"; reverse_sentense(str); printf("reverse_sentense = %s\n",str); return 0;
str指向栈空间(数据仍然存放text段,编译器会优化为拷贝到栈空间),程序运行正常;
2. 字符串转整形
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 6 int main(int argc, char* argv[]) 7 { 8 char str[1000] = "2356"; 9 char *str2 = str; 10 unsigned int num = 0; 11 12 while(*str2 != '\0') 13 { 14 num= num*10+*str2-'0'; 15 str2++; 16 } 17 printf("num = %d\n",num); 18 return 0; 19 }
1. str作为数组名,其内涵在于其指代实体是一种数据结构,这种数据结构就是数组;其外延在于其可以转换为指向其指代实体(数组的首地址)的指针,而且是一个指针常量。这个指针常量不能用于左值操作:
while(*str != '\0') { num= num*10+*str-'0'; str++; }
编译出错
但是如果将str作为形参传入函数使用,它会被自动转换为普通指针,可以用于左值操作。
2.
char str[10];
char* pStr = str;
sizeof(str) ----> 10
sizeof(pStr) ----> 4
如果将str作为形参传入函数后再计算sizeof(str),其会转换普通指针,结果为4
3. 最长无重复子串
1 int main(int argc, char* argv[]) 2 { 3 int result; 4 char str[] = "123412567890"; 5 result = get_longest_char(str); 6 printf("get_longest_char = %d\n",result); 7 return 0; 8 } 9 10 11 12 int get_longest_char(char* str) 13 { 14 int ascii_array[256]; 15 int i,j,res=0,temp=0; 16 17 memset(&ascii_array[0],0,sizeof(ascii_array)); 18 19 for(i=0;i<strlen(str);i++) 20 { 21 22 for(j=i;j<strlen(str);j++) 23 { 24 if((ascii_array[*(str+j)])==0) 25 { 26 ascii_array[*(str+j)] = 1; 27 } 28 else 29 { 30 temp = j-i; 31 break; 32 } 33 temp = j-i+1; 34 35 } 36 37 if(temp>res) 38 res = temp; 39 40 //printf("i= %d,j= %d,temp = %d\n",i,j,temp); 41 memset(&ascii_array[0],0,sizeof(ascii_array)); 42 } 43 44 return res; 45 46 }
-- ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符,'0'-> 0x30, 'A'->0x41, 'a'->0x61;