XDOJ第六弹:指针

这篇博客包含了多项式合并、中心对称判断、成绩处理、元素放置、字符统计、字符串长度判断、最长单词长度、回文串判断、字符串部分复制、月份判断等算法的C语言实现。涉及链表操作、指针应用、字符串处理等多个方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


P-0133 一元稀疏多项式

在这里插入图片描述

这题比较恶心,这里给出自己用来测试的几个例子

在这里插入图片描述

总体思路是:

存储俩个多项式(单链表或者数组)
合并俩个多项式
(指数一样的,对系数运算,不一样的则插入)
接着输出多项式
(输出多项式的时候,需要特别注意以下几个问题)

1. 系数为0
2. 系数为±1
3. 指数为0
4. 指数为1

附上代码和注释:

(最后某些部分需要free函数释放内存,读者自行处理)

仅供参考。

//xdoj0133.c
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode *List;
struct LNode{
    int c;//系数
    int exp;//指数
    List Next;
}p1,p2;//p1 p2两个链表void Combine(List l,List s,int op){//多项式合并
    List p = l;//存个开头,用于下面合并的判断int flag=1;
    if(op==0){
        while(l&&s){
            //插在开头的情况,只用判断一次
            if(flag && l->exp > s->exp && p->Next==l){
                List temp=(List)malloc(sizeof(p1));
                temp->exp=s->exp;
                temp->c=s->c;
​
                temp->Next=l;
                p->Next=temp;
​
                s=s->Next;
​
                flag=0;
            }//最多只会执行一次if(s==NULL){
                return;
            }if(l->exp == s->exp){
                l->c = l->c + s->c;
                s=s->Next;
            }if(s==NULL){
                return;
            }if( (l->exp < s->exp && l->Next!=NULL && l->Next->exp > s->exp) || (l->exp < s->exp && l->Next==NULL)){
                //三种情况,一种是插在开头(已经处理),一种是结尾,一种是中间
                List temp=(List)malloc(sizeof(p1));
                //数据域 存储到temp
                temp->exp=s->exp;
                temp->c=s->c;
                //插入
                temp->Next=l->Next;
                l->Next=temp;
​
                s=s->Next;
            }
            l = l->Next;
        }
    }else if(op==1){//复制op==1的情况,把其中一个加号改成减号
        while(l&&s){
            if(flag && l->exp > s->exp && p->Next==l){
                List temp=(List)malloc(sizeof(p1));
                temp->exp=s->exp;
                temp->c=-s->c;//这里改了
​
                temp->Next=l;
                p->Next=temp;
​
                s=s->Next;
​
                flag=0;
            }if(s==NULL){
                return;
            }if(l->exp == s->exp){
                l->c = l->c - s->c;//这里改了
                s=s->Next;
            }if(s==NULL){
                return;
            }if( (l->exp < s->exp && l->Next!=NULL && l->Next->exp > s->exp) || (l->exp < s->exp && l->Next==NULL)){
                List temp=(List)malloc(sizeof(p1));
                temp->exp=s->exp;
                temp->c=-s->c;//这里改了
                temp->Next=l->Next;
                l->Next=temp;
                s=s->Next;
            }
            l = l->Next;
        }
    }}void PrintList(List l,int* count){//输出多项式中某个项的函数  总体思路:在每个项的添加正负号
    if(l->c==0){
        return;
    }
    //指数 为0 和 为1 和 不为0也不为1 的情况 count用于判断是否打印过
    if(l->exp==0){
        if(l->c==1){
            if((*count)!=0){
                printf("+");
            }
            printf("1");
            (*count)=1;
        }else if(l->c==-1){
            printf("-1");
            (*count)=1;
        }else{
            if(l->c>0){
                if((*count)!=0){
                    printf("+");
                }
                printf("%d",l->c);
                (*count)=1;
            }else if(l->c<0){
                printf("%d",l->c);
                (*count)=1;
            }
            
        }
    }else if(l->exp==1){//指数为1
        if(l->c==1){
            if((*count)!=0){
                printf("+");
            }
            printf("x");
            (*count)=1;
        }else if(l->c==-1){
            printf("-x");
            (*count)=1;
        }else{
            if(l->c>0){
                if((*count)!=0){
                    printf("+");
                }
                printf("%dx",l->c);
                (*count)=1;
            }else{
                printf("%dx",l->c);
                (*count)=1;
            }
        }
    }else{//指数不为0也不为1
        if(l->c==1){
            if((*count)!=0){
                printf("+");
            }
            printf("x^%d",l->exp);
            (*count)=1;
        }else if(l->c==-1){
            printf("-x^%d",l->exp);
            (*count)=1;
        }else{
            if(l->c>0){
                if((*count)!=0){
                    printf("+");
                }
                printf("%dx^%d",l->c,l->exp);
                (*count)=1;
            }else{
                printf("%dx^%d",l->c,l->exp);
                (*count)=1;
            }
        }
    }
    return;
}
int main(){
    int n,m,t;
    scanf("%d%d%d",&n,&m,&t);//存储第一个多项式
    List Ptrl1=(List)malloc(sizeof(p1));//创建并分配头结点的内存
    Ptrl1->Next=NULL;//指针域设为空
    List s,p;
    p=Ptrl1;
    //这里采用尾插法
    for(int i=0;i<n;i++){
        s=(List)malloc(sizeof(p1));
        scanf("%d%d",&s->c,&s->exp);
        p->Next=s;
        s->Next=NULL;
        p=s;
    }
    
    //重复上面的操作,存储第二个多项式
    List Ptrl2=(List)malloc(sizeof(p2));
    Ptrl2->Next=NULL;
    p=Ptrl2;
    for(int i=0;i<m;i++){
        s=(List)malloc(sizeof(p2));
        scanf("%d%d",&s->c,&s->exp);
        p->Next=s;
        s->Next=NULL;
        p=s;
    }
    //让Ptrl1 是 较长的多项式的头  Ptrl2是较短多项式的头
    if(n<m){
        s=Ptrl1;
        Ptrl1=Ptrl2;
        Ptrl2=s;
    }
    //先合并多项式
    Combine(Ptrl1,Ptrl2,t);
    //输出部分
    List out=Ptrl1->Next;//判断是否全部为0
    int sign=0;//假设全为0
    while(out){
        if(out->c!=0){
            sign=1;
            break;
        }
        out=out->Next;
    }if(sign==0){
        printf("0");//全为0说明多项式完全抵消了
        return 0;
    }
​
    out=Ptrl1->Next;
    int count=0;//防止开头出现加号
    while(out&&sign){
        PrintList(out,&count);
        out=out->Next;
    }
    return 0;
}

