coding日记
1、计算字符串最后一个单词的长度,单词以空格隔开。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 int main() 6 { 7 int i, len = 5000, j=0, flag = 1; 8 char *str = NULL; 9 str = (char *)malloc(5000); 10 memset(str, 0, 5000); 11 getline(&str, (size_t *)&len, stdin); 12 //fgets(str, len, stdin); //\n都会读入 13 len = strlen(str); 14 for(i = len -1; i >= 0; i--) 15 { 16 if (flag && (str[i] == ' ' || str[i] == '\n')) 17 { 18 continue; 19 } 20 else if(str[i] != ' ') 21 { 22 flag = 0; 23 j++; 24 } 25 else 26 { 27 break; 28 } 29 } 30 printf("len: %d\n", j); 31 free(str); 32 return 0; 33 }
总结:在gcc编译器中,对标准库进行了扩展,加入了一个getline函数。该函数的定义如下:
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
其中*lineptr指向一个动态分配的内存区域。*n是所分配内存的长度。如果*lineptr是NULL的话,getline函数会自动进行动态内存的分配(忽略*n的大小),所以使用这个函数非常注意的就使用要注意自己进行内存的释放。
如果*lineptr分配了内存,但在使用过程中发现所分配的内存不足的话,getline函数会调用realloc函数来重新进行内存的分配,同时更新*lineptr和*n。
注意*lineptr指向的是一个动态分配的内存,由malloc,calloc或realloc分配的,不能是静态分配的数组。
注意一个问题就是,getline函数读入的一行是包括最后的换行符的。
下面是使用这个函数情况,事先分配了动态内存。
1 void test3(){ 2 int read; 3 int len=0; 4 char *line=NULL; 5 while((read=getline(&line,&len,stdin))!=-1) 6 printf("%s\n",line); 7 free(line); 8 }
自己实现getline(在标准C语言中,getline函数是不存在的。)
1 int getline1_(char s[],int lim){ 2 int c,i; 3 i=0; 4 while((c=getchar())!=EOF&&c!='\n'&&i<lim-1) 5 s[i++]=c; 6 s[i]='\0'; 7 return i; 8 }
测试程序:
1 int test1(){ 2 char s[100]; 3 int len; 4 while((len=getline_(s,100))>0) 5 printf("%s\n",s); 6 7 return 0; 8 }
但是这个实现是有问题的,就是遇到空行的时候也会停止的。
为了解决这个问题,我们需要重新考虑while循环的判断条件。
在上面的实现中,我们是遇到EOF和换行'\n'的时候都停止 ,然后通过判断所读到的字符串的长度是否大于0来判断是否结束。
为了能读入空行,我们需要判断一下是否读入的是结尾EOF,如果不是就继续读取就可以了。
还有一点,EOF是什么?
EOF是C语言中为了区分有效数据和输入结束符的。
C语言采用的解决办法是:在没有输入时getchar函数将返回一个特殊值,这个特殊值与任何实际字符都不同。这个值成为EOF(end of file ,文件结束)。我们在声明变量c 的时候,必须让它大到足以存放getchar函数返回的任何值。之所以不把c声明成char类型,是因为它必须足够大,除了能存储任何可能的字符外还要能存储文件结束符EOF。
EOF的输入由系统锁定。windows下是ctrl+z,linux/unix下是ctrl+d。
下面是给出的修改后的getline函数
1 int getline2_(char s[],int lim){ 2 int c,i; 3 i=0; 4 while((c=getchar())!=EOF&&c!='\n'&&i<lim-1) 5 s[i++]=c; 6 if(c==EOF&&i==0) 7 return -1; 8 s[i]='\0'; 9 return i; 10 }
这儿还要注意一个问题就是,getline函数读入的一行是包括最后的换行符的。之前我们写的函数是不包括这个的。下面我们进行修改一下,也读入换行符
1 int getline3_(char s[],int lim){ 2 int c,i; 3 i=0; 4 while((c=getchar())!=EOF&&c!='\n'&&i<lim-1) 5 s[i++]=c; 6 if(c==EOF&&i==0) 7 return -1; 8 if(c=='\n') 9 s[i++]=c; 10 s[i]='\0'; 11 return i; 12 }
1 //------------2----------------//------------2----------------//------------2----------------//------------2----------------//------------2---------------- 2 // 写出一个程序,接受一个由字母和数字组成的字符串,和一个字符,然后输出输入字符串中含有该字符的个数。不区分大小写。 3 #include<stdio.h> 4 #include<string.h> 5 6 int main() 7 { 8 char str[10000] = {0}; 9 char the_one; 10 int len = 0, i, num = 0; 11 12 /* if (-1 == (getline((char **)&str, (size_t *)&len, stdin))) //会读入回车\n, getline有长度限制 13 { 14 printf("error: %s\n", "getline"); 15 return 0; 16 }*/ 17 fgets(str, 10000, stdin); 18 19 /* printf("read%d\n", read); 20 for(i = 0; i < read; i++) 21 { 22 printf("str[:%d]: %d\r\n", i, str[i]); 23 }*/ 24 the_one = getchar(); 25 26 len = strlen(str); 27 for (i = 0; i < len ; i++) 28 { 29 if (str[i] == the_one || (str[i] -32) == the_one || (str[i] + 32) == the_one) 30 { 31 num++; 32 } 33 } 34 printf("%d\n", num); 35 return 0; 36 37 }
1 //------------3----------------//------------3----------------//------------3----------------//------------3----------------//------------3---------------- 2 3 //明明的随机数 4 #include<stdio.h> 5 6 int main() 7 { 8 int array[1000] = {0}; 9 int i; 10 int num; 11 12 13 while(scanf("%d", &num) != EOF) 14 { 15 i = 0; 16 while(i < 1000) 17 { 18 array[i] =0; 19 i++; 20 } 21 while(num) 22 { 23 scanf("%d", &i); 24 array[i] = 1; 25 num--; 26 printf("num: %d, i: %d\n", num, i); 27 } 28 29 i = 0; 30 while(i < 1000) 31 { 32 if(array[i]) 33 printf("%d\n", i); 34 i++; 35 } 36 37 } 38 39 return 0; 40 41 }
1 //------------4----------------//------------4----------------//------------4----------------//------------4----------------//------------4---------------- 2 //•连续输入字符串,请按长度为8拆分每个字符串后输出到新的字符串数组; 3 //•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。 4 5 #include<stdio.h> 6 #include<string.h> 7 8 int main() 9 { 10 int len = 0; 11 char str[108] = {0}; 12 int left, i; 13 14 while (scanf("%s", str) != EOF) 15 { 16 //scanf("%s", str); 17 len = strlen(str); 18 printf("%d\n", len); 19 if (len) 20 { 21 for (i = 0; i < len; i++) 22 { 23 if (((i+1) % 8) == 0) 24 { 25 printf("%c\n", str[i]); 26 } 27 else 28 { 29 printf("%c", str[i]); 30 } 31 } 32 left = 8 - len % 8; 33 if (8 != left) 34 { 35 for (i = 0; i < left; i++) 36 { 37 printf("0"); 38 } 39 printf("\n"); 40 } 41 } 42 } 43 return 0; 44 }
1 //------------5----------------//------------5----------------//------------5----------------//------------5----------------//------------5---------------- 2 //写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。(多组同时输入 ) 3 #include<stdio.h> 4 #include<string.h> 5 6 int main() 7 { 8 char number_str[100] = {0}; 9 int number, len, i, tmp = 0; 10 while ((scanf("%s", number_str)) != EOF) 11 { 12 number = 0; 13 tmp = 0; 14 len = strlen(number_str); 15 for(i = 2; i < len; i++) 16 { 17 if(number_str[i] > '9') 18 { 19 tmp = number_str[i] - 'A' + 10; 20 } 21 else 22 { 23 tmp = number_str[i] - '0'; 24 } 25 printf("tmp: %d\n", tmp); 26 number = number * 16 + tmp; 27 } 28 printf("number: %d\r\n", number); 29 } 30 return 0; 31 }
1 //------------6----------------//------------6----------------//------------6----------------//------------6----------------//------------6---------------- 2 /*功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 ) 3 4 最后一个数后面也要有空格*/ 5 #include<stdio.h> 6 7 /* 返回值1表示是质数, 0表示非质数*/ 8 int is_the_one(int number) 9 { 10 int i; 11 for (i = 2; i < number; i++) 12 { 13 if((number % i) == 0) 14 { 15 return 0; 16 } 17 } 18 return 1; 19 } 20 21 int main() 22 { 23 int number, theone = 2, max; 24 25 scanf("%d", &number); 26 max = number / 2; 27 while(theone <= max) 28 { 29 if ((number % theone) == 0) 30 { 31 if (is_the_one(theone)) 32 { 33 printf("%d ", theone); 34 } 35 36 number = number / theone; 37 max = number / 2; 38 } 39 else 40 { 41 theone++; 42 } 43 44 } 45 46 printf("%d\n", number); 47 return 0; 48 49 }
1 //------------6----------------//------------6----------------//------------6----------------//------------6----------------//------------6---------------- 2 //写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。 3 /*#include<stdio.h> 4 int main() 5 { 6 int a,b; 7 8 scanf("%d.%d", &a,&b); 9 if (b>=5) 10 { 11 printf("%d", a+1); 12 } 13 else 14 { 15 printf("%d", a); 16 } 17 return 0; 18 19 } 20 21 #include <stdio.h> 22 23 int main() 24 { 25 int i,j=2; 26 float fl; 27 scanf("%f",&fl); 28 i=(int)(fl*10); 29 i = i/10+(i%10>=5); 30 printf("%d",i); 31 32 return 0 ; 33 };*/
1 //------------7----------------//------------7----------------//------------7----------------//------------7----------------//------------7---------------- 2 //数据表记录包含表索引和数值(int范围的整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。 3 /*#include<stdio.h> 4 #include<string.h> 5 6 int main() 7 { 8 int key_value[1000] = {0}; 9 int num, key, value, i; 10 11 while(scanf("%d", &num) != EOF) 12 { 13 for(i = 0; i < num; i++) 14 { 15 scanf("%d %d", &key, &value); 16 key_value[key] += value; 17 } 18 19 for (i = 0; i < 1000; i++) 20 { 21 if (key_value[i]!= 0) 22 { 23 printf("%d %d\n", i, key_value[i]); 24 } 25 } 26 } 27 28 return 0; 29 30 }*/
1 //------------8----------------//------------8----------------//------------8----------------//------------8----------------//------------8---------------- 2 //输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。 3 /*#include<stdio.h> 4 5 int main() 6 { 7 int num, temp; 8 int num_array[10] = {0}; 9 10 scanf("%d", &num); 11 12 while(num) 13 { 14 //printf("%d \n", num); 15 temp = num % 10; 16 if (!num_array[temp]) 17 { 18 printf("%d", temp); 19 num_array[temp] = 1; 20 } 21 num /= 10; 22 } 23 printf("\n"); 24 return 0; 25 26 }*/
1 //------------9---------------- 2 //编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),换行表示结束符,不算在字符里。不在范围内的不作统计。注意是不同的字符 3 /*#include<stdio.h> 4 #include<stdlib.h> 5 #include<string.h> 6 7 int main() 8 { 9 char str_p[1000]; 10 int char_num[128] = {0}, i, num = 0; 11 12 scanf("%s", &str_p); 13 14 for (i = 0; i < strlen(str_p); i++) 15 { 16 if (str_p[i] == '\n') 17 { 18 break; 19 } 20 else if (str_p[i] >= 0 && str_p[i] <= 127) 21 { 22 char_num[str_p[i]] = 1; 23 } 24 } 25 26 for (i = 0; i < 128; i++) 27 { 28 if (char_num[i] != 0) 29 { 30 num++; 31 } 32 } 33 printf("%d\n", num); 34 35 36 return 0; 37 }*/
1 //------------10---------------- 2 //输入一个整数,将这个整数以字符串的形式逆序输出,程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001 3 /*#include<stdio.h> 4 5 int main() 6 { 7 int i; 8 int num; 9 10 scanf("%d", &num); 11 while(num) 12 { 13 printf("%d", num%10); 14 num /= 10; 15 } 16 printf("\n"); 17 return 0; 18 }*/
1 //------------11---------------- 2 //写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000) 3 /*#include<stdio.h> 4 #include<string.h> 5 6 int main() 7 { 8 int i = 0; 9 char str_buf[1000]; 10 11 scanf("%s", &str_buf); 12 i = strlen(str_buf) - 1; 13 14 while(i >= 0) 15 { 16 printf("%c", str_buf[i]); 17 i--; 18 } 19 printf("\n"); 20 return 0; 21 }*/
1 //------------12---------------- 2 //将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”,所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符 3 // #include<stdio.h> 4 // #include<string.h> 5 6 // int main() 7 // { 8 // int start = 0, end, i, len, tmp_start; 9 // char str_buf[1000] = {0}; 10 11 // fgets(str_buf, 1000, stdin); 12 13 // len = strlen(str_buf); 14 // start = end = len - 1; 15 16 // //printf("11start: %d\n", len); 17 // while(start) 18 // { 19 // //printf("start: %d\n", start); 20 // if (str_buf[start] == ' ') 21 // { 22 // //printf("come \n"); 23 // tmp_start = start + 1; 24 // while(str_buf[tmp_start] != ' ') 25 // { 26 // if (tmp_start == end) 27 // { 28 // break; 29 // } 30 // printf("%c", str_buf[tmp_start]); 31 // tmp_start++; 32 // } 33 // printf(" "); 34 // end = start; 35 // start--; 36 // } 37 // else 38 // { 39 // start--; 40 // } 41 42 // } 43 // for (i = start; i <= end; i++) 44 // { 45 // printf("%c", str_buf[i]); 46 // } 47 // printf("\n"); 48 49 // return 0; 50 // }
1 //------------13---------------- 2 //输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。数据输出n行,输出结果为按照字典序排列的字符串。 3 4 // #include<stdio.h> 5 // #include<stdlib.h> 6 // #include<string.h> 7 // #include<ctype.h> 8 9 // int main() 10 // { 11 // int i = 0, num = 0, j = 0, len = 0; 12 // char *str_array = NULL, *str_tmp = NULL, min_str[100] = {0}; 13 14 15 // scanf("%d", &num); 16 // len = num * 100 * sizeof(char); 17 // str_tmp = str_array = (char *)malloc(len ); 18 // memset(str_array, 0 , len ); 19 20 // while(i < num) 21 // { 22 // scanf("%s", str_tmp); 23 // str_tmp += 100; 24 // i++; 25 // } 26 27 // // str_tmp = str_array; 28 // // /*把字符串都转小写*/ 29 // // for(i = 0; i < len; i++) 30 // // { 31 // // if (str_array[i] >= 'A' && str_array[i] <= 'Z') 32 // // { 33 // // str_array[i] -= ('A' - 'a'); 34 // // } 35 // // } 36 // // for(i = 0; i < num; i++) 37 // // { 38 // // printf("%s\n", str_tmp); 39 // // str_tmp += 100; 40 // // } 41 // for (i = 0; i < num; i++) 42 // { 43 // for (j = i + 1; j < num; j++) 44 // { 45 // if (strcmp(str_array + i * 100, (str_array + j * 100)) > 0) 46 // { 47 // memcpy(min_str, str_array + j * 100, 100); 48 // memcpy(str_array + j * 100, str_array + i * 100, 100); 49 // memcpy(str_array + i * 100, min_str, 100); 50 // } 51 // } 52 // } 53 // str_tmp = str_array; 54 // for(i = 0; i < num; i++) 55 // { 56 // printf("%s\n", str_tmp); 57 // str_tmp += 100; 58 // } 59 60 // return 0; 61 // }
1 //------------14---------------- 2 //输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。 3 /*#include<stdio.h> 4 5 int main() 6 { 7 int num, time = 0; 8 9 scanf("%d", &num); 10 while(num) 11 { 12 if (num%2) 13 { 14 time++; 15 } 16 num /= 2; 17 } 18 printf("%d", time); 19 return 0; 20 }*/
1 //------------15---------------- 2 //题目描述 3 /*王强今天很开心,公司发给N元的年终奖。王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子: 4 主件 附件 5 电脑 打印机,扫描仪 6 书柜 图书 7 书桌 台灯,文具 8 工作椅 无 9 如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。王强想买的东西很多, 10 为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。 11 他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。 12 设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j 1 , j 2 ,……, j k ,则所求的总和为: 13 v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 为乘号) 14 请你帮助王强设计一个满足要求的购物单。*/ 15 16 #include<stdio.h> 17 18 int vv[65][3], w[65][3], d[65][32000]; 19 20 int main() 21 { 22 int m, n, i, j, v, p, q, temp = 0; 23 scanf("%d %d", &m, &n); 24 25 for(i = 1; i <= n; i++) 26 { 27 scanf("%d %d %d", &v, &p, &q); 28 if (0 == q) 29 { 30 vv[i][0] = v; 31 w[i][0] = p*v; 32 } 33 else if(0 == vv[q][1]) 34 { 35 vv[q][1] = v; 36 w[q][1] = p*v; 37 } 38 else 39 { 40 vv[q][2] = v; 41 w[q][2] = p*v; 42 } 43 } 44 45 for (i = 1; i <= n; i++) 46 { 47 for(j = 0; j <= m; j++) 48 { 49 d[i][j] = d[i-1][j]; 50 if (j >= vv[i][0]) 51 { 52 temp = d[i-1][j - vv[i][0]] + w[i][0]; 53 d[i][j] = (temp > d[i][j])? temp : d[i][j]; 54 55 } 56 if (j >= vv[i][0] + vv[i][1]) 57 { 58 temp = d[i-1][j - vv[i][0] - vv[i][1]] + w[i][0] + w[i][1]; 59 d[i][j] = (temp > d[i][j])? temp : d[i][j]; 60 } 61 if (j >= vv[i][0] + vv[i][2]) 62 { 63 temp = d[i-1][j - vv[i][0] - vv[i][2]] + w[i][0] + w[i][2]; 64 d[i][j] = (temp > d[i][j])? temp : d[i][j]; 65 } 66 if (j >= vv[i][0] + vv[i][1] + vv[i][2]) 67 { 68 temp = d[i-1][j - vv[i][0] - vv[i][1] - vv[i][2]] + w[i][0] + w[i][1] + w[i][2]; 69 d[i][j] = (temp > d[i][j])? temp : d[i][j]; 70 } 71 } 72 } 73 printf("%d\n", d[i-1][j-1]); 74 return 0; 75 76 }
1 //------------16---------------- 2 3 // 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。 4 5 // 输入: 6 7 // 合法坐标为A(或者D或者W或者S) + 数字(两位以内) 8 9 // 坐标之间以;分隔。 10 11 // 非法坐标点需要进行丢弃。如AA10; A1A; $%$; YAD; 等。 12 13 // 下面是一个简单的例子 如: 14 15 // A10;S20;W10;D30;X;A1A;B10A11;;A10; 16 17 // 处理过程: 18 19 // 起点(0,0) 20 21 // + A10 = (-10,0) 22 23 // + S20 = (-10,-20) 24 25 // + W10 = (-10,-10) 26 27 // + D30 = (20,-10) 28 29 // + x = 无效 30 31 // + A1A = 无效 32 33 // + B10A11 = 无效 34 35 // + 一个空 不影响 36 37 // + A10 = (10,-10) 38 39 // 结果 (10, -10) 40 41 42 #include<stdio.h> 43 #include<string.h> 44 45 char str[10000] = {0}; 46 47 void check_and_go(char *str_p, int len, int *x, int *y) 48 { 49 int num = 0; 50 printf("22len: %d, %c\n", len, *str_p); 51 if ('A' == *str_p) 52 { 53 str_p++; 54 if (len == 2) 55 { 56 if (*str_p <= '9' && *str_p >= '0') 57 { 58 *x -= (*str_p - '0'); 59 } 60 } 61 else if(len == 3) 62 { 63 if (*str_p <= '9' && *str_p >= '0') 64 { 65 num += (*str_p - '0') * 10; 66 str_p++; 67 if (*str_p <= '9' && *str_p >= '0') 68 { 69 num += (*str_p - '0'); 70 *x -= num; 71 } 72 } 73 } 74 } 75 else if ('D' == *str_p) 76 { 77 str_p++; 78 if (len == 2) 79 { 80 if (*str_p <= '9' && *str_p >= '0') 81 { 82 *x += (*str_p - '0'); 83 } 84 } 85 else if(len == 3) 86 { 87 if (*str_p <= '9' && *str_p >= '0') 88 { 89 num += (*str_p - '0') * 10; 90 str_p++; 91 if (*str_p <= '9' && *str_p >= '0') 92 { 93 num += (*str_p - '0'); 94 *x += num; 95 } 96 } 97 } 98 } 99 else if ('W' == *str_p) 100 { 101 str_p++; 102 if (len == 2) 103 { 104 if (*str_p <= '9' && *str_p >= '0') 105 { 106 *y += (*str_p - '0'); 107 } 108 } 109 else if(len == 3) 110 { 111 if (*str_p <= '9' && *str_p >= '0') 112 { 113 num += (*str_p - '0') * 10; 114 str_p++; 115 if (*str_p <= '9' && *str_p >= '0') 116 { 117 num += (*str_p - '0'); 118 *y += num; 119 } 120 } 121 } 122 } 123 else if ('S' == *str_p) 124 { 125 str_p++; 126 if (len == 2) 127 { 128 if (*str_p <= '9' && *str_p >= '0') 129 { 130 *y -= (*str_p - '0'); 131 } 132 } 133 else if(len == 3) 134 { 135 if (*str_p <= '9' && *str_p >= '0') 136 { 137 num += (*str_p - '0') * 10; 138 str_p++; 139 if (*str_p <= '9' && *str_p >= '0') 140 { 141 num += (*str_p - '0'); 142 *y -= num; 143 } 144 } 145 } 146 } 147 } 148 149 int main() 150 { 151 char *p1 = NULL, *p2 = NULL; 152 int len = 0, x = 0, y = 0; 153 154 while (fgets(str, 10000, stdin)) 155 { 156 x = 0, y = 0; 157 len = strlen(str); 158 printf("len: %d\n", len); 159 p1 = p2 = str; 160 while('\n' != *p2) 161 { 162 if (';' == *p2) 163 { 164 check_and_go(p1, p2 - p1, &x, &y); 165 p2++; 166 p1 = p2; 167 } 168 else 169 { 170 p2++; 171 } 172 173 } 174 printf("%d, %d\n", x, y); 175 } 176 return 0; 177 }