课外闲谈1.谈一谈最近自己遇到的比较不错的题目(C语言)

简介: 课外闲谈1.谈一谈最近自己遇到的比较不错的题目(C语言)

我现在写的是从头开始,比较经典,难以理解的一些题目。


1.求1-1/3+1/5-1/7+......+1/n;


#include<stdio.h>
int main(){
  int flog,i,f,n;
  double item,sum;
  printf("请输入n的值:");
  scanf("%d",&n);
  flog=1;
  f=1;
  sum=0;item=1;
  for(i=1;i<=n;i++)
  {
  sum=sum+item;
  flog=-flog;
  f=f+2;
  item=flog*1.0/f;}
  printf("sum=%f",sum);
  return 0;
} 


2.


abd8eca846ed4063b8b1f2ddfa61651d.png


3.输出图形


#include<stdio.h>
int main()
{
  int i,j;
  for(i=1;i<=5;i++)
  {
    for(j=4;j>=i;j--)
    printf(" ");
    for(j=1;j<=i;j++)
    printf("*");
    putchar('\n');
  }
  return 0;
}


4.逆序输出


#include<stdio.h>
int main(){
  int x;
  printf("请输入一个逆序的整数:");
  scanf("%d",&x);
  printf("正序为:"); 
  do{
    printf("%d",x%10);//每当一个数%10时,结果都为最后一位数值。 
    x=x/10;//每当一个数/10时,都会去掉最后一位数值。 
  }while(x!=0);
  return 0;
}
bool symm(long m){
  long temp = m,n=0;
  while (temp){
    n = n*10+temp%10;
    temp = temp/10;//逆序输出数
  }
  return (m == n);
}


5.证明哥德巴赫思想


#include<stdio.h>
#include<math.h>
int main(){
  int x,y,i,n;
  printf("请输入一个数:");
  scanf("%d",&n);
  for(x=2;x<=n/2;x++){
    //定义一个x,属于2~n/2。两个数相加,必有一个大于二分之n另一个则小于二分之n
    for(i=2;i<=sqrt(x);i++){//判断x是否为素数
      if(x%i==0)
      break;
    }
     if(i>sqrt(x)){
      y=n-x;
      for(i=2;i<=sqrt(y);i++){//判断y是否为素数。 
        if(y%i==0)
        break;
       }
          if(i>sqrt(y))
          printf("%d+%d=%d\n",x,y,n);
     }      
  }
  return 0;
}
/*判断一个数是否为素数
假设有数x,
 for(i=2;i<=sqrt(x);i++){
   if(x%i==0)   
    break;  
     if(i>sqrt(x))
      printf("这是一个素数!");
   }
*/ 


6.斐波那契数列问题


#include<stdio.h>
int main(){
  int i,n,x1,x2,x;
  printf("请输入n:");
  scanf("%d",&n);
  if(n<1||n>46){//据题目限定,超出此范围则无效。
    printf("Invalid.\n");
  }
     else if(n==1)
          printf("%10d",1);
      else{
        x1=1;
          x2=1;
          printf("%10d%10d",x1,x2);
      for(i=3;i<=n;i++){
        x=x1+x2;
        printf("%10d",x);
        if(i%5==0)
        printf("\n");
        x1=x2;
          x2=x;
      }
    }
  return 0;
} 


#include<stdio.h>
#define MAXN 46//定义在最上面,需要更改时便只需改这一个地方。 数组都可以如此,更方便 
int main(){
  int i,n;
  int fib[MAXN]={1,1};//先输出前两项 
  printf("请输入n:");
  scanf("%d",&n);
  if(n>=1&&n<=46){
    for(i=2;i<n;i++){//i=2,是因为,数组从零开始,i=2时,其实是第三项 
      fib[i]=fib[i-1]+fib[i-2];//前一项等于后两项之和 
    }
    for(i=0;i<n;i++){
      printf("%6d",fib[i]);
    if((i+1)%5==0)
      printf("\n");
    }
      if(n%5!=0)
        printf("\n");
  }
  else
    printf("Invalid Value!\n");
  return 0;
} 


7.数学思维问题


