2024/3/17 C语言刷题笔记

1.给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点

struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    struct ListNode *dummy=malloc(sizeof(struct ListNode));
    dummy->next=head;
    struct ListNode *cur=dummy;
    while(cur->next&&n>0)
    {
        cur=cur->next;
        n--;
    }
    struct ListNode *p=dummy;
    while(cur->next!=NULL)
    {
        p=p->next;
        cur=cur->next;
    }
    p->next=p->next->next;
    return dummy->next;
}

2.给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

struct ListNode* oddEvenList(struct ListNode* head) {
    struct ListNode *odd=malloc(sizeof(struct ListNode));
    odd->next=NULL;
    struct ListNode *even=malloc(sizeof(struct ListNode));
    even->next=NULL;
    struct ListNode *optail=odd,*eptail=even;
    struct ListNode *cur=head;
    int index=1;
    while(cur!=NULL)
    {
        if(index%2==1)
        {
            struct ListNode *node1=malloc(sizeof(struct ListNode));
            node1->val=cur->val;
            node1->next=NULL;
            optail->next=node1;
            optail=node1;
        }
        else
        {
            struct ListNode *node2=malloc(sizeof(struct ListNode));
            node2->val=cur->val;
            node2->next=NULL;
            eptail->next=node2;
            eptail=node2;
        }
        index++;
        cur=cur->next;
    }
    optail->next=even->next;
    return odd->next;
}

3.给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。(跟上题类似,基本不用改啥,所以变量名也懒得改了)

struct ListNode* partition(struct ListNode* head, int x){
    struct ListNode *odd=malloc(sizeof(struct ListNode));
    odd->next=NULL;
    struct ListNode *even=malloc(sizeof(struct ListNode));
    even->next=NULL;
    struct ListNode *optail=odd,*eptail=even;
    struct ListNode *cur=head;
    while(cur!=NULL)
    {
        if(cur->val<x)
        {
            struct ListNode *node1=malloc(sizeof(struct ListNode));
            node1->val=cur->val;
            node1->next=NULL;
            optail->next=node1;
            optail=node1;
        }
        else
        {
            struct ListNode *node2=malloc(sizeof(struct ListNode));
            node2->val=cur->val;
            node2->next=NULL;
            eptail->next=node2;
            eptail=node2;
        }
        cur=cur->next;
    }
    optail->next=even->next;
    return odd->next;
}

4.给定两个用链表表示的整数,每个节点包含一个数位。这些数位是反向存放的,也就是个位排在链表首部。编写函数对这两个整数求和,并用链表形式返回结果。

示例:

输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
输出:2 -> 1 -> 9,即912
(这种题一直没思路,抄的官方题解,以后好好琢磨琢磨)
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2){
    struct ListNode *head=NULL,*tail=NULL;
    int carry=0;
    while(l1||l2)
    {
        int n1=l1?l1->val:0;
        int n2=l2?l2->val:0;
        int sum=n1+n2+carry;
        if(!head)
        {
            head=tail=malloc(sizeof(struct ListNode));
            tail->val=sum%10;
            tail->next=NULL;
        }
        else
        {
            tail->next=malloc(sizeof(struct ListNode));
            tail->next->val=sum%10;
            tail=tail->next;
            tail->next=NULL;
        }
        carry=sum/10;
        if(l1)
            l1=l1->next;
        if(l2)
            l2=l2->next;
    }
    if(carry>0){
        tail->next=malloc(sizeof(struct ListNode));
        tail->next->val=carry;
        tail->next->next=NULL;
    }
    return head;
}

5.编写一个函数,检查输入的链表是否是回文的。

bool isPalindrome(struct ListNode* head){
    if(head==NULL||head->next==NULL)
        return true;
    struct ListNode *last=malloc(sizeof(struct ListNode));
    last->next=NULL;
    struct ListNode *cur=head;
    int len=0;
    while(cur!=NULL)
    {
        cur=cur->next;
        len++;
    }
    struct ListNode *fast=head;
    int temp=len/2;
    while(temp>0)
    {
        fast=fast->next;
        temp--;
    }
    while(fast!=NULL)
    {
        struct ListNode *node=malloc(sizeof(struct ListNode));
        node->val=fast->val;
        node->next=last->next;
        last->next=node;
        fast=fast->next;
    }
    //那么现在last存的是后半部分的逆置
    cur=last->next;
    fast=head;
    while(cur!=NULL)
    {
        if(cur->val!=fast->val)
            return false;
        cur=cur->next;
        fast=fast->next;
    }
    return true;
}

6.给你一个链表的头节点 head ,判断链表中是否有环。

