• 第二次博客作业


    目录:

    • 薄弱的知识点

    • 有挑战性的题目


    薄弱的知识点:

    1. 对字符串的处理不熟悉,尤其是对字符串的处理函数(strcat,strcpy,strcmp)的运用。
    2. 二维数组作为形参来传递不熟悉,编译器经常报错 cannot convert from 'int*' to 'int* *'
    3. 指针的运用不清晰,编译器经常报错段错误,后来我通过查询了解到段错误的原因及解决方法,下面是对应的连接:

    有挑战性的题目:

     1. PTA 10 7-4 从小到大输出字符串 

      任意输入三个字符串,按从小到大顺序输出。编程要求:⑴在主函数中定义三个字符数组str1[]、str2[]、str3[],输入三个字符串分别存入这三个字符数组中。⑵将str1、str2、str3三个字符数组的指针传递给被调函数。⑶被调函数swap(char *, char *, char *)中做字符串变量值的交换。⑷返回主函数后,变量str1中是初始三个字符串中的最小者,变量str1中是初始三个字符串中的最大者,输出str1、str2、str3三个字符串的值。

    输入格式:

    输入共三行,每行是一个字符串。

    输出格式:

    从小到大输出三个字符串。

    输入样例:

    在这里给出一组输入。例如:

    hello,world
    hello,Judy
    hello

    输出样例:

    在这里给出相应的输出。例如:

    hello
    hello,Judy
    hello,world
    

      下面是我的代码:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    void swapa(char *a,char *b,char *c);
    int main()
    
    {
    	char str1[20],str2[20],str3[20];
    	cin.getline(str1,20);
    	cin.getline(str2,20);
    	cin.getline(str3,20);
    	swapa(str1,str2,str3);
    	//cout<<str1<<endl<<str2<<endl<<str3<<endl;
    } 
    void swapa(char *a,char *b,char *c)
    {
    	if(strlen(a)>strlen(b)&&strlen(b)>strlen(c))
    	{
    		swap(a,c);
    	}
    	if(strlen(a)>strlen(c)&&strlen(c)>strlen(b))
    	{
    		swap(c,b);
    		swap(a,c);
    	}
    	if(strlen(b)>strlen(a)&&strlen(a)>strlen(c))
    	{
    		swap(a,c);
    		swap(b,c);
    	}
    	if(strlen(b)>strlen(c)&&strlen(c)>strlen(a))
    	{
    		swap(b,c);
    	}
    	if(strlen(c)>strlen(a)&&strlen(a)>strlen(b))
    	{
    		swap(a,b);
    	}
    	cout<<a<<endl<<b<<endl<<c<<endl;
    }
    

      我一开始想到运用strlen函数进行比较,把其当作一道排序,而且并没有考虑到输入输出方面的优化,而且这道题更适合运用strcmp来进行比较。例如:

    if(strcmp(str1,str2)>0)
    

      最后由于在标准输入输出流中,存在swap已经被定义,存在

    std::swap
    

     所以直接使用会报错,我就用swapa来代替副函数名,当然也有其他做法。比如不用命名空间

    #include <iostream.h>
    int main()
    

      2 .  PTA 10 7-1 拷贝奇数字符 

    在主函数中输入字符串str1,调用函数将str1中下标为奇数的字符取出构成一个新的字符串放入字符串str2中(要求被调函数参数为str1和str2),在主函数中输出结果字符串str2。若输出的字符串为空串,输出 "empty string" 。要求函数用指针变量作形参。

    输入格式:

    一个字符串,以回车结束。

    输出格式:

    输出由奇数下标的字符组成的新字符串。

    输入样例:

    在这里给出一组输入。例如:

    12345

    输出样例:

     24

    在这里给出相应的输出。例如:

      我一开始只是想通过在主函数中通过strlen函数来进行str2为空串的判断,却忽略了首格为空的错误情况,在是我开始时的代码(在sample4上报错不通过)

    #include<iostream>
    #include <string.h>
    #define N 10 
    using namespace std; 
    void  chage(char* str2,int n);
    int main() 
    {   
        char str1[N] ;
        cin>>str1; 
    
    	if (strlen(str1)>1)  
    	{
    		chage(str1,N);
    		cout<<str1<<endl;
    	}
    	else  cout<<"empty string"<<endl;
        return 0; 
    }   
    void chage(char* str2,int n)
    { 
        int c=0;
        char str1[N] = {0}; 
        for(int j=0;j<n;j++)
        { 
            if(j%2!=0) 
            {
                str1[c++]=str2[j];  
            } 
        } 
        strcpy(str2, str1);
    }
    

      其核心部分是在循环中通过下标数字是否为偶数来实现转录str2,并通过strcpy来完成与str1的交换(必须考虑是否有特殊情况导致发生变化,比如在本题中应是j%2!=0

    void chage(char* str2,int n)
    { 
        int c=0;
        char str1[N] = {0}; 
        for(int j=0;j<n;j++)
        { 
            if(j%2!=0) 
            {
                str1[c++]=str2[j];  
            } 
        } 
        strcpy(str2, str1);
    }
    

      当然也可以通过下标加二来实现

    int strPartCopy(char *s1, char *s2) {
     int len1=strlen(s1);
     for(int i=1,j=0; i<len1; i+=2,j++)
      s2[j]=s1[i];
     return strlen(s2);
    }
    

       这是我后来改正后的代码

    #include<iostream>
    #include<cstring>
    using namespace std;
    int strPartCopy(char *s1, char *s2) {
     int len1=strlen(s1);
     for(int i=1,j=0; i<len1; i+=2,j++)
      s2[j]=s1[i];
     return strlen(s2);
    }
    int main() {
     char str1[1000000],str2[1000000];
     int n;
     cin>>str1;
     n=strPartCopy(str1,str2);
     if(str2[0]=='') cout<<"empty string";
     else for(int i=0; i<n; i++)
       cout<<str2[i];
     return 0;
    }
    

         最后一次修改,经过多次在字符串处理问题上发生报错,我觉得对字符串的处理应该转成对int型数据的处理(比如运用strlen函数来处理,我所提出的这两道问题都是这样进行),另外除了会运用strcpy等函数,还应该认识memcpy等字符处理函数,例如PTA 9 7-3就是能运用memcpy来实现。

    这是PTA 9 7-3数组元素循环移动的题目:

    在主函数中输入10个整数到数组中,调用函数完成将数组循环移动k位(要求函数参数为⑴数组名 ⑵数组元素的个数 ⑶循环移动的位数k)。当K>0时,实现循环右移;当K<0时,实现循环左移。循环右移一位的意义是:将数组全体元素向后一个下标位置移动一个元素的位置,原数组最后一个元素移动到数组最前面第0个元素的位置。提示:当K<0时,转换成等价的循环右移。要求函数的形参是指针变量。

    输入格式:

    第一行是数组的10个整数; 第二行是k,表示循环左(右)移动的位数。

    输出格式:

    输出循环移位后的数组,以空格分隔。

    输入样例:

    在这里给出一组输入。例如:

    1 2 3 4 5 6 7 8 9 10
    3
    

      

    输出样例:

    在这里给出相应的输出。例如:

    8 9 10 1 2 3 4 5 6 7
    

      

             这是PTA 9 7-3的运用memcpy函数的代码

    #include <iostream>
    #include <cmath>
    #include <string.h>
    using namespace std;
    int *myfun(int *p,int n,int k){
        int *pt,tmp;
        k%=n;
        if((pt=new int[abs(k)])==NULL){
            exit(0);
        }
        tmp=sizeof(int);
        if(k>0){
            memcpy(pt,p+(n-k),tmp*k);
            memcpy(p+k,p,tmp*(n-k));
            memcpy(p,pt,tmp*k);
        }
        else if(k<0){
            k=-k;
            memcpy(pt,p,tmp*k);
            memcpy(p,p+k,tmp*(n-k));
            memcpy(p+(n-k),pt,tmp*k);
        }
        delete []pt;
        return p;
    }
    int main(void){
        int a[10],i,k;
        for(i=0;i<10;cin >> a[i++]);
        cin >> k;
        myfun(a,10,k);
        for(i=0;i<9;cout << a[i++] << " ");
        cout <<a[9]<< endl;
        return 0;
    }
    

      memcpy函数与strcpy函数很相进(strcpy和memcpy都是标准C库函数),都可以用来拷贝。

      strcpy和memcpy主要有以下3方面的区别。
    1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
    2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符""才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度
    3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

      内容部分来自于:https://blog.csdn.net/taric_ma/article/details/7383713



     两者实现方式:

      memcpy()的实现
    难点:1.指针类型的变换
             2.要防止内存拷贝时的相互覆盖

    #include <iostream>
    #include "assert.h"
    using namespace std;
    void* memcpy(void* dest,const void* source,int lengh)
    {
        assert((dest!=NULL)&&(source!=NULL));    //断言
      if(dest < source)
        {
            char* cdest = (char*)dest;
            const char* csource = (char*)source;
            for(int i=0;i<lengh;i++)
                *cdest++ = *csource++;
      return cdest;
        }
        else
        {
            char* cdest = (char*)(dest)+lengh-1;
            char* csource = (char*)(source)+lengh-1;
            for(int i=0;i<lengh;i++)
                *cdest-- = *csource--;
      return cdest;
        } 
        
    }
    int main()
    {
        char* a = "hello";
        char b[10];
     memcpy(b,a,10);
     for(int k=0;k<6;k++)
      cout << b[k] <<endl;
        return 0;
    }

    输出:

    h
    e
    
    l
    l
    o

     #include <assert.h>为设定插入点的头文件,在博客园中有关于assert函数的用法总结,这是其连接:http://www.cnblogs.com/ggzss/archive/2011/08/18/2145017.html


       如果换成strcpy()的实现。其副函数部分为

    char* strcpy(char* dest,const char* source)
    {
         assert(dest!=NULL&&source!=NULL);
         while((*dest++ = *source++) != '')
                                ;
         return dest;
    }


    用下面函数来看下memcpy与strcpy的区别:

    #include <iostream> 
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    int main()
    {
        char a[30] = "string (a)";
        char b[30] = "hizengxiaolong";
        int i;
    
        strcpy(a, b);             //a[30] = "hiing (a)"
        cout<<"strcpy():"<<'
    ';
        for(i = 0; i < 30; i++)
            cout<<a[i];   //hiing (a)
    
    
        memcpy(a, b, 30);         //a[30] = "hizengxiaolong"
        cout<<"
    memcpy():"<<endl;
        for(i = 0; i < 30; i++)
            cout<< a[i];   //hizengxiaolong
        cout<<'
    '<<"i = "<<i<<endl; //30
    
    }

    突然发现我好像离题了。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

    这题我当时做了很久,代码也很长,直到我偶然百度到memcpy ,瞬间减少一半多。。。。。。

      

  • 相关阅读:
    Android Studio 开发
    Jsp编写的页面如何适应手机浏览器页面
    电影
    Oracle 拆分列为多行 Splitting string into multiple rows in Oracle
    sql server 2008 自动备份
    WINGIDE 激活失败
    python安装 错误 “User installations are disabled via policy on the machine”
    ble编程-外设发送数据到中心
    iOS开发-NSString去掉所有换行及空格
    ios9 字符串与UTF-8 互相转换
  • 原文地址:https://www.cnblogs.com/yingni/p/10088869.html
Copyright © 2020-2023  润新知