#include<stdio.h>
int main(){
  int x,men,women,cnt,n;
  printf("请输入n:");
  scanf("%d",&n);
  cnt=0;
  for(men=0;men<=n;men++){
    for(women=0;women<=n;women++){
      for(x=0;x<=n;x++){
        if((men+women+x==n)&&(men*3+women*2+x*0.5==n))
        printf("men=%d,women=%d,x=%d\n",men,women,x);
        cnt++;
      }
    }
    if(cnt==0)
  printf("None!\n");//未经过循环,即无方案。 
  }
  printf("cnt=%d",cnt);//count的缩写,代表循环的次数。97336 
  return 0;
} 


125fc68108d64773b0f1e8600f70dd07.png


8.a与b中找不同


#include<stdio.h>
#define N 10
int main(){
  int m,n,i,j,k,a[N],b[N],c[2*N],flag=0;
  printf("请输入一个数:");
  scanf("%d",&m);
  printf("请输入%d个数据:",m);
  for(i=0;i<m;i++){
    scanf("%d",&a[i]);//初始化a数组 
  }
    printf("请输入一个数:");
  scanf("%d",&n);
  printf("请输入%d个数据:",n);
  for(i=0;i<n;i++){
    scanf("%d",&b[i]);//初始化b数组 
  }
  for(i=0;i<m;i++){
    for(j=0;j<n;j++){
      if(a[i]==b[j])
      break;//将a数组中的元素拿出与b数组中的元素比较 
    }
    if(j>=n){
    flag=1;
    c[k++]=a[i];//如果是正常循环结束,则表明a中的元素无与b中相同的元素 ,且flag=1 
  }
  } 
  for(j=0;j<n;j++){
    for(i=0;i<m;i++){
      if(b[j]==a[i])
      break;
    }
    if(i>=m){
    flag=1;
    c[k++]=b[j];//b也要与a比较 
    }
  }
  for(i=0;i<k;i++)
  printf("%d ",c[i]);
  if(flag==0)
  printf("No found!");//避免两数组无非公有元素而无操作 
  return 0;
}


9.日期计算


#include<stdio.h>
#define MAXN 8
int main(){
  int i,n,response;
  int count[MAXN+1];//实际问题是以1开头的,所以定义一个更长的,其实也可以在宏定义时定义更长的 
  printf("请输入n:");
  scanf("%d",&n);
  for(i=1;i<=MAXN;i++)
  count[i]=0;//数据的初始化,避免该存储单元之前的数据影响 !!!!!!! 
  for(i=1;i<=n;i++){
    printf("Enter your response:");
    scanf("%d",&response);
    if(response>=1&&response<=MAXN)
    count[response]++;//等价于count[response]+=1. 上面已经初始化过了,所以出现一次就会累加一次 
    else
      printf("Invalid:%d\n",response);
  }
  printf("result:\n");
  for(i=1;i<=MAXN;i++){
    if(count[i]!=0)
    printf("%4d%4d\n",i,count[i]);
  }
  return 0;
} 


10.压缩字符串


#include<stdio.h>
#define MAXN 80
void zip(char *p);
int main(){
  char line[MAXN];  
  printf("Input the string:");
  gets(line);
  zip(line);
  puts(line);
  return 0;
}
void zip(char *p){
  char *q=p; 
  int n;
  while(*p!='\0'){
    n=1;
    while(*p==*(p+n)){
      n++;
    }
    if(n>=10){
      *q++=(n/10)+'\0';
      *q++=(n%10)+'\0';
    }
    else if(n>=2){
      *q++=n+'\0';
    }
    *q++=*(p+n-1);
    p+=n;
  }
  *q='\0';
}


11.正序输出整数(递归)


//正序输出数字 
void print(unsigned int num ){
  //递归 
  if(n>9){
    print(n/10);
  }//反复调用此自定义函数,直到n<=9,首先输出n<=9时的数,因为n<=9时函数最先调用完,其次就是它的上一层调用,妙呀 
  printf("%d",n%10);
  //数组 
}
#include<stdio.h>
int main(){
  unsigned int num=0; 
  scanf("%u",&num);
  print(num);
  return 0;
} 


12.移动字母(把字符串的前三个移动到最后)


