第三章 数组和字符串
来源:互联网 发布:python 去除列表重复 编辑:程序博客网 时间:2024/06/09 22:38
3.1 数组
3.2 字符数组
3-1 逆序输出
读入一些数据,逆序输出在一行(整数不超过100个)
#include<stdio.h>#define N 105 // 注意点①int num[N]; // 存储量较大的建议定义在外面int main(){ int x, i=0; while(~scanf("%d", &x)){ num[i++] = x; } int j = i-1; // 注意点② for(; j>=0; j--){ printf("%d", num[j]); if(j){ printf(" "); } else { printf("\n"); } } return 0;}
memcpy():
①头文件:string.h
②数组a复制k个元素到数组b:
memcpy(b, a, sizeof(int)*k)
③将数组a全部复制到数组b:
memcpy(b, a, sizeof(a))
3-2 开灯问题
有n盏灯,编号为1-n,第一个人把灯全打开,第二个人把编号为2的倍数的灯关掉,第三个人把编号为3的倍数的灯(关掉的打开,打开的关掉)·····一共k个人(k<=n<=1000),输出最后开着的灯的编号
#include<stdio.h>#include<string.h>#define N 1010int light[N];int main(){ int n, k; scanf("%d%d", &n, &k); memset(light, 0, sizeof(light)); // 初始状态设置为关灯(0) int i, j; for(i=1; i<=k; i++){ for(j=1; j<=n; j++){ if(j%i == 0){ light[j] = !light[j]; // 入手点 } } } int first = 1; // 设置输出格式 for(i=1; i<=n; i++){ if(light[i]){ if(first){ first = 0; } else { printf(" "); } printf("%d", i); } } return 0;}
用到:
memset(str, num, sizeof(str)) // str:数组, num:初始化的数
3-3 蛇形填数
#include<stdio.h>#include<string.h>#define N 20int n[N][N];int main(){ memset(n, 0, sizeof(n)); int num; scanf("%d", &num); int max = 1; n[0][num-1] = max; int x = 0, y = num-1; while(max < num*num){ while(x+1<num && !n[x+1][y]){ n[++x][y] = ++max; } // 下 while(y-1>=0 && !n[x][y-1]){ n[x][--y] = ++max; } // 左 while(x-1>=0 && !n[x-1][y]){ n[--x][y] = ++max; } // 上 while(y+1<num && !n[x][y+1]){ n[x][++y] = ++max; } // 右 } for(x=0; x<num; x++){ for(y=0; y<num; y++){ printf("%3d", n[x][y]); } printf("\n"); } return 0;}
这里:
(1)通过寻找填数规律:顺时针一圈一圈
(2)先全部初始化为0,让右上角数为1,往下递增,左转是当它越界前(再一次往下递增时,通过判断下一位数是否已经被初始化为非零数),依次····
(3)%3d很好的找出了输出的规律
3-4 竖式问题
给出一个数字集合,找出满足abc*de的情况,也就是说,三位数乘以两位数,手动计算,计算过程除了进位,数字应该在数字集合中
#include<stdio.h>#include<string.h>int main(){ int count = 0; // 记录满足情况的种类 char s[20], buf[99]; // buf缓冲数组 scanf("%s", s); int abc, de; for(abc=111; abc<=999; abc++){ for(de=11; de<=99; de++){ int x = abc * (de%10); int y = abc * (de/10); int z = abc * de; sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z); int own = 1; for(int i = 0; i<strlen(buf); i++){ if(strchr(s, buf[i]) == NULL){ own = 0; } } if(own){ printf("<%d>\n", ++count); printf("..%d\nX..%d\n-----\n.%d\n%d.\n-----\n%5d\n", abc, de, x, y, z); } } } return 0;}
(1)字符类型char:存储的是ASCII码
(2)scanf读入不含空格、tab、回车符的字符串
(3)strchr的作用:一个字符串中查找1单个字符串
(4)printf:输出到屏幕,fprintf:输出到文件,fprintf:输出到字符串
(5)字符串的本质是:数组,赋值:strcpy(a, b),比较:strcmp(a,b),连接:strcat(a, b)
3-5 TeX中的引号
输出一段文章的Tex的格式(区分左右引号)
#include<stdio.h>int main(){ int character, q=1; while((character = getchar()) !=EOF){ if(character == '"'){ printf("%s", q? "“" : "“"); q = !q; } else { printf("%c", character); } } return 0;}
(1)fgetc
(2)fgets(buf, maxn, fin) :存储限定maxn-1,maxn用来存储\0,gets(s)没有限制,存在缓存区溢出漏洞
3-6 WERTYU
键入一组字符串,每一位都是在输入时,输入了该位在键盘的下一个字符,输出真正想要键入的字符串
#include<stdio.h>int main(){ char s[] = "`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./"; // 常量数组 char c; while((c=getchar())!=EOF){ for(int i=1;s[i] && s[i]!=c; i++){ if(s[i]){ putchar(s[i-1]); } else { putchar(c); } } } return 0;}
巧妙的运用了:常量数组
(1)简化代码
(2)无需计算大小,编译器会计算
3-7 回文词
(1)回文串(abba)
(2)镜像串 (2S)
A-A E-3 H-H I-I L-J M-M O-O S-2 T-T U-U V-V W-W X-X Y-Y Z-5 1-1 2-S 8-8
一般没有空白字符,所以选择scanf
#include<stdio.h>#include<string.h>#include<ctype.h>// 常量数组存储const char *rev = "A 3 HIL JM O 2TUVWXY51SE Z 8 ";const char *msg[] = {"not a palidrome", "a regular palindrome", "a mirrored string", "a mirrored palindrome"};char r(char ch){ if(isalpha(ch)){ return rev[ch - 'A']; } return rev[ch-'0'+25];} int main(){ char s[30]; while(scanf("%s", s) == 1){ int len = strlen(s); int p = 1, m =1; for(int i = 0; i<(len+1)/2; i++){ if(s[i] != s[len-1-i]){ // 非回文串 p = 0; } if(r(s[i]) != s[len-1-i]){ // 非镜像串 m = 0; } } printf("%s -- is %s.\n\n", s, msg[m*2+p]); } return 0;}
头文件ctype.h定义的
(1)isalpha、isdigit、isprint可以用来判断字符的属性
(2)toupper、tolower用来转换大小
3-8 猜数字游戏的提示
输入每个测试项的个数,然后再输入测试项及对比项,统计对比项有多少项与测试项相同,统计在两个项都出现过的但位置对不上的数字数
两次统计有点重复存在,就是说,统计一下在两个项中都出现的数字的个数
#include<stdio.h>#define N 1010int main(){ int n, kcase = 0; while(scanf("%d", &n) == 1 && n){ int a[N], i=0; for(; i<n; i++){ scanf("%d", &a[i]); } int b[N]; for( ; ; ){ int kseatSame = 0, kb = 0; for(i=0; i<n; i++){ scanf("%d", &b[i]); if(a[i] == b[i]){ kseatSame++; } } if(b[0] = 0){ // 由题意得:正常情况下,测试项不含0 (个人刚开始没有考虑到这个,感觉题目也没有说明) break; } int d; for(d=1; d<=9; d++){ int c1 = 0, c2 = 0; for(i=0; i<n; i++){ if(a[i] == d){ c1++; } if(b[i] == d){ c2++; } } if(c1 < c2){ kb += c1; } else { kb += c2; } } printf("Game %d:\n", ++kcase); printf(" (%d,%d)\n", kseatSame, kb - kseatSame); } } }
3-9 生成元
对于生成元,解释是:当y满足:y = x + x各个数位上的数 时,x称作y的生成元
下面这个题目要求对于输入的整数,输出它的最小生成元,无解时输出0
#include<stdio.h>#include<string.h>#define N 100000int num[N];int main(){ memset(num, 0, sizeof(num)); int i = 1; // 将每个数当作 生成元,存储到对应的位置,制作成一张表 for(; i<N; i++){ int key = i, digit = i; // digit:生成元, key:生成元对应的数值 while(digit){ key += digit%10; digit /= 10; } // 为了保证存储的是最小生成元, 得判断要存储的位置是否已经有生成元了 或是 生成元是否比较大 if(num[key] || num[key]>i){ num[key] = i; } } int testTime, n; scanf("%d", &testTime); while(testTime--){ // 利用上面已经存储好的数 scanf("%d", &n); printf("%d\n", num[n]); } return 0;}
这是一个挺好的方法,先制表,再查表
3-10 环状序列
输入一个长度为n的环状DNA串(只含ACGT四个字母),对于这样的字符串,有多种表示方式(任意从一个端点顺时针得到),现在求输入的字符串(环状)的最小表示
【最小表示】:字典序最小的表示法
【字典序】:字符串在字典中的序列
①对于两个字符串,从第一个字符开始比较,当某个位置的字符不同,该处字符较小的字符串的字典序较小(abc<bcd)
②没有不同的字符时,较短的字符串的字典序较小(hi<his)
③1,2,4,7 <1,2,5
#include<stdio.h>#include<string.h>#define N 105int less(const char *s, int p, int q){ // 环状串s的p表示法是否比q表示法的字典小 int n = strlen(s); int i = 0; for(; i<n; i++){ if(s[(p+i)%n] != s[(q+i)%n]){ return s[(p+i)%n] < s[(q+i)%n]; } } return 0;}int main(){ int T; char s[N]; scanf("%d", &T); while(T--){ scanf("%s", s); int num = 0; int n = strlen(s); int i; for(i=1; i<n; i++){ if(less(s, i, num)){ num = i; } } for(i=0; i<n; i++){ putchar(s[(i+num)%n]); } putchar('\n'); } return 0; }
3-10
1.用ASCII码表示字符
2.进制转换和移位运算符
(1<<8)-1 // 等价于2^8-1,这里的括号不能缺少,(优先级)
3.补码表示法
在大多数计算机内部,整数采用补码表示法
-n == 2^32-n
-1:4294967295
- 第三章 数组和字符串
- 第三章 数组和字符串
- 第三章 数组和字符串
- 第三章 字符串、向量和数组
- 第三章 字符串、向量和数组
- 第三章 字符串、向量和数组
- 第三章 字符串、向量和数组
- 第三章 字符串、向量和数组
- 第三章 数组和字符串(1)
- 第三章 数组和字符串(2)
- 第三章 数组和字符串(上)
- 第三章数组和字符串下
- 第三章:字符串、向量和数组
- 紫书第三章-----数组和字符串
- C++学习笔记 | 第三章 字符串、向量和数组 | (1)
- [C++ primer]第三章笔记--字符串、向量和数组
- 经典重拾-第一部分 第三章-数组和字符串
- C++ Primer | 第三章 字符串、向量和数组
- 第五周上机实践项目——项目1-三角形类雏形(1)
- MySQL批量SQL插入性能优化
- 求整数的最小完全平方数个数
- java第二十六节-UDP编程
- 802.11p的信道功能
- 第三章 数组和字符串
- POJ 1915 Knight Moves(广搜)
- java事件处理的三种方式
- hdu-1298 T9(字典树+DFS)
- android,bindService实例
- linux基础
- 微信公众号开发443端口,本地服务器,小记
- 唯爱小粽子:Redis的安装与使用
- 浅析Java中的final关键字