• C博客作业--指针


    C博客作业--指针

    一、PTA实验作业

    题目1:判断回文字符串

    1. 本题PTA提交列表(要提交列表,不是结果)

    2. 设计思路(伪代码或流程图)

    伪代码:

    函数传入数组名即地址,给形参s
    定义ij为循环变量
    for i=0 to s【i】!=''
    end
    i--
    j=0
    while (1)
        如果s【i】==s【j】首尾字符相等
            如果比较的字符相遇则停止循环
            i--
            j++
        否则 返回0 结束循环
    end
    返回1
    

    流程图:

    3.代码截图(注意,截图,截图,截图。不要粘贴博客上。不用用···语法去渲染)

    4.本题调试过程碰到问题及PTA提交列表情况说明。

    答案错误
    第一次没有考虑到奇数和偶数字符串的关系,结束循环的条件只写了ij时的情况,导致答案错误
    解决方法:加了j
    i+1的结束条件就可以了

    题目2:求子串在母串中最后一次出现的地址

    1. 本题PTA提交列表(要提交列表,不是结果)

    2. 设计思路(伪代码或流程图)

    传入数组s
    定义循环变量i,j,mark用于比较子串,mark2记录地址,flag判断是否为子串
    for i=0 to s【i】!=‘’
        mark=i记录比较开始的位置
        for j=0 to s【j】!=‘’
            如果该位置的字符与子串第一个相同比较下一个字符,都相同flag=0
            如果不相同flag=1
        如果flag==0,mark2记录i
    end
    如果mark2没有变化返回null
    否则返回s【mark2】的地址
    

    3.代码截图(注意,截图,截图,截图。不要粘贴博客上。不用用···语法去渲染)

    4.本题调试过程碰到问题及PTA提交列表情况说明。

    答案错误
    1.刚开始未有设计返回空指针,导致答案一直错误
    解决方法:如果mark2没有被改变,表明没有找到过子串,所以这个时候就要返回空指针
    2.只找到第一个出现子串的地址
    解决方法:将程序设为反复查找,并写再一次找到的地址会覆盖掉第一次查找的地址,最后的结果就是最后的地址
    3.返回地址的问题:刚开始习惯直接返回数组名,但是显然不行
    解决方法:用&,取出s【mark】的地址

    题目3:字符串串动变化

    1. 本题PTA提交列表(要提交列表,不是结果)

    2. 设计思路(伪代码或流程图)

    传入数组p
    定义循环变量i,max存最大ASCII码最大的字符,t由于交换,code存最大码的下标
    max先取p【0】code取0
    for i=1 to p【i】!=‘’
        if p【i】>max 将p【i】写入max,code保存i
    end
    先用t存p【code】即找到最大的字符
    for i=code to 1
        code的字符右移
    end
    t存的字符给第一个字符
    

    3.代码截图(注意,截图,截图,截图。不要粘贴博客上。不用用···语法去渲染)

    4.本题调试过程碰到问题及PTA提交列表情况说明。


    问题如图,字符e消失,而A多了一个,明显是交换时发生的错误
    解决方法:最后t的值不应该给p【i-1】,因为上一轮循环,i最后跳出时有发生了递减,所以,我的做法是直接交给p【0】

    二、截图本周题目集的PTA最后排名。

    三、阅读代码

    • 猴子选大王
      让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。
    #include<stdio.h>  
    int main()  
    {  
        int i, j, k, temp;  
        int monkey[1001];//总数不能大于1000  
        unsigned int n;  
        scanf("%d", &n);//输入猴子总数  
        for (i = 0; i < n; i++){  
            monkey[i] = i + 1;//给猴子排序,站成一排  
        }  
        for (i = n - 1; i >= 0; i--){  
            for (k = 1; k <= 3; k++){  
                temp = monkey[0];  
                for (j = 0; j < i; j++){  
                    monkey[j] = monkey[j + 1];  
                }  
                monkey[i] = temp;  
            }  
        }  
        printf("%d", monkey[0]);//数组头就是猴王  
        return 0;  
    }  
    

    功能:选出猴王
    优点:通常的思路是考虑下标移动和删除第三个位置,但是改代码思路新颖,不去考虑下标移动和删除,而是简单的做数组数字移动,巧妙的将数到3这个步骤替换成数组数据的移动3次,第3个数就会刚好排到数组尾,再在剩下的数之间移动,第3的数就会渐渐排到后面,最后数组头就是“猴王”。当初做这道题时感觉题目会很复杂,想了好久,一点思路都没有,关键是围成一个圈,数到最后还要接到数组头,然后上网查了很多很长的代码,直到找到这个代码,原来十几行就可以了。

    • 最大公共子串
      求两个串的所有子串中能够匹配上的最大长度是多少。
      比如:"abcdkkk" 和 "baabcdadabc",
      可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。
      下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。
    #include <stdio.h>  
    #include <string.h>  
      
    #define N 256  
    int f(const char* s1, const char* s2)  
    {  
        int a[N][N];  
        int len1 = strlen(s1);  
        int len2 = strlen(s2);  
        int i,j;  
          
        memset(a,0,sizeof(int)*N*N);  
        int max = 0;  
        for(i=1; i<=len1; i++){  
            for(j=1; j<=len2; j++){  
                if(s1[i-1]==s2[j-1]) {  
                    a[i][j] =a[i-1][j-1]+1; 
                    if(a[i][j] > max) max = a[i][j];  
                }  
            }  
        }  
          
        return max;  
    }  
      
    int main()  
    {  
        printf("%d
    ", f("abcdkkk", "baabcdadabc"));  
        return 0;  
    }
    

    题目思路:
    动态规划的思想,a[i][j]表示到字符串s1的i位置和s2的j位置的最大公共子串的长度 ,数组初始化为0。为了方便理解,我们这么想,如果s1的字符串的第一个字符和s2的第一个字符相同,那么a[1][1] = 1;如果两个字符串的第二个字符也相同,那么,到第二个位置的最长公共子串就等于1+1 = 2,也就是到第一个字符的公共子串的个数+1。即a[i][j] = 1+ a[i-1][j-1]。因此,我们可以从第一个位置开始递推求出到任意一个位置的公共子串,在递推过程中记录最大的结果即可。

    优点:巧妙的运用二维数组,通过遍历,对每个位置子串长度做了统计和比较,大大节省了时间,同时具有极高的效率。

    四、本周学习总结

    1.自己总结本周学习内容。

    1.使用指针基本应用
    利用指针的移动,代替数组下标法提高程序效率
    例:
    冒号排序函数用指针代替

    void bubble(int *a,int n)
    {
        int *i,*j,t;
        for(i=1+a;i<a+n;i++){
            for(j=a;j<a+n-1;j++){
                if(*j>*(j+1)){
                    t=*j;*j=*(j+1);*(j+1)=t;
                }
            }
        }
    }
    

    数组名即地址,定义两个指针,遍历数组只需指针的移动即可,下标法需要交换数组的数,指针则只要交换地址即可,效率远比下标法搞得多
    2.数组与指针是相通的,数组就是const 类型的指针,不能随意修改,但是指针就可以
    3.字符型指针,指针类型都是指向变量的类型,所以字符指针指向字符,当字符指针指向字符数组时,指针名即数组的首字符的地址,即p【0】等价于*str,p【i】等价于*(str+i)
    4.字符串再C语言中会自动生成地址保存它们,所以字符串可以直接赋值给指针变量,即char *p=“string”;这个字符串叫做字符串常量。

    2.罗列本周一些错题。

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

    void CountOff( int n, int m, int out[] ){  
        int i=0,j=0,k=0,cnt=0,a[MAXN];  
        for(i=0;i<n;i++)  
            a[i] = i+1;
        i=0;  
        while(cnt < n){  
            if(a[i]!=0) k++;  
            if(k==m){  
                j++;  
                out[i]=j;  
                k=0;  
                cnt++;  
                a[i]=0;  
            }  
            i++;  
            if(i==n) i=0;  
        }  
    } 
    

    这道题想了很久都没有思路,上网查了一下,居然只有这么短。后来理解了这题,通过in时,i0将数组连成一个圈,将数到的数变成0而做到可以跳过这个数。

  • 相关阅读:
    多维梯度下降
    梯度下降
    三种评价函数
    Gluon sgd
    Gluon.vision的几类数据集
    Gluon Data API
    Gluon 实现 dropout 丢弃法
    AlexNet 分类 FashionMNIST
    LeNet 分类 FashionMNIST
    LeNet
  • 原文地址:https://www.cnblogs.com/doimpossible/p/8027226.html
Copyright © 2020-2023  润新知