#include <stdio.h>
#include <string.h>
void Shift( char s[] ){
  getchar();
  int a[3];
  int i,j;
  for(i=0;i<3;i++){
    a[i]=s[i];
  }
  for(i=3;s[i];i++){
    s[i-3]=s[i];
  }
  for(j=i-3,i=0;i<3;i++){
    s[j++]=a[i];
  }
}
/*void Shift( char s[] ){
  char temp[MAXN];
  int len=strlen(s);
  strcpy(temp,s);
  for(int i=0;i<len;i++)
  s[i]=temp[(i+3) % len];//数组左移都能用这套。 
}*/ 
#define MAXS 10
void Shift( char s[] );
void GetString( char s[] ); /* 实现细节在此不表 */
int main()
{
    char s[MAXS];
    GetString(s);
    Shift(s);
    printf("%s\n", s);
    return 0; 
}
/*void Shift( char s[] )
{
    char str1[4],str2[MAXS];
  strncpy(str1,s,3);   //将前三个字符复制到str1中
  strcpy(str2,s+3);    //将剩余的字符复制到str2中
  strcat(str2,str1);   //连接
  strcpy(s,str2);      //复制到s中
}*/


13.模拟实现qsort函数


//模拟实现qsort函数
#include<stdio.h>
//交换函数(也可以不单独写成函数,但是我觉得主要可读性更好)
void swap(char* buf1, char* buf2,size_t width) {
  int i;
  for (i = 0; i < width; i++) {
    char temp = *buf1;
    *buf1 = *buf2;
    *buf2 = temp;
    buf1++;
    buf2++;
  }
}
//写qsort必须写的函数,必须由使用者写,虽然我们这里是模拟实现qsort函数,但是仍需要写这个。
int compare(const void* e1, const void* e2) {
  //根据返回值进行排序(来绝对是升序还是降序)
  return *(char*)e1 - *(char*)e2;
}
void bubble_sort(void* base, size_t sz, size_t width, int (*compare)(const void*, const void*)) {
  int i, j;
  //外层循环控制总趟数
  for (i = 0; i < sz-1; i++) {//这里一定是sz减一,sz是数组长度,下标只能到sz-1;
    for (j = 0; j < sz - i- 1; j++) {
      //这个地方是妥妥的重点了,为什么要强制类型转换为char* 类型?
      //其实这个地方我觉得转换为其他类型也行,但是qsort函数是可以对所有数据类型进行排序的,如果只是对单一的一种数据排序,那的确是可以的
      //但是我们这里是模拟实现qsort函数的功能,故,我们这里转换为char* 类型
      //还有一个原因,char*类型的指针解引用时只走一个字节,众所周知,字节是代码的最小存储单位了,其他无论什么类型的数据都是以字节论的
      if (compare((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
        swap(((char*)base + j * width), ((char*)base + (j + 1) * width),width);
      //我们再来理解一下这个(char*)base + j * width是什么意思呢?
      //首先这个char*我是已经将过了的,接下来我们要解释的就是j*width的含义
      //因为我们对未知类型的数据进行排序,(int*)+1是走四个字节,但对它本身来说就只移动了一个元素长度
      //那如果是(int*)+i呢?我们是不是就可以理解为从头开始往后面走了i个元素,拿这个例子与上面一对比,这就十分明确了
      //j*width的意思就是待排序数据一个元素所占用的长度,也就是往后面移动了一位。
    }
  }
}
int main() {
  int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
  bubble_sort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), compare);
  int i = 0;
  for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
    printf("%d",arr[i]);
  }
  printf("\n");
  char arr1[] = "hello world";//这里我准备了两个例子供大家参考
  bubble_sort(arr1, sizeof(arr1) / sizeof(arr1[0]), sizeof(arr1[0]), compare);
  for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
    printf("%c",arr1[i]);
  printf("\n");
  return 0;
}