P-0376 判断是否中心对称

在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main(){
    char str[100];
    gets(str);
    int len=strlen(str);
    char *l=str;
    char *r=str+len-1;
    int flag=1;
    while(l<=r){
        if(*l != *r){
            flag=0;
            break;
        }
        l++;
        r--;
    }
    if(flag){
        printf("Yes");
    }else{
        printf("No");
    }
    return 0;
}

P-0211 成绩处理–数组与指针

在这里插入图片描述

#include<stdio.h>
int main(){
    double stu[5][4],sum=0,avg=0;
    int c1=0,countF=0,countW=0,flag=1;
    for(int i=0;i<5;i++){
        c1=0;//不及格科目数
        avg=0;
        flag=1;
        for(int j=0;j<4;j++){
            scanf("%lf",&stu[i][j]);
            if(stu[i][j]<60){
                c1++;//判断不及格
            }
            avg+=stu[i][j];//计算一个学生的平均成绩
            if(stu[i][j]<85){
                flag=0;
            }
        }
        if(avg>=360||flag==1){//判断优秀 4*90=360
            countW++;
        }
        sum+=stu[i][0];//第一门课的总和
        if(c1>=2){
            countF++;//2门及以上不及格人数
        }
    }
    printf("%.1lf %d %d",sum/5,countF,countW);
    return 0;
}

P-0213 元素放置–指针练习

在这里插入图片描述

//xdoj0213.c
//测试样例输入的绝对有不符合题意的输入,千万不要让2<=m<=n<=7 否则最后一个例子会出错
#include<stdio.h>
int nums[50]={0};
void swap(int *a,int *b){
    int t=*a;
    *a = *b;
    *b = t;
}
void reverse(int *nums,int start,int end){
    while(start<end){
        swap(&nums[start],&nums[end]);
        start++;
        end--;
    }
}
void SelectionSort(int *nums,int length){
    int i,j,min;
    for(i=0;i<length-1;i++){
        for(j=i,min=i;j<length;j++){
            if(nums[min]>nums[j]){
                min=j;
            }
        }
        if(min!=i){
            swap(&nums[min],&nums[i]);
        }
    }
}
int main(){
    int m,n;
    scanf("%d%d",&m,&n);
    int k=0;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            scanf("%d",&nums[k++]);
            if(nums[k-1]>100){
                return 0;
            }
        }
    }
    //排序
    SelectionSort(nums,m*n);
    //奇数行反转
    for(int i=0;i<n*m;i=i+(n+n)){
        reverse(nums,i,i+n-1);
    }
    //按照二维输出
    k=0;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            printf("%3d",nums[k++]);
        }
        if(i!=m-1){
            printf("\n");
        }
    }
    return 0;
}

