第二次博客作业

目录:

  • 薄弱的知识点

  • 有挑战性的题目


 

薄弱的知识点:

 

  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]=='\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不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。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 = "he\0llo";
    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++) != '\0')
                            ;
     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] = "hi\0zengxiaolong";
    int i;

    strcpy(a, b);             //a[30] = "hi\0ing (a)"
    cout<<"strcpy():"<<'\n';
    for(i = 0; i < 30; i++)
        cout<<a[i];   //hiing (a)


    memcpy(a, b, 30);         //a[30] = "hi\0zengxiaolong"
    cout<<"\nmemcpy():"<<endl;
    for(i = 0; i < 30; i++)
        cout<< a[i];   //hizengxiaolong
    cout<<'\n'<<"i = "<<i<<endl; //30

}

 

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

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

  

 

posted @ 2018-12-08 19:59  yingni  阅读(389)  评论(0编辑  收藏  举报