14.模拟实现计算器


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void menu(void) {
  printf("************请选择****************\n");
  printf("******1.Add*********2.Sub*********\n");
  printf("******3.Mul*********4.Div*********\n");
  printf("************0.exit****************\n");
  printf("**********************************\n");
}
int Add(int x, int y) {
  return x + y;
}
int Sub(int x, int y) {
  return x - y;
}
int Mul(int x, int y) {
  return x * y;
}
int Div(int x, int y) {
  return x / y;
}
int main() {
  //这里并没有用switch结构,这里跟第一个程序不同,上一个程序中input定义在了switch外面,所以没啥问题
  //但是在这里,函数的主体就只有一个循环,由于我们用的是do-while循环,最后while后面的input是在循环体外面的,
  //如果在里面定义input的话,作用域就到不了外面,故,我们把input定义在外面。
  int input = 0;
  do {
    //这里我们采用函数指针数组的方法。
    int (*parr[5])(int, int) = { NULL,Add,Sub,Mul,Div };
    int x, y, ret;
    x = y = ret = 0;
    //输出菜单
    menu();
    //选择方法
    printf("请选择:>");
    scanf("%d", &input);
    if (input >= 1 && input <= 4) {
      //初始化数据
      printf("请输入2个操作数:");
      scanf("%d%d", &x, &y);
      //用函数指针的方法,用指针调用函数
      ret = (parr[input])(x, y);
      printf("ret =%d\n", ret);
    }
    else if (input == 0)
      printf("程序结束。");
    else
      printf("选择错误,请重新选择\n");
  } while (input);
  return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void menu(void) {
  printf("************请选择****************\n");
  printf("******1.Add*********2.Sub*********\n");
  printf("******3.Mul*********4.Div*********\n");
  printf("************0.exit****************\n");
  printf("**********************************\n");
}
int Add(int x, int y) {
  return x + y;
}
int Sub(int x, int y) {
  return x - y;
}
int Mul(int x, int y) {
  return x * y;
}
int Div(int x, int y) {
  return x / y;
}
int Calc(int(*pf)(int, int)) {
  int x, y;
  x = y  = 0;
  printf("请输入两个操作数:");
  scanf("%d%d",&x,&y);
  return pf(x, y);
}
int main() {
  int input=0;
  menu();
  printf("请选择:>");
  scanf("%d",&input);
  do {
    switch (input) {
    case 1:
      printf("ret=%d\n",Calc(Add));
    case 2:
      printf("ret =%d\n",Calc(Sub));
    case 3:
      printf("ret=%d\n", Calc(Mul));
    case 4:
      printf("ret=%d\n", Calc(Div));
    case 0:
      printf("退出程序");
    default:
      printf("请重新选择:");
    }
  } while (input);
  return 0;
}
/*其实这个地方就是一个回调函数的方法,首先,我们要清楚回调函数的作用和定义,回调函数就是在b函数调用a函数,
那么回调函数的作用是什么呢?就是在有多个函数选择时,我们可以另外定义一个函数,这个函数就是就是回调函数了,
回调函数的参数就是一个函数指针,这个指针便可以接收函数了,因为指针并没有指向,所以这个指针可以接收任意一个函数、
这就是回调函数。*/


15.建立一个有N个学生信息数据的链表

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define N 4
struct student {
  //数据域
  int num;
  char name[20];
  char sex;
  int score;
  //指针域
  struct student* next;
};
int main() {
  //定义指针变量
  struct student* head, * p, * q;
  //定义结点大小
  p = (struct student*)malloc(sizeof(struct student));
  //初始化结点
  scanf("%d%s%c%d",&p->num,p->name,&p->sex,&p->score);
  //将第一个结点的地址给head。
  head = p;
    head->next=NULL;
  //用一个for循环,初始化所有的结点,即整个链表。
  for (int i = 0; i < N; i++) {
    //要重新定义第二个结点,然后初始化
    q = (struct student*)malloc(sizeof(struct student));
    scanf("%d%s%c%d", &q->num, q->name, &q->sex, &q->score);
    //让前一个结点的指针域指向下一个结点的地址
    p->next = q;
    //再让p指向已定义好的结点,q指针继续去处理下一个结点。
    p = q;
  }
  //循环结束后,最后一个结点的指针域为空。
  p->next = NULL;
  //用一个for循环输出所有结点中的信息
  for (p = head; p; p = p->next) {
    printf("%d %s %c %d\n",p->num,p->name,p->sex,p->score);
  }
  return 0;
}


16.输出平均分最高的学生信息


#define _CRT_SECURE_NO_WARNINGS 1
//输出平均分最高的学生信息
#include<stdio.h>
struct student {
  int num;
  char name[10];
  int computer, english, math;
  double average;
};
int main() {
  int i, n;
  //定义结构变量
  struct student max, stu;
  printf("Input n:");
  scanf("%d",&n);
  printf("Input the student's information:");
  //这里与已知长度和数据的数组的选择法排序不同,这里数据都是未知的。
  for (i = 1; i <= n; i++) {
    printf("NO.%d:",i);
    scanf("%d%s%d%d%d",&stu.num,stu.name,&stu.math,&stu.english,&stu.computer);
    stu.average = (stu.math + stu.english + stu.computer) / 3.0;
    if (i == 1) {
      max = stu;
    }
    else if (max.average < stu.average)
      max = stu;
  }
  printf("num:%d,name:%s.average:%2lf\n",max.num,max.name,max.average);
  return 0;


17.链表的比较及排序


#define _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>
#include<stdlib.h>
#define N 10
struct student {
  int num;
  int score;
  struct student* next;
};
int main() {
  struct student* head, * p, * q, * k;
  k = (struct student*)malloc(sizeof(struct student));
  //以后内存函数的使用都要判断一下,是否开辟成功,如果未开辟成功,则结束进程
  if (!k)
    exit(1);
  scanf("%d%d",&k->num,&k->score);
  //初始化第一个结点,因为结点是不连续的,仅仅是靠指针域中的地址来进行联系,所以,这既是第一个结点,也是最后一个结点,对指针域进行初始化
  k->next = NULL;
  head = k;
  //接下来对后面的N-1个结点进行定义初始化
  //这一整个片段是很关键的一环,写的是真的好,主要是我没见过
  for (int i = 1; i < N; i++) {
    k = (struct student*)malloc(sizeof(struct student));
    //判断语句
    if (!k)
      exit(1);
    scanf("%d%d", &k->num, &k->score);
    //让p指向第一个结点
    p = head;
    q = NULL;
    //此时的while起一个比较的作用(升序)
    while (p && (p->num <= k->num)) {
      q = p;
      p = p->next;
    }
    if (p == head) {
      k->next = head;
      head = k;
    }
    else {
      k->next = q->next;
      q->next = k;
    }
  }
  /*首先,让p指向第一个结点,k指向的是第二个结点,二者相比较,如果k指向的结点大于p指向的,先把初始结点的地址给q,p就指向下一位,
  执行else语句。即在q指向的结点后面插入k指向的结点。
  如果p指向的结点数据大于k指向的结点数据,则将k指向的结点插到第一个结点前面,也就是插到相比较结点的前面。
    交换完数据以后,利用for循环再次重新定义一个新节点,再次进行比较。
  */
    free(k);//一定要记得释放申请的内存
  //输出整个的链表
  for (p = head; p; p = p->next) {
    printf("%d  %d\n", p->num,p->score);
  }
  return 0;
}


18.建立链表,查找值为x的结点并删除这个结点,x的值从键盘输入


#define _CRT_SECURE_NO_WARNINGS 1
//建立链表,查找值为x的结点并删除这个结点,x的值从键盘输入。
#include<stdio.h>
#include<stdlib.h>
//先定义结构体类型
struct node {
  int date;
  struct node* next;
};
//函数声明
struct node* create_number(int);
struct node* find(struct node *, int);
struct node* Delete(struct node *, struct node * );
void out_list(struct node*);
int main() {
  //建议还是初始化一下
  struct node* head=NULL, * p=NULL;
  int n, x;
  n = x = 0;
  printf("Create List,Enter n:");
  scanf("%d", &n);
  head = create_number(n);
  printf("List:");
    out_list(head);
  printf("x:");
    scanf("%d", &x);
    p = find(head, x);
    head = Delete(head, p);
    printf("Result:");
    out_list(head);
  return 0;
}
//创造结点的函数
struct node* create_number(int n) {//n代表准备创造结点的个数
  //创造结点时,至少需要三个指针变量,head固定在首结点,p和k用于创造新结点
  int i;
  struct node* head=NULL, * k=NULL, * p=NULL;
  if (n < 1) {
    return NULL;
  }
  else {
    k = (struct node*)malloc(sizeof(struct node));
    //判断是否申请成功
    if (!k)
      exit(1);
    k->date = 1;//初始化第一个数据
    //第一个结点,也是最后一个,这个操作相当于给指针域初始化
    k->next = NULL;
    head = k;
    p = k;
    for (i = 2; i <= n; i++) {
      k = (struct node*)malloc(sizeof(struct node));
      if (!k)
        exit(1);
      k->date = i;
      //初始化
      k->next = NULL;
      p->next = k;
      p = k;
    }
    return head;
  }
}
//查找函数
struct node* find(struct node* head, int x) {//头指针和待查找的元素
  //另外定义一个指针去遍历,从而保证head指针不被改变
  struct node* p = head;
  while (p && p->date != x) {
    p = p->next;
  }
  if (!p)
    return NULL;
  else
    return p;
}
//删除函数
struct node* Delete(struct node* head, struct node* p) {
  struct node* q;
  if (!p)
    return head;
  //如果p不为空,判断p指向结点的位置,从而进行删除操作
  if (p = head)
    head = head->next;
  else {
    q = head;
    while (q->next != p)
      q = q->next;
    q->next = p->next;
  }
  //别忘了释放空间
  free(p);
  return head;
}
//输出函数
void out_list(struct node* head) {
  //另外定义变量去遍历
  struct node* p;
  if (!head) {
    p = head;
    while (!p) {
      printf("%d", p->date);
      p = p->next;
    }
  }
  else
    printf("不存在\n");
  putchar('\n');
}


19.有序表的增删查操作(这个题目用了比较少见的全局变量)


#define _CRT_SECURE_NO_WARNINGS 1
//有序表的增删查操作
#include<stdio.h>
#define MAXN 100
//***用全局变量count来表示数组a中待处理的元素个数
int count = 0;
//决定对有序数组a进行何种操作的控制函数
void select(int a[], int option, int value);
//输入有序数组
void input_array(int a[]);
//输出有序数组
void print_array(int a[]);
//在有序数组a中插入一个值为value的元素
void insert(int a[], int value);
//删除有序数组中等于value的元素
void remove(int a[], int value);
//用二分法查找等于value的元素
void query(int a[], int value);
int main() {
  int option, value, a[MAXN];
  input_array(a);
  //显示菜单
  printf("[1] Insert\n");
  printf("[2] Delete\n");
  printf("[3] Query\n"); 
  printf("[Other option] End\n");
  while (1) {
    printf("Input option:");
    scanf("%d", &option);
    if (option < 1 || option>3) {
      break;
    }
    printf("Input an element:");
    scanf("%d", &value);
    //调用函数
    select(a, option, value);
    printf("\n");
  }
  //结束操作
  printf("Thanks!");
  return 0;
}
void select(int a[], int option, int value) {
  switch (option) {
  case 1:
    insert(a, value);//增
    break;
  case 2:
    remove(a, value);//删
    break;
  case 3:
    query(a, value);//查
    break;
  }//跟模拟计算器的三种方法相似,都可。
}
void input_array(int a[]) {
  printf("Input the number of array element:");
  scanf_s("%d", &count);
  printf("Input an order array element:");
    for (int i = 0; i < count; i++) {
      scanf_s("%d", &a[i]);//初始化数组
  }
}
void print_array(int a[]) {
  printf("The ordered array a is:");
    for (int i = 0; i < count; i++) {
      if (i == 0)
        printf("%d", a[i]);
      else
        printf("%d", a[i]);
    }
}
//有序表插入函数
void insert(int a[], int value) {
  int i, j;
  //定位,找到待插入的位置,即退出循环时i的位置
  for (i = 0; i < count; i++) {
    if (value < a[i]) {
      break;
    }
  }
  //腾位:将a[i]~a[count-1]向后顺移一位
  for (j = count - 1; j >= i; j--) {
    a[j + 1] = a[j];
  }
  a[i] = value;//将value的值赋给a[i]
  count++;//数组待处理的元素数量加1
  print_array(a);
}
//有序表删除函数
void remove(int a[], int value) {
  int i, index = -1;
  //定位:如果找到待删除的元素,用index记录其下标
  for (i = 0; i < count; i++) {
    if (value == a[i]) {
      index = i;
      break;
    } 
  }
  //没找到
  if (index == -1) {
    printf("Failed to find the date,deletion failed.");
  }
  //找到,删除a[index],并且将之后的所有元素向前挪一位
  else {
    for (i = index; i < count - 1; i++) {
      a[i] = a[i + 1];
    }
  }
  //待处理的元素数量减1
  count--;
  print_array(a);
}
//有序表二分查找法查询函数
void query(int a[], int value) {
  int mid, left = 0, right = count - 1;
  while (left <= right) {
    mid = (left + right) / 2;
    if (value == a[mid]) {
      printf("The index is:%d", mid);
      return;//
    }
    else if (value < a[mid]) {
      right=mid - 1;
    }
    else {
      left = mid + 1;
    }
  }
  printf("This element does not exist.");
}


20.这个题目就是给学生分等级,但是由于分级的时候,分数不是整十的数,所以不能用switch,但是我们要知道,switch只不过是比较厉害的多分支结构罢了,所以我们直接用多分支就好了


#include <stdio.h>
#define MAXN 10
struct student{
    int num;
    char name[20];
    int score;
    char grade;
};
int set_grade( struct student *p, int n );
int main()
{   struct student stu[MAXN], *ptr;
    int n, i, count;
    ptr = stu;
    scanf("%d\n", &n);
    for(i = 0; i < n; i++){
       scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score);
    } 
   count = set_grade(ptr, n);
   printf("The count for failed (<60): %d\n", count);
   printf("The grades:\n"); 
   for(i = 0; i < n; i++)
       printf("%d %s %c\n", stu[i].num, stu[i].name, stu[i].grade);
    return 0; 
}
int set_grade( struct student *p, int n ){
  int count=0; 
  for(int i=0;i<n;i++){
    if((p->score)<60){
      count++;
      p->grade='D';
    }else if(p->score>=60 && p->score<=69){
      p->grade='C';
    }else if(p->score>=70 && p->score<=84)
      p->grade='B';
    else
      p->grade='A'; 
    p++;
  }
  return count;
}


21.凯撒密码


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define MAXLINE 80
#define M 26
//凯撒密码
int main() {
  int i, offset;//offset是偏移量
  char str[MAXLINE];
  printf("Enter a string:");
  //初始化数组
  i = 0;
  while ((str[i] = getchar()) != '\n') {
    i++;
  }
  str[i] = '\0';//一定要记得这一步,字符串数组没有‘\0’是很难操作的
  printf("Enter offest:");
  scanf("%d", &offset);
  //如果偏移量大于26,
  if (offset >= M) {
    offset = offset % M;
  }
  //遍历数组
  for (i = 0; str[i]; i++) {
    if (str[i] >= 'A' && str[i] <= 'Z') {
      if ((str[i] - 'A' + offset) < M)
        str[i] += offset;
      else {
        str[i] -= (M - offset);
      }
    }
    else if (str[i] >= 'a' && str[i] <= 'z') {
        if ((str[i] - 'a' + offset) < M){
          str[i] += offset;
        }
        else {
          str[i] -= (M - offset);
        }
      }
    }
  //做题目的时候,一定要养成这种思维,不是为了做题而去做题,不是说有了思路之后就直接写完了,要全面考虑,考虑会不会有其他bug。
  printf("After being encrypted:");
  for (i = 0; str[i]; i++) {
    putchar(str[i]);
  }
  printf("\n");
  return 0;
}
/*如果我需要随机输入一个字符串,我可以选择定义数组长度,然后用一个for循环来输入,但是这样并不能保证完美用到每个空间,就算自己计算,则会导致
运算量的增大。最常用的办法就是用while循环来输入,表达式为(str[i]=getchar())!='\n'.就跟上面一样,要先定义一个i=0;然后在循环体中i++。*/


22.判断完数


#define _CRT_SECURE_NO_WARNINGS 1
//判断完数-一个数敲好等于它的因子之和,这个数就叫做完数。
#include<stdio.h>
int main() {
  int i, j, n, sum;
  static int k[10];
  for (i = 2; i <= 1000; i++) {
    n = -1;
    sum = i;
    //遍历找因子,如果sum-=j成立且最后为0,则代表他们相等,再把每次的因子分别存到数组。
    for (j = 1; j < i; j++) {
      if (i % j == 0)
      {
        n++;
        sum -= j;
        k[n] = j;
      }
    }
    if (sum == 0)
    {
      printf("%d is a 完数.", i);
      for (j = 0; j <=n; j++) {
        printf("%d,", k[j]);
      }
      printf("\n");
    }
  }
  return 0;
}


23.旋转数组


#define _CRT_SECURE_NO_WARNINGS 1
//旋转数组(以逆时针旋转90度为例)
#include<stdio.h>
int main() {
  int a[4][4], b[4][4];
  int i, j;
  printf("请输入16个数据:");
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) {
      scanf("%d", &a[i][j]);
      b[3 - j][i] = a[i][j];//真正的点睛之笔,把这个式子带到程序中理解,b数组第一个存进去的元素是b[3][0],b[2][0],
                           //b[1][0],b[0][0],分别是由a[0][0],a[0][1],a[0][2],a[0][3]存进去的,就像旋转了一样
    }
  }
  printf("array b:\n");
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 4; j++) 
      printf("%6d", b[i][j]);
    printf("\n");
  }
  return 0;
}