bool hasCycle(struct ListNode *head) {
    struct ListNode *fast=head,*slow=head;
    while(fast!=NULL&&fast->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)
            return true;
    }
    return false;
}

7.给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *fast=head,*slow=head;
    while(fast!=NULL&&fast->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)
        {
            struct ListNode *p=head;
            struct ListNode *q=fast;
            while(p!=q)
            {
                p=p->next;
                q=q->next;
            }
            return p;
        }
    }
    return NULL;
}

8.给你链表的头节点 head 和一个整数 k 。

交换 链表正数第 k 个节点和倒数第 k 个节点的值后,返回链表的头节点(链表 从 1 开始索引

struct ListNode* swapNodes(struct ListNode* head, int k) {
    struct ListNode *cur=head;
    int temp=k;
    while(temp>1)
    {
        cur=cur->next;
        temp--;
    }
    struct ListNode *thezk=cur;
    int zk=cur->val;
    struct ListNode *p=head;
    while(cur->next!=NULL)
    {
        p=p->next;
        cur=cur->next;
    }
    int dk=p->val;
    p->val=thezk->val;
    thezk->val=dk;
    return head;
}

2024/3/17 上午10:17 今天链表题就做到这了,复试考链表这块基本就排序去重等操作,理解即可


9.读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

输入格式:

每个测试输入包含 1 个测试用例,即给出自然数 n 的值。这里保证 n 小于 10^100。

#include <stdio.h>
int main()
{
    char str[100000];
    gets(str);
    int sum=0;
    int res[100000];
    for(int i=0;str[i]!='\0';i++)
        sum+=str[i]-'0';
    char letter[][10]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
    int temp=sum,len=0;
    while(temp!=0)
    {
        len++;
        temp/=10;
    }
    int templen=len;
    while(sum!=0)
    {
        res[templen-1]=sum%10;
        templen--;
        sum/=10;
    }
    for(int i=0;i<len-1;i++)
    {
        printf("%s ",letter[res[i]]);
    }
    printf("%s",letter[res[len-1]]);
    return 0;
}

10.卡拉兹(Callatz)猜想

#include <stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    int step=0;
    while(n!=1)
    {
        if(n%2==0)
            n=n/2;
        else
            n=(3*n+1)/2;
        step++;
    }
    printf("%d\n",step);
    return 0;
}

11.给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。

输入格式:

测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。

输出格式:

每个测试用例的输出占一行,输出倒序后的句子。

输入样例:

Hello World Here I Come

输出样例:

Come I Here World Hello

 

#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
    char str[81];
    fgets(str,81,stdin);
    str[strcspn(str, "\n")] = '\0';
//该语句等价为:
/*  int len=strlen(str);
    if(str[len-1]=='\n')
    str[len-1]='\0';
*/
    int len=0;
    for(len=0;str[len]!='\0';len++);
    for(int i=0;i<len/2;i++)
    {
        char temp=str[i];
        str[i]=str[len-i-1];
        str[len-i-1]=temp;
    }
    int start=0,end=0;
    for(int i=0;str[i]!='\0';i++)
    {
        if(isalpha(str[i]))
        {
            start=i;
            while(isalpha(str[i]))
                i++;
            if(str[i]==' '||str[i]=='\0')
                end=i-1;
        }
        for(int j=start;j<=(start+end)/2;j++)
        {
            char temp=str[j];
            str[j]=str[start+end-j];
            str[start+end-j]=temp;
        }
    }
    for(int i=0;i<len;i++)
        printf("%c",str[i]);
    return 0;
}

