• 考试周前最后一次总结,主要关于字符串类问题


    一些特殊的字符串类型问题

    我们现在已经结束了第一学期的学习,不知道大家收获如何,但是希望大家不要止步于考试能过的程度,而是深入一些,理解透一些,为未来的学习打下坚实的基础。

    我们最后学习了数组以及字符串数组,一般类型的问题以及足以 解决,但是有一些典型问题还是需要去深入讨论一下,那么我们以期末的实验测试题为例,相信大家还有印象。

    (题目摘自PTA)

    7-8 到底有多二(15 分)

    一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值。如果这个数是负数,则程度增加0.5倍;如果还是个偶数,则再增加1倍。例如数字-13142223336是个11位数,其中有3个2,并且是负数,也是偶数,则它的犯二程度计算为:3/11×1.5×2×100%,约为81.82%。本题就请你计算一个给定整数到底有多二。

    输入格式:

    输入第一行给出一个不超过50位的整数N。

    输出格式:

    在一行中输出N犯二的程度,保留小数点后两位。

    输入样例:

    -13142223336
    

    输出样例:

    81.82%
    

    那么我们先对题目进行分析,第一句 ,主要为(包含‘2’的个数),那么显然是 一个需要用到数组遍历的环节,其次“负数”,这里是一个特殊测试点,但我们先不进行处理,“偶数”,同上,我们先略过,之后我们观察样例易得,“二”的程度首先取决于‘2’的个数,这是该问题的一般性,其余的均为特殊性,先不做处理,之后我们观察输入格式 ,重点来了,如果是一般的数据处理显然该题目是容易完成的,但是其中的关键问题在于“50位”,显然,该题目涉及到高位数的处理,要知道,在C语言中,unsigned long long 型的范围也只能到20位数,这里显然是提示我们,需要用到字符串数组 ,那么其余的问题就简单了,下面给出代码:

    #include<stdio.h>
    #include<string.h>
    int main(void)
    {
        char ch[100] = {''};     //定义数组存储所给数
        int count = 0,i = 0;      //定义循环变量以及计数器
        double pow = 0.0;        //定义double型存储乘积,即“犯二”程度
        gets(ch);               //输入数据     
        for(i = 0;i < strlen(ch);i++) //首先从一般性入手,查找‘2’的个数
        {
    	    if(ch[i] == '2')
    	    {
    		    count++;
    	    }
        }
        if(ch[0] == '-')        //接着,由于负号影响所给数的实际位数判断,因此首先分析该特殊情况
        {
    	    pow = count / (double)(strlen(ch) - 1);   //若为负,则总位数减1
    	    pow *= 1.5;
        }
        else
        {
    	    pow = count / (double)strlen(ch);   //若无特殊情况,则直接计算
        }
        if((ch[strlen(ch) - 1] - '0') % 2 == 0)     //由于判断某数是否为偶只需判断个位,那么我们只需判断最后一位即可
        {
    	    pow *= 2;
        }
        pow *= 100;                   //转换为百分制的格式
        printf("%.2f%%",pow);        //输出
        return 0;
    }
    

    至此,该题目解决。

    下面给出一些小总结。字符串数组常用于高位数据的处理问题,由于已给出的几种类型可能造成的内存溢出问题,因此我们对于高位的数据只能由数组保存,以字符串数组为方法解决的问题的一个显著特征就是高位,所以在拿到题前一定要先审清题目类型,可以节约宝贵的时间。

    下面给出字符串数组的另外一种用法,即高位数的运算问题。

    上面提到过,高位数我们可以依靠字符串数组来存储,那么运算可以实现吗,实际上是可以的,请回忆一下小学时期是如何进行四则运算的,即末位对齐,分别计算,那么同理,我们只需将两个高位数的末位对齐,再进行计算,最后进位即可,下面给出代码:

    #include<stdio.h>
    #include<string.h>
    int main(void)
    {
        char num1[100] = {''},num2[100] = {''},t = '';  //设置两个字符串型数组存放待计算的数
        int i = 0,j = 0,l1 = 0,l2 = 0;    //设置两个变量来存放两数的位数  ,以及循环变量
        gets(num1);     //输入数1
        gets(num2);     //输入数2
        l1 = strlen(num1);          //计算两数位数
        l2 = strlen(num2);
        j = l1 - 1;                 //将最后一位对齐
        for(i = l2 - 1;i >= 0;i--,j--)         //开始将两数由末位相加,这里笔者将数2加到数1中
        {
            t = num2[i] - '0';
            num1[j] += t;
        }
        for(i = l1 - 1;i > 0;i--)      //上面加和完成后,开始遍历数组,查找所有比9大的值,并逆向进位
        {
            if(num1[i] - '0' > 9)
            {
    	        num1[i - 1]++;
    	        num1[i] -= 10;
            }
        }
        if(num1[0] > '9')                //最后判断首位是否需要进位 
        {
    	    t = num1[0];
    	    num1[0] = '0';
    	    for(i = l1 - 1;i >= 0;i--)   //若需要,则将所有元素后移 
    	    {
    		    num1[i + 1] = num1[i];
    	    }
    	    num1[1] = t - 10;
    	    num1[0]++;
        }
        puts(num1);      //输出
        return 0;
    }
    

    这里笔者只给出加法运算,减法以及乘法同理,只要遵循相应的运算法则即可,除法由于涉及到浮点数,因此先不考虑。
    其次,笔者在此所给的代码并不严谨,实际上数1的位数是要严格大于数1的,实际上要改进也并不困难,只需要在初始时判断两数长度即可,在此笔者仅想展示该种方法。

    由于期末考试临近,篇幅有限,最后再给出一个经典算法,用以快速求最大公约数(GCD),该方法由欧几里得发明,因而被称为欧几里得算法。

    对于常规算法,我们判断最大公约数是采取枚举法,即从1~较小数为止,寻找满足能被两数同时取模为0的数,最坏情况下,可能要取到较小数为止,加上期间的取模运算,实际上是相当耗费时间的,当然我们可以用到欧几里得算法,该算法的时间复杂度为O(logB)下面给出函数:

    int GCD(int A,int B)              //传入两个正整数A,B 
    {
        int t = 1;                    //设置中间变量 
        while(t)
        {
    	    t = A % B;                //记录A 与 B第n次取模的结果 
    	    A = B;                    //将A B与t的值进行迭代 
    	    B = t;
        }
        return A;                     //当A B取模为零时,算法结束 ,返回最后一次的结果
    }
    

    数学上的证明由于时间有限在此不做解释了...最后祝大家考试顺利。

  • 相关阅读:
    自考新教材--p78
    自考新教材--p76_2
    自考新教材--p76_1
    自考新教材--p75
    自考新教材--p70
    自考新教材--p69
    以HTML5及其衍生技术为基础的B/S架构实时视频监控解决方案
    智能化安防视频监控行业发展是如何转变的?
    摄像头视频监控是如何与流媒体服务器云平台连接的?
    如何实现摄像头监控数据实时存储及传输?
  • 原文地址:https://www.cnblogs.com/Reloaded/p/8215138.html
Copyright © 2020-2023  润新知