24.


#define _CRT_SECURE_NO_WARNINGS 1
/*
通过键盘输入3名学生4门课程的成绩,
分别求每个学生的平均成绩和每门课程的平均成绩。
要求所有成绩均放入一个4行5列的数组中,输入时同一人数据间用空格,不同人用回车
其中最后一列和最后一行分别放每个学生的平均成绩、每门课程的平均成绩及班级总平均分。*/
#include<stdio.h>
int main() {
  float a[4][5], sum1, sum2;
  int i, j;
  //先初始化不算平均值的地方,把其他地方空出来
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 4; j++) {
      scanf("%f", &a[i][j]);
    }
  }
  //将上面的数据算出平均值存到最后一列
  for (i = 0; i < 3; i++) {
    sum1 = 0;
    for (j = 0; j < 4; j++) {
      sum1 += a[i][j];  
    }
    a[i][4] = sum1 / 4;
  }
  //由于此时最后一列是有数据的,所以此时j的循环条件改变为j<5,最后一列也要求平均值
  for (j = 0; j < 5; j++) {
    sum2 = 0;
    for (i = 0; i < 3; i++) {
      sum2 += a[i][j];
    }
    a[3][j] = sum2 / 3;
  }
  //输出
  for (i = 0; i < 4; i++) {
    for (j = 0; j < 5; j++) {
      printf("%6.2f", a[i][j]);
    }
    putchar('\n');
  }
  return 0;
}