12.“性感素数”是指形如 (p, p+6) 这样的一对素数。之所以叫这个名字,是因为拉丁语管“六”叫“sex”(即英语的“性感”)。(原文摘自 http://mathworld.wolfram.com/SexyPrimes.html)

现给定一个整数,请你判断其是否为一个性感素数。

输入格式:

输入在一行中给出一个正整数 N (≤108)。

输出格式:

若 N 是一个性感素数,则在一行中输出 Yes,并在第二行输出与 N 配对的另一个性感素数(若这样的数不唯一,输出较小的那个)。若 N 不是性感素数,则在一行中输出 No,然后在第二行输出大于 N 的最小性感素数。

#include<stdio.h>
#include<math.h>
int isprime(int n)
{
    if(n<=1)
        return 0;
    for(int i=2;i<=(int)sqrt(n);i++)
        if(n%i==0)
            return 0;
    return 1;
}
int main()
{
    int n;
    scanf("%d",&n);
    if((isprime(n)&&isprime(n+6))||(isprime(n)&&isprime(n-6)))
    {
        printf("Yes\n");
        printf("%d",isprime(n-6)?n-6:n);
    }
    else{
        printf("No\n");
        for(int i=n+1;;i++)
            if((isprime(i)&&isprime(i+6))||(isprime(i)&&isprime(i-6))) //别以为只能往后找
            {
                printf("%d",i);
                break;
            }
    }
    return 0;
}

13.当自然数 n 依次取 1、2、3、……、N 时,算式 ⌊n/2⌋+⌊n/3⌋+⌊n/5⌋ 有多少个不同的值?(注:⌊x⌋ 为取整函数,表示不超过 x 的最大自然数,即 x 的整数部分。)

输入格式:

输入给出一个正整数 N(2≤N≤104)。

输出格式:

在一行中输出题面中算式取到的不同值的个数。

#include<stdio.h>
#include<math.h>
int main()
{
    int n;
    scanf("%d",&n);
    int hash[100001]={0};
    for(int i=1;i<=n;i++)
    {
        int y=i/2+i/3+i/5;
        hash[y]=1;
    }
    int count=0;
    for(int i=0;i<100001;i++)
    {
        if(hash[i]==1)
            count++;
    }
    printf("%d\n",count);
    return 0;
}

14.给定 N 张卡片,正面分别写上 1、2、……、N,然后全部翻面,洗牌,在背面分别写上 1、2、……、N。将每张牌的正反两面数字相减(大减小),得到 N 个非负差值,其中是否存在相等的差?

输入格式:

输入第一行给出一个正整数 N(2 ≤ N ≤ 10 000),随后一行给出 1 到 N 的一个洗牌后的排列,第 i 个数表示正面写了 i 的那张卡片背面的数字。

输出格式:

按照“差值 重复次数”的格式从大到小输出重复的差值及其重复的次数,每行输出一个结果。

输入样例:

8
3 5 8 6 2 1 4 7

输出样例:

5 2
3 3
2 2
#include<stdio.h>
#include<stdlib.h>
int main()
{
    int n;
    scanf("%d",&n);
    int hash[10001]={0};
    int *z=malloc(sizeof(int)*n);
    for(int i=0;i<n;i++)
        z[i]=i+1;
    int *f=malloc(sizeof(int)*n);
    for(int i=0;i<n;i++){
        scanf("%d",&f[i]);
        int temp=abs(z[i]-f[i]);
        hash[temp]++;
    }

    for(int i=10000;i>=0;i--)
        if(hash[i]>1)
        {
            printf("%d %d\n",i,hash[i]);
        }
    return 0;
}

2024/3/17 15:00 再次分割,新买的书到了,虐虐简单题玩玩,哈哈哈


15.练习5-1 求m到n之和

int sum(int m,int n)
{
    int sum=0;
    for(int i=m;i<=n;i++)
        sum+=i;
    return sum;
}

16.练习5-2 找两个数中最大者

int max(int a,int b)
{
    return a>b?a:b;
}

17.练习5-3 字符金字塔

void CharPyramid( int n, char ch)
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n-i-1;j++)
            printf(" ");
        for(int j=0;j<=i;j++)
            printf("%c ",ch);
        printf("\n");
    }
}

18.习题5-1 符号函数

int sign( int x )
{
    if(x>0)
        return 1;
    else if(x==0)
        return 0;
    else
        return -1;
}

19.习题5-2 使用函数求奇数和

int even( int n )
{
    if(n%2==0)
        return 1;
    return 0;
}
int OddSum( int List[], int N )
{
    int sum=0;
    for(int i=0;i<N;i++)
        if(!even(List[i]))
            sum+=List[i];
    return sum;
}

20.习题5-3 使用函数计算两点间的距离

#include<math.h>
double dist( double x1, double y1, double x2, double y2 )
{
    return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}

21.习题5-4 使用函数求素数和

#include<math.h>
int prime( int p )
{
    if(p<=1)
        return 0;
    for(int i=2;i<=(int)sqrt(p);i++)
        if(p%i==0)
            return 0;
    return 1;
}
int PrimeSum( int m, int n )
{
    int sum=0;
    for(int i=m;i<=n;i++)
        if(prime(i)==1)
            sum+=i;
    return sum;
}

22.习题5-5 使用函数统计指定数字的个数

int CountDigit( int number, int digit )
{
    int count=0;
    if(number==0&&digit==0)
        return 1;
    if(number<0)
        number=-number;
    while(number!=0)
    {
        if(number%10==digit)
            count++;
        number/=10;
    }
    return count;
}