P-0214 字符统计

在这里插入图片描述

//xdoj0214.c
#include<stdio.h>
#include<ctype.h>
#include<string.h>
char string[101]={'\0'};
int num[5];
void count(int *num,char *string,int strlen){
    char *p=string;
    while(p<string+strlen){
        if(isupper(*p)){
            num[0]++;
        }else if(islower(*p)){
            num[1]++;
        }else if(*p==' '){
            num[2]++;
        }else if(isdigit(*p)){
            num[3]++;
        }else{
            num[4]++;
        }
        p++;
    }
    return;
}
int main(){
    gets(string);
    int len=strlen(string);
    count(num,string,len);
    for(int i=0;i<5;i++){
        printf("%d ",num[i]);
    }
    return 0;
}

P-0220 字符串长度判断

在这里插入图片描述

//xdoj0220.c
#include<stdio.h>
#include<string.h>
int main(){
    char str[100];
    gets(str);
    printf("%d",strlen(str));
    return 0;
}

P-0231 最长单词的长度

在这里插入图片描述

//xdoj0231.c
#include<stdio.h>
#include<string.h>
#include<ctype.h>
char str[101];
int main(){
    gets(str);
    char *p=str;
    int len=strlen(str),max=0,c=0;
    while(p<str+len){
        if(isalpha(*p)){
            c++;
        }else if(*p==' '|| *p=='.'){
            if(c>max){
                max=c;
            }
            c=0;
        }
        p++;
    }
    printf("%d",max);
    return 0;
}

P-0232 判断字符串是否是回文串

在这里插入图片描述

//xdoj0232.c 一样
//xdoj0376.c
#include<stdio.h>
#include<string.h>
char str[100];
int main(){
    gets(str);
    int len=strlen(str);
    char *l=str;
    char *r=str+len-1;
    int flag=1;
    while(l<=r){
        if(*l != *r){
            flag=0;
            break;
        }
        l++;
        r--;
    }
    if(flag){
        printf("yes");
    }else{
        printf("no");
    }
    return 0;
}

P-0233 字符串部分复制

在这里插入图片描述

//xdoj0233.c
#include<stdio.h>
#include<string.h>
char str[51]={'\0'};
char copy[51]={'\0'};
void copystr(char *str,int m,char *copy,int len){
    char *p=str+m-1;
    char *i=copy;
    while(p<str+len){
        *i = *p;
        p++;
        i++;
    }
    return;
}
int main(){
    gets(str);
    int m,len=strlen(str);
    scanf("%d",&m);
    if(m>len){
        printf("error");
        return 0;
    }
    copystr(str,m,copy,len);
    puts(copy);
    return 0;
}

P-0235 月份判断

在这里插入图片描述

//xdoj0235.c
#include<stdio.h>
char *months[12]={"January","February","March","April","May","June","July","August","September","October","November","December"};
int main(){
    int n;
    scanf("%d",&n);
    if(n>1&&n<13){
        printf("%s",months[n-1]);
    }else{
        printf("wrong");
    }
    return 0;
}

P-0236 字符串长度判断(1)

在这里插入图片描述

//xdoj0236.c  和 220是一样的
#include<stdio.h>
#include<string.h>
int main(){
    char str[100];
    gets(str);
    printf("%d",strlen(str));
    return 0;
}

P-0237 字符串复制

在这里插入图片描述

//xdoj0237.c
//xdoj0233.c
#include<stdio.h>
#include<string.h>
char str[51]={'\0'};
char copy[51]={'\0'};
void copystr(char *str,int m,char *copy,int len){
    char *p=str+m-1;
    char *i=copy;
    while(p<str+len){
        *i = *p;
        p++;
        i++;
    }
    return;
}
int main(){
    gets(str);
    int m,len=strlen(str);
    scanf("%d",&m);
    if(m>len){
        printf("error");
        return 0;
    }
    copystr(str,m,copy,len);
    puts(copy);
    return 0;
}

最后

感兴趣的可以关注我的微信公众号,第一时间收到动态
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值