25.删除字符串中的某个字母并输出


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main() {
  char s[100], c;
  int i, j = 0;
  printf("Enter a string:");
  //编译器问题,vs2022里面的stdio.h中里面没有gets函数,只有gets_s函数
  gets_s(s);
  printf("\nEnter a character:");
  c = getchar();
  for (i = 0; s[i]; i++) {
    //把不同的字母存到另一个数组中,从而达到删除的目的
    if (s[i] != c)
      s[j++] = s[i];
  }
    s[j] = '\0';
    printf("\n%s", s);
  return 0;
}


26.


#define _CRT_SECURE_NO_WARNINGS 1
//在有序数组中插入一个元素,并且插入过后同样是有序的。
#include<stdio.h>
int main() {
  //a[0]为工作单元,从a[1]开始存放数据。
  int a[10] = { 0,1,2,3,4,6,7};
  //j代表元素个数
  int x, i, j = 6;
  //输入插入的值
  printf("Enter a number:");
  scanf("%d", &x);
  //把x要放在数组中,避免数据的丢失。
  a[0] = x;
  //可以选择从大往小,也可以选择从小往大。我这里是从大往小。
  i = j;
  while (a[i] > x) {
    a[i + 1] = a[i];
    i--;
  }
  //把x放到比他小的值后面一位,因为上面已经把它的后面一位空出来了,所以,这个操作不会对数组内的数据有影响
  a[++i] = x;
  //插入x后,元素总个数增加。
  j++;
  //输出数组
  for (i = 1; i <= j; i++)
    printf("%8d", a[i]);
  printf("\n");
  return 0;
}


