【算法】算法的艺术(四)
2013-04-05 11:55
246 查看
数组作计数器
一篇文章共有10行,每行最多80字符,编程统计文章中26个英文字母分别出现的次数(不区分大小写)。 实例解析: 文章的内容可以通过键盘输入到一个二维数组中:
写一个函数,用来判断字符串是否回文。 实例解析: 所谓回文,是指顺读、倒读都相同,即左右对称,比如:abcba。 本实例要求写一个被调函数(而不是主函数)。被判断的字符串需要由主调函数传来,故所编函数应有一个参数。是否回文这个结论需要告知主调函数,故函数需要返回值。 判断是否回文,可用循环,先测试字符串有效长度,然后第0个字符和最后一个字符比较,第1个和倒数第二个比较…..,若所有比较都相等,则是回文,只要有一对不相等,则不是回文。
找素数 利用函数调用找出1000以内的所有素数。 实例解析: 根据题意,本题应该编写两个函数,一个主函数main(),一个被调函数prime()。可这样设计:被调函数prime()负责判断一个数是否素数;主函数利用循环在1~1000中找出素数,自然地,如果需要判断某数是否素数,则调用prime()。 prime()判断的数要由主函数给定,故prime()需要一个参数,当判断结束时,需要将结论告之主函数,故需要返回值。返回值可以是字符型(返回’Y’或’N’),也可以返回整型(1代表是素数,0代表不是素数),这里我们采用整型。
字符串转化为实数
编写一个函数,用来把键盘输入的字符串(如: “312.96”),转换为实数。 实例解析: 键盘输入的应是一个字符串组合,函数将之转换为实型数据。方法是:从字符串的第一个字符开始逐个读取字符,并作相应的计算处理。其中对整数部分的处理和对小数部分的处理要用不同的方法。 (1)对于整数部分,从左到右依次读取字符:先读取’3’,实际上读出来的是’3’的ASCII码值51,减掉48,得到数值3,然后将该值存入变量x,即x=3。 如果’3’后面没有数字了(比如:字符串是“3”时),或者’3’后面是小数点(比如“3.14”),则整数部分就是3了。 对于字符串“312.96”这种情况,由于‘3’后面既不是空字符,也不是小数点,而是字符’1’,故’3’应升级为“十位”上的数字,所以首先将x乘以10,然后将后面’1’读出来,减掉48,合并到x中。即x = x*10+’1’- 48 = 31。 继续读取,读出第三个字符’2’,使x = x*10+’2’- 48 = 312。 同样的方法继续,直到小数点或空字符,则整数部分计算结束。 (2)对于小数部分,从左到右读取,读取的第一个字符,要减去48然后除以10,再合并到x中。 对于第二个字符,读取出来减48然后除以100。 对第三个字符,读取后减48后再除以1000。 …… 直到空字符为止。 程序代码:
一篇文章共有10行,每行最多80字符,编程统计文章中26个英文字母分别出现的次数(不区分大小写)。 实例解析: 文章的内容可以通过键盘输入到一个二维数组中:
char s[10][81]; for(i = 0; i <= 9; i++) gets(s[i]);下面的任务就是统计这个二维数组中的26个英文字母各自出现的次数。根据经验,要统计他们出现的次数,需要26个计数器,即需要26个变量。由于所用变量较多,自然地,我们想到了数组。 定义一个数组 count[26],用count[0]统计字母A或a出现的次数,用count[1]统计B或b出现的次数…..用count[25]统计Z或z出现的次数。 从头依次判断文章中每个字母,并统计到count的某元素中。可以用if语句判断是哪个字母,也可以用switch语句,作用相同。 下面是用if语句的算法:
if(s[i][j] == ’A’ || s[i][j] == ’a’) count[0]++; if(s[i][j] == ’B’ || s[i][j] == ’b’) count[1]++; if(s[i][j] == ’C’ || s[i][j] == ’c’) count[2]++; ……但是这样写的代码太麻烦。 下面我们介绍另一种简单的方法:我们注意到,字母的ASCII码值与其计数器下标总是相差65(或97),利用这个规律,可以这样编程: 对大写字母,这样统计:
count[s[i][j]-65]++;对小写字母,则这样统计:
count[s[i][j]-97]++;完整的程序代码如下:
int main() {char s[10][81]; int i, j, count[26] = {0}; for(i = 0; i <= 9; i++) gets(s[i]); for(i = 0; i <= 9; i++) for(j = 0; s[i][j] != 0; j++){ if(s[i][j] >= 65 && s[i][j] <= 90) count[s[i][j]-65]++; if(s[i][j] >= 97 && s[i][j] <= 122) count[s[i][j]-97]++; } for(i = 0; i <= 25; i++) printf(“%4d”, count[i]); printf(“\n”); return 0; }判断字符串是否回文
写一个函数,用来判断字符串是否回文。 实例解析: 所谓回文,是指顺读、倒读都相同,即左右对称,比如:abcba。 本实例要求写一个被调函数(而不是主函数)。被判断的字符串需要由主调函数传来,故所编函数应有一个参数。是否回文这个结论需要告知主调函数,故函数需要返回值。 判断是否回文,可用循环,先测试字符串有效长度,然后第0个字符和最后一个字符比较,第1个和倒数第二个比较…..,若所有比较都相等,则是回文,只要有一对不相等,则不是回文。
#include <string.h> int palindrome(char *p) {int i, n; n = strlen(p); //测试字符串长度 for(i = 0; i < n/2; i++){ if(*(p+i) != *(p+n–i–1)) return 0; } return 1; }
找素数 利用函数调用找出1000以内的所有素数。 实例解析: 根据题意,本题应该编写两个函数,一个主函数main(),一个被调函数prime()。可这样设计:被调函数prime()负责判断一个数是否素数;主函数利用循环在1~1000中找出素数,自然地,如果需要判断某数是否素数,则调用prime()。 prime()判断的数要由主函数给定,故prime()需要一个参数,当判断结束时,需要将结论告之主函数,故需要返回值。返回值可以是字符型(返回’Y’或’N’),也可以返回整型(1代表是素数,0代表不是素数),这里我们采用整型。
#include <math.h> int main() {int prime(int); int i, count = 0; for(i = 1; i <= 1000; i++) if(prime(i) == 1) printf(“%5d”, i); printf(“\n”); getch(); return 0; } int prime(int m) {int k, i; k = sqrt(m); for(i = 2; i <= k; i++) if(m%i == 0) return 0; return 1; }上面prime()函数中,若某一个i的取值使得m%i == 0成立,则直接返回0,后面剩下的循环,包括return 1,都将被忽略,所以prime()不会返回两个值;若i所有的取值都不能使表达式为真,则结束循环后执行return 1。 prime()函数也可以这样设计:
int prime(int m) {int k, i; int flag = 1; //先让flag = 1,表示是素数,若不是,再改为0 k = sqrt(m); for(i = 2; i <= k; i++) if(m%i == 0){ flag = 0; break; } return flag; }或将核心代码改成:
for(i = 2; i <= k && flag == 1; i++) if(m%i == 0) flag = 0;这两种设计都不如第一种方法简捷。
字符串转化为实数
编写一个函数,用来把键盘输入的字符串(如: “312.96”),转换为实数。 实例解析: 键盘输入的应是一个字符串组合,函数将之转换为实型数据。方法是:从字符串的第一个字符开始逐个读取字符,并作相应的计算处理。其中对整数部分的处理和对小数部分的处理要用不同的方法。 (1)对于整数部分,从左到右依次读取字符:先读取’3’,实际上读出来的是’3’的ASCII码值51,减掉48,得到数值3,然后将该值存入变量x,即x=3。 如果’3’后面没有数字了(比如:字符串是“3”时),或者’3’后面是小数点(比如“3.14”),则整数部分就是3了。 对于字符串“312.96”这种情况,由于‘3’后面既不是空字符,也不是小数点,而是字符’1’,故’3’应升级为“十位”上的数字,所以首先将x乘以10,然后将后面’1’读出来,减掉48,合并到x中。即x = x*10+’1’- 48 = 31。 继续读取,读出第三个字符’2’,使x = x*10+’2’- 48 = 312。 同样的方法继续,直到小数点或空字符,则整数部分计算结束。 (2)对于小数部分,从左到右读取,读取的第一个字符,要减去48然后除以10,再合并到x中。 对于第二个字符,读取出来减48然后除以100。 对第三个字符,读取后减48后再除以1000。 …… 直到空字符为止。 程序代码:
float myatof(char *p) {float x = 0; while(*p != ’\0’ && *p != ’.’){ x = x*10 + *p - 48; p++; } if(*p == ’.’){ int k = 10; p++; while(*p != ’\0’){ x += (float)(*p - 48)/k; k *= 10; //为下一次循环做准备 p++; } } return x; } //主函数: int main() {char s[20]; float x; gets(s); x = myatof(s); printf("%f\n",x); getch(); return 0; }任意进制数的转换 编写函数用于将任意无符号整数转换为d(2~16)进制数。 实例解析: 设要转换的数为n,转换为d进制后,将结果存入指定位置s处。 方法:用n一次次除以d,直到n为0为止,每次都记录下余数,将余数倒排起来就是n的d进制数。 程序代码:
#define M sizeof(unsigned int)*8 int trans(unsigned n, int d, char *s) {char digits[] = "0123456789ABCDEF"; //十六进制数字的字符 char buf[M+1]; //用于存放余数字符 int j, i = M; buf[i] = '\0'; do{ buf[--i] = digits[n%d]; n /= d; }while(n); for(j = 0; buf[i] != '\0'; j++,i++) //复制到指定位置s处 s[j] = buf[i]; s[j] = ’\0’; return j; //设计有返回值,但可以不用 } 附:主函数,用于测试trans函数 int main() { unsigned int num,d; char s[33]; scanf(“%d%d”, &num, &d); trans(num, d, s); printf(“%d = %s(%d)\n”, num, s, d); getch(); return 0; }本文出自 “创十三” 博客,请务必保留此出处http://liucw.blog.51cto.com/6751239/1171343
相关文章推荐
- 程序员面试、算法研究、编程艺术、红黑树、机器学习5大系列集锦
- 程序员面试、算法研究、编程艺术、红黑树4大经典原创系列集锦与总结
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- 程序员面试、算法研究、编程艺术、红黑树4大经典原创系列集锦与总结
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- 程序员编程艺术:第三章续、Top K算法问题的实现
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- PhotoShop算法实现高级篇-剪纸艺术滤镜(三十二)
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结
- 程序员面试、算法研究、编程艺术、红黑树4大系列集锦与总结 .
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- ACM 算法艺术与信息学竞赛 1.2.1盒子里面的汽球
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
- 程序员面试、算法研究、编程艺术、红黑树4大系列集锦与总结
- 程序算法艺术与实践:递归策略之递归,循环与迭代
- 程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结
- 程序员编程艺术:第三章续、Top K算法问题的实现
- 程序员编程艺术(算法卷):第十章、如何给10^7个数据量的磁盘文件排序