1(1).判断素数(prime)
#include <stdio.h>
#include <math.h>
int prime (int n); //函数声明
int main( ){
int n;
scanf("%d",&n);
if (prime(n)==1)
printf("%d is a prime.\n",n);
else
printf("%d is not a prime",n);
return 0;
}
int prime(int n){
if(n<=1)
return 0;
else if(n==2)
return 1;
else if(n%2==0)
return 0;
for(int i=3;i<=sqrt(n);i+=2){
if(n%i==0)
return 0;//如果是main函数内,换成break
}
return 1;
}
1(2).寻找素数
编写一个函数,从键盘输入m,输出大于m且紧随m的素数。在主函数中进行输入和输出
#include <math.h>
int prime(int n){
if(n<=1)
return 0;
if(n==2)
return 1;
if(n%2==0)
return 0;
for(int i=3;i<=sqrt(n);i+=2){
if(n%i==0)
return 0;
}
return 1;
}
int fun(int m){
m++;
while(prime(m)==0) //注意循环开始条件:m不为素数,加一继续寻找
m++;
return m;
}
2.最大公约数(hcf)和最小公倍数(lcd)
辗转相除法(欧几里得算法):
较大数a作除数,较小数b作被除数,两数相除得余数;把b赋为除数,余数赋为被除数,反复相除直至余数为0;最后一次相除的除数为最大公约数,最大公约数*最小公倍数=a*b
原理:对于任意两个正整数啊a,b(a>b),有gcd( a,b)=gcd( b,a mod b)
//a mod b指a除以b的余数,gcd(x,y)表示x,y的最大公约数
#include <stdio.h>
int main(){
int hcf(int m,int n);
int lcd(int m,int n);
int m,n,h,l;
scanf("%d %d",&m,&n);
h=hcf(m,n);
l=lcd(m,n);
printf("最大公约数为%d.\n",h);
printf("最小公倍数为%d.\n",l);
return 0;
}
int hcf(int u,intv){
while(v!=0){
int temp=u%v;
u=v;
v=temp;
}
return u;
}
int lcd(int u;int v;int h){ //h为最大公约数
h=hcf(u,v);
return u*v/h;
}
3.除去数组最值后输出
#include <stdio.h>
int main(){
int n,i;
scanf("%d",&n);
if(n-2<=0){
printf("None.\n");
return 0;
}
int a[n];
for(i=0;i<n;i++)
scanf("%d",&a[i]);
int max=a[0],min=a[0];
for(i=0;i<n;i++){
if(a[i]<a[0])
min=a[i];
if(a[i]>a[0])
max=a[i];
}
for(i=0;i<n;i++){
if(a[i]==max||a[i]==min)//
continue;
else
printf("%d",a[i]);
}
return 0;
}
4.合并有序数组为新数组
1 2 9 和3 4 5 6(指针)
1 2 9 1 2 9 1 2 9 1 2 9
3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6
新数组:1 2 3 4 5 6
已知两个升序数组,将它们合并成一个升序数组并输出。
例如:数组array1={3,6,13,35,54},数组array2={14,19,26,32},合并为新的数组array={3,6,13,14,19,26,32,35,54}。
输入格式:
输入两行升序整数,当每行输入0时,表示输入结束。每行整数的个数1<=N<=10。
输出格式:
输出合并后的升序数组。(最后一个数据后有一个空格)
#include <stdio.h>
int main(){
int a[10],b[10],c[20];
int num1,num2;
int m=0,n=0,t=0;
while(scanf("%d",&num1)==1&&num1!=0) //==1保证系统成功读取一个整数
a[m++]=num1;
while(scanf("%d",&num2)==1&&num2!=0) //只用一个num就够了,可删去num2
b[n++]=num2;
int i=0,j=0;
while(i<=m&&j<=n){
if(a[i]<=b[j]) //相同的数不会被漏掉
c[t++]=a[i++];
else
c[t++]=b[j++];
}
while(j<=n) //while(m>i)不可以,没有条件限制,死循环
c[t++]=b[j++];
while(i>=m)
c[t++]=a{i++];
for(int k=0;k<t;k++){
printf("%d ",c[k]);
}
printf("\n");
return 0;
}
5.字符查找
查找字符串(长度不超过100)中某字符最后一次出现的位置(下标)并输出,不存在则输出-1。
输入格式:
第一行输入一个字符串(可以包含空格)
第二行输入一个字符
输出格式:
一个整数
#include <stdio.h>
#include <string.h>
int main(){
char a[100];
char b;
int i=0,j;
while((a[i++]=getchar())!=EOF);//getchar函数不需要参数,!=优先级高于=
a[i]='\0';
b=getchar(); 或者 gets(a); //直接读取字符串
for(j=0;j<i,j++){ for(int i=0;a[i]!='\0';i++)
if(a[j]==b)
printf("%d",j);
}
if(i>j)
printf("-1");
return 0;
}
6.约瑟夫环问题
N 个人围成一圈,从第一个开始报数,第 M 个将出圈;然后继续报数,每到第 M 个就出圈,直到剩下 K 个人。
输入格式:
输入在一行中给出 N M K 的值,用空格隔开。输入保证数据都是正整数,并且 N > K 。
输出格式:
输出安全离开的出圈顺序。例如:N = 6, M = 5,K = 2,那么出圈顺序是5、4、6、2,剩余3、1。
1.数组法
#include <stdio.h>
void Joseph(int n,int m,int k){
int a[n];
int i=0,count=0,k=0;
//i用来遍历数组a中人的状态
//count用于统计退出人数
//k用来报数
for(i=0;i<n;i++)
a[i]=1;//1表示在圈里,0表示出圈
i=0;
while(count<=n-k){
if(a[i]){
k++;
if(k==m){
a[i]=0;//当前报数的人出圈
count++;//出圈人数加一
k=0; //重新报数
continue;//
}
i=(i+1)%n;//保证i的取值<n,也包含代码i++
}
}
for (i=0;i<n;i++){
if(a[i])
printf("%d ",i+1);
}
}
int main(){
int M,N,K;
scanf("%d %d %d",&N,&m,&K);
Joseph(N,M,K);
return 0;
}
7.一元二次方程
float x1,x2,disc,p,q; //无参函数要想对主函数中的值起作用,可通过全局变量
void greater_than_zero(float a,float b){
x1=(-b+sqrt(disc))/2*a;
x2=(-b-sqrt(disc))/2*a;
}
void equal_to_zero(float a,float b){
x1=x2=-b/2*a;
}
void smaller_than_zero(float a,float b){
p=-b/2*a;
q=sqrt(-disc)/2*a;
}
8.每个月的天数
本题要求实现一个简单函数,能计算给定的年份和月份的天数。其中1、3、5、7、8、10、12月有31天,4、6、9、11月有30天,2月平年有28天,闰年有29天。
输入样例:
2002
输出样例:
31 28 31 30 31 30 31 31 30 31 30 31
#include <stdio.h>
int MonthDays(int year, int month);
int main()
{
int ndays, month, year;
scanf("%d", &year);
for(month = 1; month <= 12; month++){
ndays = MonthDays(year, month);
printf("%d ", ndays);
}
return 0;
}
int MonthDays(int year, int month){
int days;
switch(month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days=31;
break;
case 4:
case 6:
case 9:
case 11:
days=30;
break;
case 2:
if((year%4==0&&year%100!=0)||year%400==0)
//逻辑运算符优先级低于算术运算符
//闰年:能被4整除但不能被100整除,或能被400整除
days=29;
else days=28;
break;
default days=0;
}
return days;
}
9.数字统计
输入一行字符,统计其中中英文字母、空格、数字和其他字符的个数
//用getchar()函数(遇到换行符'\n'结束)
//a~z:
12.统计一个整数的位数及各位数字(逆序输出)
#include <stdio.h>
int main(){
int n;
int t[100]; //数组统计各位数字
int weishu=0; //计数器
scanf("%d",&n);
if(n<0)
n=-n; //考虑负数情况
do{
t[weishu++]=n%10;
n/=10;
}while(n>0); //保证n=0时也正常运算
printf("一共有%d位",位数);
for(int i=0;i<weishu;i++)
printf("%d",t[i]);
return 0;
12.阿姆斯特朗数
阿姆斯特朗数(Armstrong number)是指一个n位正整数上各位数字的n次方之和等于这个数。特别的,当n=3时,又称水仙花数(Narcissistic number),特指一种三位数,其各位数字之立方和等于该数。请你写一个函数,判断一个正整数是不是阿姆斯特朗数。
int armstrong(int m){
int t[100]; //数组统计各位数字
int weishu=0;
do{
t[weishu++]=n%10;//注意位数是从0开算,
//但结果实际位数就是weishu,因为最后一步赋完值后weishi加一
n/=10;
}while(n>0);
int chengji=1,sum=0;
for(int i=0;i<weishu;i++){ //累加累乘
chengji=1; //i<weishu不加等号!!!
for(int j=0;j<weishu;j++){
chengji*=t[i]; //某位数字的位数的位数次方
}
sum+=chengji; //做加法
]
if(sum==m) //if语句亦可换成return sum==m?1:0 //sum==m成立取1,不成立取0
return 1;
else
return 0;
}
13.大整数阶乘
//算法:竖式乘法,小数放上面
4 0
x 1 2 3 4 5 6 7
2 8 0
2 4 0
2 0 0
1 6 0
1 2 0
8 0
4 0
4 9 3 8 6 8 0
要求实现一个打印较大非负整数阶乘的函数。
void print_factorial(int num){
if(num<0){
printf("Invalid input\n");
return;
}
int i,j;
int last=1; //位数
int a[100000]={0,1,0};//存放大数,从a[1]开始使用
for(i=1;i<=n;i++){ //
for(j=1;j<=last;j++){
a[j]*=i;
}
for(j=1;j<=last||a[j]!=0;j++){ //处理进位
a[j+1]+=a[j]/10;
a[j]%=10;
}
last=j-1;
}
printf(j=last;j>=1;j--){
printf("%d",a[j]);
}
}
13(1).对整数的冒泡排序
1.下标法
void bubbleSort(int a[],int c){
for(int i=0;i<c-1;i++){
for(int j=0;j<c-i-1;j++){
if(a[j]>a[j+1]){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
2.指针法
void bubbleSort(int *p,int c){
for(int i=0;i<c-1;i++){
for(int j=0;j<c-i-1;j++){
if(*(p+j)>*(p+j+1)){
int temp=*(p+j);
*(p+j)=*(p+j+1);
*(p+j+1)=temp;
}
}
}
}
13(2).对字符数组的冒泡排序
写一个函数,用冒泡法对输入的n个字符进行由小到大排序
void sort(char str[]){
int temp;
int n=strlen(str); //strlen函数求字符数组的长度
//使用前要加上#include <string.h>
for(int i=0;i<n-1;i++){
for(int j=0;j<n-1-i;j++){
if(str[j]>str[j+1]){
temp=str[j];
str[j]=str[j+1];
str[j+1]=temp;
}
}
}
}
14.字符串反序函数
指针移动法和下标法
1.指针移动法
void inverse(char str[]){
int len=strlen(str);
char temp;
char *left=str,*right=str+len-1;//别忘了减一;
//if不减一right定位的是'\0'
while(left<right){
temp=*left;
*left=*right;
*right=*temp;
left++;
right--;
}
}
2.下标法
void inverse(char str[]){
int len=strlen(str);
int mid=len/2;
char temp;
for(int i=0;i<mid;i++){
temp=str[i];
str[i]=str[i+len-1];
str[i+len-1]=temp;
}
}
15.字符串复制
strcpy函数
结构:strcpy(目标数组,源字符串);
不用strcpy函数:复制的核心是访问到s1中的每个字符,访问同时复制到s2中,最后添加结束符
#include <string.h>
void copy(char s2[],char s1[]){ //s1为源数组,s2为目标数组
int len=strlen(s1);
int i;
for(i=0;s1[i]!='\0';i++)
s2[i]=s1[i];
s2[i]='\0'; //添加结束符
}
16.字符串连接
(1).连接到源字符串
strcat函数
结构:strcat(目标字符串,源字符串);
不用strcat函数:先找到源字符串中‘\0’的位置,再逐个访问s2中的每一个字符并连接到s1中,最后添加结束符
void concatenate(char s1[],char s2[]){
int i,j;
for(i=0;s1[i]!='\0';i++); //得到连接的起始位置
for(j=0;s2[j]!='\0';j++)
s1[i++]=s2[j]; //连接过程别忘了每次循环i也要加一
s2[j]='\0'; //添加结束符
}
(2).连接后形成新的字符数组
1.下标法
void concatenate(char s1[],char s2[];char s[]){
int i,j;
for(i=0;s1[i]!='\0';i++) //得到连接的起始位置
s[i]=s1[i];
for(j=0;s2[j]!='\0';j++)
s[i++]=s2[j]; //连接过程别忘了每次循环i也要加一
s[j]='\0'; //添加结束符
}
2.指针法
void concatenate(char s1[],char s2[];char s[]){
int*p=s1,*q=s;
while(*p){
*q=*p;
p++;
q++;
}
p=s2;
while(*p){
*p=*q;
p++;
q++;
}
q='\0';
}
字符串输入函数:char s[20];
scanf("%s",s); //不需要&;遇空格、‘\0’会终止;
gets(s);
while((s[i]=getchar())!='\n') i++;
字符串输出函数:
printf("%s",s); //遇'\0'终止,遇空格不会终止
puts(s);
while(str[i]) putchar(str[i++]);
字符输入函数:char a;
scanf("%c",&a); //会读取空格
a=getchar(); //getchar函数无参数
字符输出函数:
printf("%c",a);
putchar(a);
17.计算二维数组每一行/列的和
下标法
void sum(int a[M][N]){
int i,j;
for(i=0;i<M;i++){
int hsum=0;
for(j=0;j<N;j++){
hsum+=a[i][j];
printf("第%d行数字之和为%d\n",i+1,hsum);
}
}
for(j=0;j<N;j++){
int lsum=0;
for(i=0;i<M;i++){
lsum+=a[i][j];
printf("第%d列数字之和为%d\n",j+1,lsum);
}
}
}
指针法
本题要求编写程序,使用指针方式求一个给定的m×n矩阵各行元素之和。(例如:scanf("%d", *(matrix + i) + j); // 使用指针方式访问二维数组元素)
输入格式:
输入第一行给出两个正整数m和n(1<=m<=6, 1<=n<=6),再输入m行数据,每行n个整数,每个整数之间用空格分隔。
输出格式:
输出m个整数,每行1个数。
#include <stdio.h>
int main(){
int m,n;
int i,j;
scanf("%d %d",&m,&n);
int matrix[m][n]; //if编译失败,可以换成matrix[6][6]
for(i=0;i<m;i++){
int sum=0;
for(j=0;j<n;j++){
scanf("%d",*(matrix+i)+j);
sum+=*((*matrix+i)+j);
}
printf("%d\n",sum);
}
return 0;
}
matrix:其实就是二维数组名,代表二维数组的首地址
matrix+i:第i行的起始地址
*(matrix+i):第i行起始地址存的数字
*(matrix+i)+j:第i行第j列元素的地址
*(*(matrix+i)+j):第i行第j列存的数字
18.二维数组每一行/列最值的差
void Fun(int a[M][N]){
int i,j;
for(i=0;i<M;i++){
int min=a[i][0],max=a[i][0];
for(j=1;j<N;j++){ //从1开始避免重复
if(max<a[i][j])
max=a[i][j];
if(min>a[i][j])
min=a[i][j];
}
printf("第%d行最大值与最小值的差为%d\n",i+1,max-min);
}
for(j=0;j<N;j++){
int min=a[0][j],max=a[0][j];
for(i=1;i<M;i++){ //从1开始避免重复
if(max<a[i][j])
max=a[i][j];
if(min>a[i][j])
min=a[i][j];
}
printf("第%d列最大值与最小值的差为%d\n",j+1,max-min);
}
}
19(1).删除字符串中的某个字符
原理:逐个访问字符数组,目标后字符覆盖目标字符,最后添加结束符‘\0’
//下标加函数法
void del(char s[],char n){ //从字符串s[]中删除字符n
int len=strlen(s);
int j=0;
for(int i=0;i<len;i++){
if(s[i]!=n)
s[j++]=s[i]; //未遇到目标字符时,j才加一,但i每次就循环都加一
}
s[j]='\0';
}
//不用strlen函数
void del(char s[],char n){
int i=0,j=0;
while(s[i]!='\0'){
if(s[i]!=n)
s[j++]=s[i];
i++;
}
s[j]='\0';
}
//指针写法
#include <stdio.h>
int main(){
char s[100];
gets(s);
char c;
while(getchar()!='\n');
c=getchar(); //保证getchar正确读入目标字符而非换行符
//当目标字符不是空格时亦可用scanf
char *p=s,*q;
while(*p!='\0'){
if(*p!=c){
*q=*p;
q++;
}
p++;
}
*q='\0';
puts(s);
return 0;
}
例题
输入一个正整数 repeat (0<repeat<10),做 repeat 次下列运算:
输入一个字符串 str,再输入一个字符 c,将字符串 str 中出现的所有字符 c 删除。
要求定义并调用函数delchar(str,c), 它的功能是将字符串 str 中出现的所有 c 字符删除,函数形参str的类型是字符指针,形参c的类型是char,函数类型是void。
#include <stdio.h>
void delchar(char *p,char *q,char c){
while(*p!='\0'){
if(*p!=c){
*q=*p;
q++;
}
p++;
}
*q='\0';
}
int main(){
int repeat;
scanf("%d",&repeat);
while(repeat--){ //实现多次输出
char str[100];
gets(c);
char c=getchar();
char*p=str,*q;
declear(p,q,c)
printf("result: ");
puts(str);
}
return 0;
}
19(2).删除字符串中指定下标的字符
编写一个函数,删除字符串s中从下标k开始的n个字符( n和k从键盘输入)
void delstring(char s[],int n,int k){
int i;
for(i=k;s[i+n]!='\0';i++) //删去从下标为k到k+n-1的这些字符
s[i]=s[i+n];
s[i]='\0';
}
19(3).删除字符串中的指定子串
strstr函数(字符串查找函数)
结构:char *p=strstr(源字符串,目标字符串)
结果:成功匹配到子串:返回字串第一次出现的起始地址,p!=NULL
未找到子串:返回NULL,p=NULL
字符串函数参数顺序区分
1.内存修改类(目标字符串在前,源字符串在后)
strcpy,strcat
2.查询/只读匹配类(源字符串在前,目标字符串在后)
strcmp,strstr,strlen
tip:使用前别忘了头文件#include <string.h>
20.数组循环右移
请你写一个函数实现功能为:一个数组a中存有n(>0)个整数,将每个整数循环向右移动m(0≤m≤n)个位置,即将a中的数据由(a0,a1...an−1)变为(an−m...an−1,a0,a1,an−m−1),即将数组最后m个数依次移动到最前面的m个位置。
原理:三次翻转:第一次翻转整体;第二次翻转an-1…an-m;第三次翻转an-m-1…a0
void reverse(int a[],int left,int right){
int temp;
while(left<right){
temp=a[left];
a[left]=a[right];
a[right]=temp;
left++;
right--;
}
}
void array_rshift(int a[], int n, int m){
reverse(a,0,n-1); //翻转整个数组
//直接a就行,不要写a[]
reverse(a,0,m-1); //翻转m个数(后m个数被翻转到前面)
reverse(a,m,n-1); //翻转n-m个数(前n-m个数翻转到后面)
}
21.函数指针做参数,实现两数的互换
#include <stdio.h>
void swap(int *x, int *y){
int temp;
trmp=*x;
*x=*y;
*y=temp;
}
int main(){
int m,n; //定义变量类型为整型,不能用指针
//指针变量是用来存数字的内存地址,本身不能直接存数字
scanf("%d %d",&m,&n);
swap(&m,&n); //swap函数参数可以传指针也可以传地址
printf("After swap:%d,%d",*m,*n);
return 0;
}
22.平均之上(多组测试数据)
输入一个整数n,再输入n个成绩,求大于平均分的成绩个数。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。
每组测试先输入n,表示数据个数,然后输入n个成绩(整数)。
输出格式:
对于每组测试,输出大于平均分的成绩个数。
#include <stdio.h>
int main(){
int T,n;
float ave;
scanf("%d",&T);
while(T--){ //每次循环为一组数据
float sum=0;
int flag=0;
scanf("%d",&n);
int a[n];
int *p;
for(p=a;p<a+n;p++){
scanf("%d",p);
sum+=*p;
}
ave=sum/n;
for(p=a;p<a+n;p++){
if(*p>ave)
flag++;
}
printf("%d\n",flag);
}
return 0;
}
23.指针法统计字符串中的空格数
输入一个字符串,统计其空格的数量。
要求编写函数 int count_sp(const char *s);
统计并返回字符串 s 中空格的数量。
输入格式:
在一行中输入一个长度不超过 80 的字符串,其中可能含有多个空格。
输出格式:
输出共 2 行:第一行打印输入的原字符串,第二行是该字符串中空格的数量。
#include <stdio.h>
int count_sp(const char *p){ //const作用为防止误改字符
//删掉对本代码功能无影响
int count=0;
while(*p!='\0'){
if(*p==' ')
count++;
p++;
}
return count;
}
int main(){
char s[80];
gets(s);
puts(s); //puts输出字符串自动换行
printf("%d",count_sp(s));
return 0;
}
24.利用指针返回多个函数值
读入n个整数,调用max_min()函数求这n个数中的最大值和最小值。
输入格式:
输入有两行:
第一行是n值;
第二行是n个数。
输出格式:
输出最大值和最小值。
#include <stdio.h> //头文件要放在最前面
void max_min(int a[],int n,int *max,int *min){
//指针的目的是将最大值和最小值传回主函数中
//指针参数所在位置,填写实参时可以是地址&…
//定义函数参数时,不能用int a[n]
*max=a[0];*min=a[0]; //必须要初始化:使用数组第一个元素作为初始值
for(int i=1;i<n;i++){
if(*max<a[i])
*max=a[i];
if(*min>a[i])
*min=a[i];
}
}
int main(){
int n;
scanf("%d",&n);
int a[n];
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int max,min; //注意不要定义成指针
max_min(a,n,&max,&min);
printf("max = %d",max);
printf("min = %d",min);
return 0;
}
25.矩阵转置(指针)
二维数组扁平化:a[m][n];int *p=a;
a[i][j]=*(p+i*n+j);
(1)方阵
定义一个3X3的整形矩阵,函数void move(int *pointer)采用指针方式实现矩阵转置。
输入格式:
例如定义一个二维数组接受3X3的整形矩阵数据。
#include <stdio.h>
void move(int *pointer){
for(int i=0;i<3;i++){
for(int j=i+1;j<3;j++){ //只交换上三角
int temp=*(p+i*3+j); //相当于temp=a[i][j]
*(p+i*3+j)=*(p+j*3+i); //相当于a[i][j]=a[j][i]
*(p+j*3+i)=temp; //相当于a[j][i]=temp
}
}
}
int main(){
int a[3][3];
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
scanf("%d",a[i][j]);
}
int *p=a;
move(p);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
printf("%d",a[i][j]);
if(j!=2)
printf(" "); //避免多余的空格
}
if(i!=2)
printf("\n"); //避免多余的换行
}
return 0;
}
(2)普通矩阵
定义新数组存放转置后的元素
核心:b[j][i]=a[i][j]
26.大小字符转换
用函数和指针将给定字母字符串的第一个字母变成大写字母,其它字母变成小写字母。在main函数中接收字符串的输入,改变后的字符串的输出也在main函数中实现。
#include <stdio.h>
void trans(char *p){
if(*p>='a'&&*p<='z') //首字母大写
*p-=32;
p++;
while(*p!='\0'){
if(*p>='A'&&*p<='Z') //其他字母小写
*p+=32;
p++;
}
}
int main(){
char s[100];
gets(s);
trans(s);
puts(s);
return 0;
}
27.指定子序列逆序
设有一数列,包含10个数,已按升序排好。现要求编一程序,它能够把从指定位置开始的n个数按逆序重新排列并输出新的完整数列,进行逆序处理时要求使用指针方法。
输入格式:
输入包括两行。
第一行输入10个整数n,以空格分隔数字。(1≤n≤10000)
第二行输入逆序开始的位置和数量。
输出格式:
输出处理后的10个数字,以空格分隔数字。
#include <stdio.h>
void reverse(int *p,int m,int n){
int *left=p+m-1;
int *right=p+m+n-2;
while(left<right){
int temp=*left;
*left=*right;
*right=temp;
right--;
left++;
}
}
int main(){
int a[10];
int m,n;
for(int i=0;i<10;i++)
scanf("%d",&a[i]);
scanf("%d %d",&m,&n);
reverse(a,m,n);
for(int i=0;i<10;i++)
printf("%d ",a[i]);
return 0;
}
28.(1)找最大数
输入n个数,输出最大数值
#include <stdio.h>
int main(){
int n,max,a;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",a);
if(i==0)
max=a; //max=a使得后面的数都和第一个数比
if(a>max)
max=a;
}
printf("Max is %d",max);
return 0;
}
(2)找最大的字符串
输入n个字符串,输出其中最大的字符串。
#include <stdio.h>
#include <string.h>
int main(){
int n;
scanf("%d",&n);
char s[100];
char max[100];
for(int i=0;i<n;i++){
gets(s); //scanf("%s",s);
if(i==0)
strcpy(max,s);
if(strcmp(s,max)>0) //函数结果>0表示前者大,=0表示相等,<0表示后者大
strcpy(max,s);
}
puts(max);//printf("%s",max);
return 0;
}
29.字符串排序
输入格式:
n 表示n个字符串
n行,n个字符串
输出格式:
排序后的n个字符串
#include <stdio.h>
#include <string.h>
int main(){
int n;
scanf("%d",&n);
char temp[100];
char s[n][100]; //s2[0],s2[1]和s1地位一样
//都可以看作存放字符串的一维数组
for(int i=0;i<n;i++)
scanf("%s",s[i]); //gets(s[i]);
for(int i=0;i<n-1;i++){
for(int j=0;j<n-i-1;j++){
if(strcmp(s[j],s[j+1])>0){ //冒泡排序
strcpy(temp,s[j]);
strcpy(s[j],s[j+1]);
strcpy(s[j+1],temp);
}
}
}
for(int i=0;i<n;i++)
printf("%s\n",s[i]);
return 0;
}
30.折半查找法
low=0、high=最后一个元素的下标、mid=(low+high)/2
所给数x:判断x和mid所指数的大小,若x>mid,则令low=mid+1;若x<mid,则令high=mid-1;
按照由小到大的顺序输入15个整数,放在一个整型数组a[15]中,然后另起一行输入一个整数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出“cannot find xxx”。
输入格式:
在一行中输入15个整数,中间以空格分隔;另起一行输入一个任意数
输出格式:
如果该数在数组中,则输出"Has found xx, its position is xx"
如果该数不在数组中,则输出“Cannot find xx”
#include <stdio.h>
int main(){
int a[15];
for(int i=0;i<15;i++)
scanf("%d ",a[i]); //printf("\n");不用加
int x;
scanf("%d",x);
int low=0,high=14,mid;
int flag=-1;
while(low<=high){
mid=(low+high)/2; //不能放在循环外
if(x==a[mid]){
flag=1;
break; //得到结果及时跳出
}
else if(x<a[mid])
high=mid-1;
else
low=mid+1;
}
if(flag==1)
printf("Has found %d, its position is %d",x,mid+1);
else
printf("Cannot find %d",x);
return 0;
}
31.选择排序
原理:选择一个指定位置的元素,依次与后面的元素进行比较,如果指定位置元素大,则交换;
指定位置分别为第1个、第2个……第n-1个
void sort(int a[],int n){
for(int i=0;i<n-1;i++){
for(int j=i+1;j<n;j++){
if(a[i]>a[j]){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}
32.(1)从字符串中提取数字
#include <stdio.h>
int main(){
char s1[100],s2[100];
gets(s1);
char *p=s1,*q=s2;
while(*p!='\0'){
if(*p>='0'&&*p<='9'){
*q=*p;
q++;
}
p++;
}
*q='\0';
q=s2; //指针归位
while(*q!='\0'){
printf("%c",*q); //注意是%c
q++;
}
return 0;
}
(2)从字符串中提取连续数字
输入一个字符串,内有数字和非数字字符,例如:a123x67 222y35i088 09x8 c,请编写程序,将其中连续的数字作为一个整数,依次存放到一维数组a中。例如前面的字符串,应将123存放到a[0]中,67存放到a[1]中……,最后输出整数的个数以及各个整数的值。
输入格式:
长度不超过100的一个字符串,其中包含整数字符和非整数字符。
输出格式:
第一行输出整数的个数
第2行输出各个整数的值,以空格间隔,最后一个整数后面没有空格。
#include <stdio.h>
int main(){
char s1[120];
int num[120]={0};
gets(s1);
char *p=s1;
int *q=num;
int count=0;
while(*p!='\0'){
while(!(*p>'0'&&*p<'9')&&*p!='\0')
p++;
while((*p>'0'&&*p<'9')&&*p!='\0'){
*q=(*q+*p-'0')*10;
p++;
}
*q/=10;
q++;
count++;
}
q=num;
for(int i=0;i<count;i++){
printf("%d",*q++);
}
return 0;
}
33.结构体生肖统计
春节至,亲朋好友聚会忙,聚会之人有时会说到自己的生肖。对于给定的若干人的生肖,请统计各种生肖的人数,并按人数从多到小输出各种出现的生肖及其人数。若有多种生肖的人数相同,则按生肖英文单词(详见最后的提示)的字典序输出。
输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试先输入1个整数n(1<=n<=100)表示聚会人数,再输入n个字符串(长度不超过7且仅包含小写字母),每个字符串表示一个人的生肖。
输出格式:
对于每组测试,按描述要求输出结果,每种出现的生肖及其人数占一行,每行的两个数据之间以一个空格间隔。每两组测试数据之间留一个空行。
#include <stdio.h>
#include <string.h>
struct shengxiao{
char name[20];
int count;
};
int main(){
int T;
scanf("%d",&T);
while(T--){ //每组作为一次循环
int n,len=0; //len表示不重复生肖的长个数
scanf("%d",&n);
struct shengxiao a[100]; //结构体数组存放生肖
for(int i=0;i<n;i++){
char s[20];
scanf("%s",s);
int flag=0;
for(int j=0;j<len;j++){
if(strcmp(a[j].name,s)==0){ //数组中找到输入生肖
a[j].num++,
flag=1;
break;
}
if(flag==0){ //未找到输入生肖就存入
strcpy(a[len].name,s);
a[len].num=1; //刚存入num=1,不能++,会变成随机垃圾值
len++:
}
}
}
for(int i=0;i<len-1;i++){
for(int j=0;j<len-i-1;j++){
if(a[j].num<a[j+1].num){ //冒泡排序
struct shengxiao t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
else if(a[j].num==a[j+1].num){
if(strcmp(a[j].name,a[j+1].name)>0){
struct shengxiao t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
for(int i=0;i<len;i++)
printf("%s %d\n",a[i].name,a[i].num);
}
return 0;
}
或者以while (scanf("%d", &n) != EOF)作为结束多组数据输入的依据
34.结构体计算总分及最高分
本题目要求先输入正整数N,然后输入N个类型为结构体stud的数组元素,计算每个学生的总分,输出每个学生的学号、姓名、三门课的成绩及总分;计算全部成绩的平均分并输出;输出总分最高同学的各项信息。
struct stud {
int num; //学号
char name[10]; //姓名
int score[3]; //3门课成绩
int sum; //总分
};
输入格式:
先输入不超过10的一个正整数N,然后每行输入一个学生的信息(学号、姓名、三门课成绩)。学号在整数范围内,姓名长度小于10个字符。
输出格式:
首先输出每个学生的信息(包括学号、姓名、三门课成绩、总分),数据项之间空1格,每人一行;再输出全部成绩的平均分;最后输出总分最高(假设没有相同总分)同学的学号、姓名、三门课成绩及总分,数据项之间空1格。
#include <stdio.h>
struct stu{
int num;
char name[10];
int score[3];
int sum;
};
int main(){
int N,i,flag;
float all_sum=0;
scanf("%d",&N);
struct stu a[10];
for(i=0;i<N;i++){
scanf("%d %c ",&a[i].num,a[i].name);
scanf("%d %d %d %d ",&a[i].score[0],&a[i].score[1],&a[i].score[2]);
a[i].sum=a[i].score[0]+a[i].score[1]+a[i].score[2];
all_sum+=a[i].sum;
if(i==0)
flag=i;
else{
if(a[flag].sum<a[i].sum)
flag=i;
}
}
float ave=all_sum/(N*3);
for(i=0;i<N;i++){
printf("%d %c ",&a[i].num,a[i].name);
printf("%d %d %d %d ",a[i].score[0],a[i].score[1],a[i].score[2]);
printf("%d",a[i].sum);
printf("\n");
}
printf("总平均分=%f",ave);
printf("%d %c ",&a[flag].num,a[flag].name);
printf("%d %d %d %d ",a[flag].score[0],a[flag].score[1],a[flag].score[2]);
printf("%d",a[flag].sum);
}
2693




被折叠的 条评论
为什么被折叠?