暂时写这么多了,够你们啃好久了,如果不知道题目,根据我代码里面的描述去搜题,同时也可以对比看看,看看别人的代码再看看我的,不说谁写的好,但是我注释一定是比很多人要清楚的。

目录
相关文章
|
6月前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
6月前
|
存储 C语言 C++
C语言------------指针笔试题目深度剖析
C语言------------指针笔试题目深度剖析
44 1
|
11月前
2.C语言题目---字符串左旋
2.C语言题目---字符串左旋
76 1
|
1月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
11月前
|
存储
1.C语言题目---指针类(基础)
1.C语言题目---指针类(基础)
60 1
|
3月前
|
存储 编译器 C语言
【C语言】指针练习题目
【C语言】指针练习题目
|
5月前
|
测试技术 C语言
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
数据结构学习记录——树习题—Tree Traversals Again(题目描述、输入输出示例、解题思路、解题方法C语言、解析)
45 1
|
6月前
|
算法 编译器 API
C语言易混淆、简单算法、结构体题目练习、常见关键字总结-1
C语言易混淆、简单算法、结构体题目练习、常见关键字总结
|
5月前
|
C语言
c语言循环题目
c语言循环题目
|
6月前
|
C语言
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)
PTA 浙大版《C语言程序设计(第3版)》题目集 习题8-4 报数 (20分)