23.习题5-6 使用函数输出水仙花数(好坑的一题,以为默认三位数呢,直接abc了....小丑了

#include<stdlib.h>
int narcissistic( int number )
{
    int temp=number;
    int len=0;
    while(temp!=0)
    {
        len++;
        temp/=10;
    }
    int *a=malloc(sizeof(int)*len);
    temp=number;
    for(int i=0;i<len;i++)
    {
        a[i]=temp%10;
        temp/=10;
    }
    int sum=0;
    for(int i=0;i<len;i++)
    {
        int temp2=1;
        for(int j=0;j<len;j++)
            temp2*=a[i];
        sum+=temp2;
    }
    if(sum==number)
        return 1;
    else
        return 0;
}
void PrintN( int m, int n )
{   
    for(int i=m+1;i<n;i++)
        if(narcissistic(i)==1)
            printf("%d\n",i);
}

24.本题要求实现一个函数,用下列公式求cos(x)的近似值,精确到最后一项的绝对值小于e:

cos(x)=x0/0!−x2/2!+x4/4!−x6/6!+⋯   (我是fw,卡了好久,先超时,再精度,菜__)

double fabs(double n)
{
    if(n<0)
        return -n;
    else
        return n;
}
double funcos( double e, double x )
{
    double temp=1,res=1,tempx=1;
    int i=2,sign=1;
    double fact=1;
    while(fabs(temp)>=e)
    {
        tempx*=x*x;
        fact*=1.0*(i*(i-1));
        sign=-sign;
        temp=tempx*sign/fact;
        i+=2;
        res+=temp;
    }
    return res;
}

25.本题要求实现一个函数,输出n行空心的数字金字塔

void hollowPyramid( int n )
{
    for(int i=1;i<=n-1;i++)
    {
        for(int j=1;j<n*2;j++)
        {
            if(j==n-i+1||j==n+i-1)
                printf("%d",i);
            else if(j<n+i-1)
                printf(" ");
        }
        printf("\n");
    }
    for(int i=1;i<n*2;i++)
        printf("%d",n);
}

26.本题要求实现一个函数,统计给定字符串中英文字母、空格或回车、数字字符和其他字符的个数。

#include<ctype.h>
void StringCount( char s[] )
{
    int letter=0,blank=0,digit=0,other=0;
    for(int i=0;s[i]!='\0';i++)
    {
        if(isalpha(s[i]))
            letter++;
        else if(isdigit(s[i]))
            digit++;
        else if(s[i]==' '||s[i]=='\n')
            blank++;
        else 
            other++;
    }
    printf("letter = %d, blank = %d, digit = %d, other = %d",letter,blank,digit,other);
}

27.给定两个均不超过9的正整数a和n,要求编写函数求a+aa+aaa++⋯+aa⋯a(n个a)之和。

int fn( int a, int n )
{
    int temp=a;
    for(int i=1;i<n;i++)
    {
        a=a*10+temp;
    }
    return a;
}
int SumA( int a, int n )
{
    int sum=0;
    for(int i=1;i<=n;i++)
        sum+=fn(a,i);
    return sum;
}

28.本题要求实现一个计算整数因子和的简单函数,并利用其实现另一个函数,输出两正整数m和n(0<m≤n≤10000)之间的所有完数。所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3,其中1、2、3为6的因子。(一开始当友好数对来做了,题做多了,脑壳晕了)

int factorsum( int number )
{
    int sum=0;
    for(int i=1;i<number;i++)
        if(number%i==0)
            sum+=i;
    return sum;
}
void PrintPN( int m, int n )
{
    int flag=0,choose;
    for(int i=m;i<=n;i++)
    {
        if(factorsum(i)==i)
        {
            printf("%d = ",i);
            flag=1;
            for(int j=1;j<i;j++)
            {
                choose=0;
                if(i%j==0)
                {
                    for(int k=j+1;k<i;k++)
                    {
                        if(i%k==0)
                        {
                            choose=1;
                            break;
                        }
                    }
                    if(choose==1)
                        printf("%d + ",j);
                    else
                        printf("%d\n",j);
                }
            }
        }
    }
    if(flag==0)
        printf("No perfect number");
}

29.本题要求实现一个计算Fibonacci数的简单函数,并利用其实现另一个函数,输出两正整数m和n(0<m≤n≤10000)之间的所有Fibonacci数。所谓Fibonacci数列就是满足任一项数字是前两项的和(最开始两项均定义为1)的数列。

int fib( int n )
{
    int f[10001];
    f[0]=1,f[1]=1;
    for(int i=2;i<=n;i++)
        f[i]=f[i-1]+f[i-2];
    return f[n-1];
}
void PrintFN( int m, int n )
{
    int i=0;
    int flag=0;
    while(fib(i)<m)
    {   
        i++;
    }
    while(fib(i)<=n)
    {
        if(fib(i+1)>n)
            printf("%d",fib(i));
        else
            printf("%d ",fib(i));
        flag=1;
        i++;
    }
    if(flag==0)
        printf("No Fibonacci number\n");
}

30.本题要求实现一个判断素数的简单函数,并利用该函数验证哥德巴赫猜想:任何一个不小于6的偶数均可表示为两个奇素数之和。素数就是只能被1和自身整除的正整数。注意:1不是素数,2是素数。

int prime( int p )
{
    if(p<=1)
        return 0;
    for(int i=2;i<p;i++)
        if(p%i==0)
            return 0;
    return 1;
}
void Goldbach( int n )
{
    for(int i=2;i<n;i++)
        if(prime(i)&&prime(n-i))
        {
            printf("%d=%d+%d",n,i,n-i);
            break;
        }
}

31.本题要求实现一个求整数的逆序数的简单函数

int reverse( int number )
{
    int res=0;
    while(number!=0)
    {
        res=res*10+number%10;
        number/=10;
    }
    return res;
}

32.本题要求实现一个计算输入的两数的和与差的简单函数。

void sum_diff( float op1, float op2, float *psum, float *pdiff )
{
    *psum=op1+op2;
    *pdiff=op1-op2;
}

33.本题要求编写函数,将输入字符串的前3个字符移到最后。

void Shift( char s[] )
{
    char ch[3];
    for(int i=0;i<3;i++)
        ch[i]=s[i];
    int len=3;
    for(int j=3;s[j]!='\0';j++)
    {
        len++;
        s[j-3]=s[j];
    }
    int k=0;
    for(int j=len-3;j<len;j++)
        s[j]=ch[k++];
}

34.本题要求实现一个拆分实数的整数与小数部分的简单函数。

void splitfloat( float x, int *intpart, float *fracpart )
{
    *intpart=(int)x;
    *fracpart=x-(int)x;
}

35.本题要求实现一个在数组中查找指定元素的简单函数。

int search( int list[], int n, int x )
{
    for(int i=0;i<n;i++)
        if(list[i]==x)
            return i;
    return -1;
}

36.本题要求实现一个对数组进行循环右移的简单函数:一个数组a中存有n(>0)个整数,将每个整数循环向右移m(≥0)个位置,即将a中的数据由(a0​a1​⋯an−1​)变换为(an−m​⋯an−1​a0​a1​⋯an−m−1​)(最后m个数循环移至最前面的m个位置)。

void ArrayShift( int a[], int n, int m )
{
    int b[n];
    for(int i=0;i<n;i++)
        b[(i+m)%n]=a[i];
    for(int i=0;i<n;i++)
        a[i]=b[i];
}

37.报数游戏是这样的:有n个人围成一圈,按顺序从1到n编好号。从第一个人开始报数,报到m(<n)的人退出圈子;下一个人从1开始报数,报到m的人退出圈子。如此下去,直到留下最后一个人。本题要求编写函数,给出每个人的退出顺序编号。

(ps:好绕的一题,正常理解我都能理解,这个实例真给我搞蒙了)

人:            1 2 3 4 5 6 7 8 9 10 11

退出次序:  4    1       2       3           以此类推.....     

输入样例:

11 3

输出样例:

4 10 1 7 5 2 11 9 3 6 8 

(这题老定式思维,想着怎么求余让数组遍历到末尾从头开始,脑子转不动了,不写了今天)

void CountOff( int n, int m, int out[] )
{
    for(int i=0;i<n;i++)
        out[i]=0;
    int step=0,count=1;
    while(count<=n)
    {
        for(int i=0;i<n;i++)
        {
            if(out[i]==0)
                step++;
            if(step==m)
            {
                out[i]=count++;
                step=0;
            }
        }
    }
}

38.本题要求实现函数,可以返回一个给定月份的英文名称。

函数接口定义:

char *getmonth( int n );

函数getmonth应返回存储了n对应的月份英文名称的字符串头指针。如果传入的参数n不是一个代表月份的数字,则返回空指针NULL。

char *getmonth( int n )
{
    //用char month[][20]定义会出错  注意(经常犯这种错)
    //用char *month[]定义二维数组比较方便,且能避免很多问题
    char *month[]={"January","February","March","April","May","June",
"July","August","September","October","November","December"};
    if(n>12||n<=0)
        return NULL;
    else
        return month[n-1];
}

39.本题要求实现一个函数,用于计算有n个元素的指针数组s中最长的字符串的长度。

#include<string.h>
int max_len( char *s[], int n )
{
    int max=0;
    for(int i=0;i<n;i++)
    {
        int len=strlen(s[i]);
        if(len>max)
            max=len;
    }
    return max;
}

//不过JLU通常不让用string.h,建议如下代码
int max_len( char *s[], int n )
{
    int max=0;
    for(int i=0;i<n;i++)
    {
        int len=0;
        for(len=0;s[i][len]!='\0';len++);
        if(len>max)
            max=len;
    }
    return max;
}

40.本题要求编写函数,将输入字符串t中从第m个字符开始的全部字符复制到字符串s中。

void strmcpy( char *t, int m, char *s )
{
    int len=0;
    for(int i=0;t[i]!='\0';i++)
        len++;
    if(len<m)
        *s=NULL;
    int j=0;
    for(int i=m-1;i<len;i++)
    {
        s[j++]=t[i];
    }
    s[j]='\0';
}

41.本题要求实现一个删除字符串中的指定字符的简单函数。

函数接口定义:

void delchar( char *str, char c );

其中char *str是传入的字符串,c是待删除的字符。函数delchar的功能是将字符串str中出现的所有c字符删除。

void delchar( char *str, char c )
{
    int len=0;
    for(len=0;str[len]!='\0';len++);
    for(int i=0;i<len;i++)
    {
        if(str[i]==c)
        {
            for(int j=i;j<len-1;j++)
                str[j]=str[j+1];
            len--;
            i--;
        }
    }
    str[len]='\0';
    
}

42.本题要求编写函数,判断给定的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。如“XYZYX”和“xyzzyx”都是回文。

bool palindrome( char *s )
{
    int len=0;
    for(int i=0;s[i]!='\0';i++)
        len++;
    for(int i=0;i<len/2;i++)
        if(s[i]!=s[len-i-1])
            return false;
    return true;
}

43.本题要求实现一个函数,统计给定字符串中的大写字母、小写字母、空格、数字以及其它字符各有多少。

void StringCount( char *s )
{
    int upper=0,lower=0,blank=0,digit=0,other=0;
    for(int i=0;s[i]!='\0';i++)
    {
        if(s[i]>='A'&&s[i]<='Z')
            upper++;
        else if(s[i]>='a'&&s[i]<='z')
            lower++;
        else if(s[i]==' ')
            blank++;
        else if(s[i]>='0'&&s[i]<='9')
            digit++;
        else 
            other++;
    }
    printf("%d %d %d %d %d",upper,lower,blank,digit,other);
}

44.本题要求实现一个计算复数之积的简单函数。

struct complex multiply(struct complex x, struct complex y)
{
    struct complex res;
    res.real=x.real*y.real-x.imag*y.imag;
    res.imag=x.real*y.imag+x.imag*y.real;
    return res;
}

45.本题要求实现一个根据学生成绩设置其等级,并统计不及格人数的简单函数。

int set_grade( struct student *p, int n )
{
    int count=0;
    for(int i=0;i<n;i++)
    {
        if(p[i].score<60){
            p[i].grade='D';
            count++;
        }
        else if(p[i].score<70)
            p[i].grade='C';
        else if(p[i].score<=84)
            p[i].grade='B';
        else
            p[i].grade='A';
    }
    return count;
}

46.本题要求实现一个用递归计算1+2+3+…+n的和的简单函数。

函数接口定义:

int sum( int n );

该函数对于传入的正整数n返回1+2+3+…+n的和;若n不是正整数则返回0。题目保证输入输出在长整型范围内。建议尝试写成递归函数。

int sum( int n )
{
    if(n<=0)
        return 0;
    if(n==1)
        return 1;
    return n+sum(n-1);
}

47.本题要求实现一个函数,统计给定区间内的三位数中有两位数字相同的完全平方数(如144、676)的个数。

函数接口定义:

int search( int n );

其中传入的参数int n是一个三位数的正整数(最高位数字非0)。函数search返回[101, n]区间内所有满足条件的数的个数。

int search( int n )
{
    int count=0;
    for(int i=11;i*i<n;i++)
        if((i*i/100==i*i/10%10)||(i*i/100==i*i%10)||(i*i/10%10==i*i%10))
            count++;   
    return count;
}

48.本题要求实现一个计算非负整数阶乘的简单函数,并利用该函数求 1!+2!+3!+...+n! 的值。

double fact( int n )
{
    if(n<=1)
        return 1;
    return n*fact(n-1);
}
double factsum( int n )
{
    double sum=0;
    for(int i=1;i<=n;i++)
        sum+=fact(i);
    return sum;
}

49.本题要求实现一个计算xn(n≥1)的函数。

double calc_pow( double x, int n )
{
    double xn=1;
    for(int i=1;i<=n;i++)
        xn*=x;
    return xn;
}

//不好意思看错题了,让用递归做
double calc_pow( double x, int n )
{
    if(n==1)
        return x;
    return x*calc_pow(x,n-1);
}

50.本题要求实现一个函数,计算下列简单交错幂级数的部分和:

f(x,n)=x−x^2+x^3−x^4+⋯+(−1)^n−1*x^n

double fn( double x, int n )
{
    if(n==1)
        return x;
    return pow(-1,n-1)*pow(x,n)+fn(x,n-1);
}

51.习题10-5 递归计算Ackermenn函数

int Ack( int m, int n )
{
    if(m==0)
        return n+1;
    else if(n==0&&m>0)
        return Ack(m-1,1);
    else if(m>0&&n>0)
        return Ack(m-1,Ack(m,n-1));
}

52.本题要求实现求Fabonacci数列项的函数。Fabonacci数列的定义如下:

f(n)=f(n−2)+f(n−1) (n≥2),其中f(0)=0,f(1)=1。

int f( int n )
{
    if(n==0)
        return 0;
    else if(n==1)
        return 1;
    else return f(n-1)+f(n-2); 
}

53.本题要求实现一个函数,将非负整数n转换为二进制后输出。

void dectobin(int n)
{
    if(n>1){
        dectobin(n/2);
    }
    printf("%d",n%2);
}

54.本题要求实现一个函数,对一个整数进行按位顺序输出。

void printdigits( int n )
{
    if(n>9)
        printdigits(n/10);
    printf("%d\n",n%10);
}

55.本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中所有存储了某给定值的结点删除。链表结点定义如下:

struct ListNode {
    int data;
    ListNode *next;
};

函数接口定义:

struct ListNode *readlist(); struct ListNode *deletem( struct ListNode *L, int m );

函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。

函数deletem将单链表L中所有存储了m的结点删除。返回指向结果链表头结点的指针。

struct ListNode *readlist()
{
    struct ListNode *head=malloc(sizeof(struct ListNode));
    head->next=NULL;
    struct ListNode *cur=head,*tail=head;
    int n;
    while(scanf("%d",&n),n!=-1)
    {
        struct ListNode *node=malloc(sizeof(struct ListNode));
        node->data=n;
        tail->next=node;
        tail=node;
    }
    tail->next=NULL;
    return head->next;
}
struct ListNode *deletem( struct ListNode *L, int m )
{
    struct ListNode *dummy=malloc(sizeof(struct ListNode));
    dummy->next=L;
    struct ListNode *cur=dummy;
    while(cur->next!=NULL)
    {
        if(cur->next->data==m)
            cur->next=cur->next->next;
        else
            cur=cur->next;
    }
    return dummy->next;
    
}

56.本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。链表结点定义如下:

struct ListNode {
    int data;
    ListNode *next;
};

函数接口定义

struct ListNode *readlist(); struct ListNode *getodd( struct ListNode **L );

函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。

函数getodd将单链表L中奇数值的结点分离出来,重新组成一个新的链表。返回指向新链表头结点的指针,同时将L中存储的地址改为删除了奇数值结点后的链表的头结点地址(所以要传入L的指针)。

struct ListNode *readlist()
{
    struct ListNode *head=malloc(sizeof(struct ListNode));
    head->next=NULL;
    struct ListNode *cur=head,*tail=head;
    int n;
    while(scanf("%d",&n),n!=-1)
    {
        struct ListNode *node=malloc(sizeof(struct ListNode));
        node->data=n;
        tail->next=node;
        tail=node;
    }
    tail->next=NULL;
    return head->next;
}

struct ListNode *getodd( struct ListNode **L )
{
    struct ListNode *dummy=malloc(sizeof(struct ListNode));
    dummy->next=*L;
    struct ListNode *cur=dummy;
    struct ListNode *odd=malloc(sizeof(struct ListNode));
    odd->next=NULL;
    struct ListNode *tail=odd;
    while(cur->next!=NULL)
    {
        if(cur->next->data%2==1)
        {
            struct ListNode *node=malloc(sizeof(struct ListNode));
            node->data=cur->next->data;
            tail->next=node;
            tail=node;
            cur->next=cur->next->next;
        }else
            cur=cur->next;
    }
    tail->next=NULL;
    *L=dummy->next;
    return odd->next;
}

57.本题要求定义一个函数,在字符串中查找字符,并定位在最后一次找到的位置。

函数接口定义:

char * match(char *s, char ch);

其中s是字符串首地址,ch是要查找的字符。要求函数在字符串s中查找字符ch,如果找到,返回最后一次找到的该字符在字符串中的位置(地址);否则,返回空指针NULL。

char * match(char *s, char ch)
{
    int len=0;
    char *temp=NULL;
    for(int i=0;s[i]!='\0';i++)
        len++;
    for(int i=len-1;i>=0;i--)
        if(s[i]==ch)
        {
            temp=&s[i];
            break;
        } 
    return temp;
}

58.本题要求实现一个函数,将两个字符串连接起来。

函数接口定义:

char *str_cat( char *s, char *t );

函数str_cat应将字符串t复制到字符串s的末端,并且返回字符串s的首地址。

char *str_cat( char *s, char *t )
{
    int i=0;
    for(i=0;s[i]!='\0';i++);
    int j=0;
    for(j=0;t[j]!='\0';j++);
    int count=0;
    for(int k=i;k<i+j;k++)
        s[k]=t[count++];
    return &s[0];
}

59.本题要求实现函数,可以根据下表查找到星期,返回对应的序号

int str_cmp(char *str1,char *str2)
{
    while(*str1!='\0'&&*str2!='\0')
    {
        if(*str1>*str2)
            return 1;
        else if(*str1<*str2)
            return -1;
        str1++;
        str2++;
    }
    if(*str1!='\0')
        return 1;
    else if(*str2!='\0')
        return -1;
    else 
        return 0;
}
int getindex( char *s )
{
    char *week[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
    for(int i=0;i<7;i++)
    {
        if(str_cmp(s,week[i])==0)
        {
            return i;
            break;
        }
    }
    return -1;
}

60.(无语了,卡了我20分钟,结果是我把modify函数想的太简单了。。。。)

习题10-11 有序表的增删改查操作

首先输入一个正整数N(1≤N≤1000)和一个无重复元素的、从小到大排列的、N个元素的有序表,然后在屏幕上显示以下菜单(编号和选项)。

[1] Insert
[2] Delete
[3] Update
[4] Query
[Other option] End

用户可以反复对该有序表进行插入、删除、修改和查找操作,也可以选择结束。当用户输入编号14和相关参数时,将分别对该有序表进行插入、删除、修改和查找操作,输入其他编号,则结束操作。本题要求实现4个函数,分别在有序表(数组)中插入、删除、修改、查找一个值。

int insert(int a[ ], int value)
{
    for(int i=0;i<Count;i++)
    {
        if(a[i]==value)
            return -1;
        if(a[i]>value)
        {
            for(int j=Count;j>i;j--)
            {
                a[j]=a[j-1];
            }
            Count++;
            a[i]=value;
            return 0;
        }
    }
    a[Count]=value;
    Count++;
    return 0;
}  
int del(int a[ ], int value)
{
    int flag=0;
    for(int i=0;i<Count;i++)
    {
        if(a[i]==value)
        {
            flag=1;
            for(int j=i;j<Count-1;j++)
                a[j]=a[j+1];
            Count--;
            return 0;
        }
    }
    return -1;
}
int modify(int a[ ], int value1, int value2)
{
    for(int i=0;i<Count;i++)
    {
        if(a[i]==value2)
            return -1;
    }
    for(int i=0;i<Count;i++)
    {
        if(a[i]==value1)
        {
            del(a,value1);
            insert(a,value2);   //我傻傻以为这儿a[i]=value2就行,忘了得保持有序了!
            return 0;
        }  
    }
    return -1;
}
int query(int a[ ], int value)
{
    int low=0,high=Count-1;
    while(low<=high)
    {
        int mid=(low+high)/2;
        if(a[mid]==value)
            return mid;
        else if(a[mid]>value)
            high=mid-1;
        else
            low=mid+1;
    }
    return -1;
}

61.本题要求实现一个函数,对给定的一个字符串和两个字符,打印出给定字符串中从与第一个字符匹配的位置开始到与第二个字符匹配的位置之间的所有字符。(这段也卡挺久,总是想复杂了)

char *match( char *s, char ch1, char ch2 )
{
    int *p;
    p=NULL;
    int i=0;
    while(s[i]!='\0'&&s[i]!=ch1)
        i++;
    p=&s[i];
    while(s[i]!='\0'&&s[i]!=ch2)
        printf("%c",s[i++]);
    if(s[i]==ch2)
        printf("%c",s[i]);
    printf("\n");
    return p;  
}
62.本题要求实现一个字符串查找的简单函数。(参考别人的,得再看看)
char *search( char *s, char *t )
{
    char *index=s;
    char *p=index,*q=t;
    while(*index)
    {
        while(*q)
        {
            if(*q==*p)
            {
                q++;
                p++;
            }
            else
                break;
        }
        if(*q)
        {
            index++;
            p=index;
            q=t;
        }
        else
            break;
        
    }
    if(*index=='\0')
        index=NULL;
    return index;
}

  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值