2015 百度笔试的一道经典题目

请编码实现memcpy函数:void *memcpy(void *dst,const void *src,unsigned int count)  显然是内存复制函数

下面是本人结合memcpy的源代码实现的一个测试用例,请大家指点

#include <stdio.h>
void *memcpy(void *dst,const void *src,unsigned int count)
{
	char *p_dst = (char *)(dst);
	char *p_src = (char *)(src);
	unsigned int i;
	if(dst>src && p_dst<=(src+count-1))
	{
		while(count--)
		{
			*(p_dst+count-1) = *(p_src+count-1);
		}
	}
	else
	{
		for(i=0;i<count;i++)
		{
			*(p_dst+i) = *(p_src+i);
		}
	}
	return dst;
}
int main()
{
    int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    memcpy(arr+4,arr,sizeof(int)*6);// 这样的拷贝 src<dst && src+count-1>dst,也就是说已经产生了覆盖,
    //所以用从后往前的复制,进入if
    for(int i=0;i<10;i++)
        printf("%d\t",arr[i]);
//    memcpy(arr,arr+4,sizeof(int)*6);// 这样的拷贝 src>dst && src<dst+count-1,
//      这和正常的拷贝一样,进入else
//    for(int i=0;i<10;i++)
//        printf("%d\t",arr[i]);
    printf("\n");
    return 0;
}

1  有人可能会问:你的算法保证了任何情况下都能够把数据正确的复制到目的地址,但是你有没有考虑过在复制的过程中,你有可能修改了原始数据呢?

修改了原始串这样的功能明确么?

回答:对,老兄你说的很对,的确会存在这个问题,举个例子吧,比如hello
world,我们想把中间的空格去掉,滤掉空格就类似于操作系统中有一种内存分配方法,叫做可重地位分区分配,就是把小作业移动,去除中间的空隙,然后空出后面的一块大的内存地址,供其他程序使用。这样对原始数据不需要保存的情况下,可以应用这个函数。

2  可能你还有疑问:最后的dst+count = ‘\0‘ 假如传入的是char
型的数组,怎么办呢?你return dst如何判断空不空呢? ——  好吧,这也是我的问题,请大神们帮助解答????

3memcpy()
和 
普通 strncpy() 复制函数的区别,看代码吧,不多说了:

#include <iostream>
#include <cstring> // for c style string manipulation

using namespace std;

int main ()
{
    char str1[]= "To be or not to be";//  18 个字符(含空格)+ '\0' = 19 个字符,因为默认结尾有 '\0'
    cout << sizeof(str1) << endl;
    char str2[40];
    cout << str1 << endl;
    // copy to sized buffer (overflow safe):
    strncpy ( str2, str1, sizeof(str2) );
    cout << str2 << endl;
    // partial copy (only 5 chars):
    strncpy ( str2, str1, 5 );
    cout << str2 << endl;
    str2[5] = '\0';   // null character manually added
    cout << sizeof(str2) << " " << str2 << endl;

    strncpy(str1 + 3, str1, 6); // 出现内存覆盖问题
    cout << str1 ;

    return 0;
}
总结:strcpy 
  源字串全部拷贝到目标字串中,包括'\0',但是程序员必须保证目标串长度足够,且不与源串重叠。
  strncpy 
  如果目标长>=指定长>源长,则将源串全部拷贝到目标串,连同'\0' 
  如果指定长<源长,则将截取源串中按指定长度拷贝到目标字符串,不包括'\0',手动添加‘\0’,建议对于前两种都手动添加就可以了
  如果指定长>目标长,错误!
#include <iostream>
#include <cstring> // for c style string manipulation
using namespace std;
const int maxn = 8;
int main ()
{
    int i;
    char dest[]="Hell99iam!";// 10个字符,占了11个空间,最后一个'\0'
    char src[]="abc\0def";
    strncpy(dest,src,maxn);
    dest[maxn] = '\0';
    for(i=0;i<sizeof(dest);i++)
    {
        if(*(dest+i) == '\0')
            cout << "* ";
        else
            cout << *(dest+i) << " ";
    }
    cout << endl << dest << endl;
    char str[maxn];
    strncpy(str,src,1);
    for(i=0;i<sizeof(str);i++)
    {
        if(*(str+i) == '\0')
            cout << "* ";
        else
            cout << *(str+i) << " ";
    }
    //str[1] = '\0'; 如果没有这句话,就是下图的结果了
    cout << endl << str << endl;
    return 0;
}
/*
    (c/c++)复制字符串src中的内容(字符,数字、汉字....)到字符串dest中,复制多少由size_t的
    值决定,返回指向dest的指针。如果遇到空字符('\0')[1] ,则空字符后面全部为空(字符),maxn 决定有多少个空格

*/

3 中第一个函数的结果:

3 中第二个函数的结果:

4  void * memset ( void * ptr, int ch, size_t num );

函数的作用是: fill the first num bytes(注意不是element) of block of memory(由空指针ptr指向) with value.
最后我们会解释这句话的含义。在C++中,设计 size_t 就是为了适应多个平台的 。size_t的引入增强了程序在不同平台上的可移植性。size_t是针对系统定制的一种数据类型,一般是整型(int),因为C/C++标准只定义一最低的位数,而不是必需的固定位数。

/* memset example */
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 11;
int main ()
{
    int arr[maxn], i;
    char str[] = "almost every programmer should know memset!";

    memset(str, '-', 6);
    cout << str << endl;

    memset(arr,10,maxn*sizeof(int));
    for(i=0; i<maxn; i++) {
       cout << arr[i] << " ";
    }
    cout << endl;

    memset(arr,-1,maxn*sizeof(int));
    for(i=0; i<maxn; i++) {
       cout << arr[i] << " ";
    }
    cout << endl;

    return 0;
}

问题来了: 对于上例子中, 对char 型数组的初始化, 输出符合预期。 但是对于整型数组却不符合预期, 为什么呢。 答案就是memset 是对于memory block  是一个字节一个字节的赋值。 由于int 型数组一个int元素就有4个bytes, 当然不符合预期了。 相信改为0后就可以了, 另外改为-1 也可以:

结果如下:

时间: 2024-12-10 11:35:29

2015 百度笔试的一道经典题目的相关文章

2015年百度笔试汇总篇

给大家分享下~ ----- 来自:http://gointernetgo.com/textinterview/baidu/bdbs 百度2015校园招聘前端开发笔试题(大连站)-回忆版 2015百度校招用户行为分析研发工程师笔试题 2015百度校招多语言产品经理笔试经验分享(大连站) 2015百度校招产品运营笔试题(笔试时间2014-9-14,长春站) 2015百度校招产品经理笔试题(笔试时间2014-9-14) 2015百度校园招聘软件研发类笔试题 2015百度校园招聘机器学习数据挖掘工程师笔

百度笔试题目01

将一串很长的字符串中的baidu改成等长的单词(hello) 问题所在 用宏定义定义了一个值为100000的maxn,字符串的长度为10000,但是不知道满不满足百度笔试题目的很长的字符串 #include<stdio.h> #include<string.h> #define maxn 100000 int main() { long int len,i,num=0; int k,j; char s[maxn]; gets(s); len=strlen(s); for(i=0;i

约瑟夫环问题,一道经典的数据结构题目

问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号. 一般我们采用一个循环队列来模拟约瑟夫环的求解过程,但是如果n比较大的时候,采用模拟的方式求解,需要大量的时间来模拟退出的过程,而且由于需要占用大量的内存空间来模拟队列中的n个人,并不是一个很好的解法. 在大部分情况下,我们仅仅需要知道最后那个人的编号,而不是要来模拟一个这样的过程,在这种情况下,可以考虑是否存在着一种数学公式能够直接求出最后那个人的编号. 我们知道第一个人(编号

创新工场笔试、小米科技笔试、百度笔试 研发部门

创新工场笔试: 单选和编程题目 单选不怎么记得了,有几道比较难,这里记录一下 1)10个左右括号组成满足条件的方案数,这个典型的catalan数,也是一个X>=Y的组合问题,可以看一下组合相关知识求解: 2)K(M,N) 一个递推推导,我是推导一部分,然后找规律(好像是K(2,m)= 2*m+3) if M == 0 return N+1; if N == 0 return K(M,1); else return K(M-1,K(M,N-1)); 求K(3,3) 编程题目: 1) A,B,C 可

NYOJ 1058 部分和问题(经典题目dfs)

部分和问题 描述 给定整数a1.a2.--.an,判断是否可以从中选出若干数,使它们的和恰好为K. 输入 首先,n和k,n表示数的个数,k表示数的和. 接着一行n个数. (1<=n<=20,保证不超int范围) 输出 如果和恰好可以为k,输出"YES",并按输入顺序依次输出是由哪几个数的和组成,否则"NO" 样例输入 4 13 1 2 4 7 样例输出 YES 2 4 7 题目分析: 这是一道经典的dfs问题,好多公司也用它做过面试题,我们定义函数dfs

阿里2014笔试中红烧狮子头的题目

今年参加阿里实习生线上笔试的时候有一道红烧狮子头的题目,当时觉得挺有意思的,今天在和师兄们聊天的时候跟他们说了这道题,然后就顺便把当时的思路写下来吧(ps:当时一个同学在这道题上帮了我很大的忙,给我提供了思路). 题目: 小张非常喜欢阿里巴巴西溪园区2号餐厅的红烧狮子头,每次都在餐厅里寻找这个菜的窗口.但餐厅不是每次都会供应,餐厅师傅会随机挑选菜品.每周(工作日,周一至周五)所有菜品至少会出现一次.2号餐厅有5个窗口,每个窗口的荤菜都是不同的.今天是周四,本周小张还没尝到红烧狮子头,他隐约觉得今

数学 2015百度之星初赛2 HDOJ 5255 魔法因子

题目传送门 1 /* 2 数学:不会写,学习一下这种解题方式:) 3 思路:设符合条件的数的最高位是h,最低位是l,中间不变的部分为mid,由题意可得到下面的公式(这里对X乘上1e6用a表示,b表示1e6) 4 (h*power+l+mid)*a = (l*power+h+mid)*b 5 可推得:mid = ((h*power+l) * a - (l*power+h) * b) / (a - b); 6 所以可以枚举h,l然后求mid,注意mid的最低位一定是0,因为留出最低位加l或者h 7

牛顿迭代法与一道经典编程问题

牛顿迭代法(Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method).它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法. 既然牛顿迭代法能够用来求解方程的根,那么最好还是以方程 x2=n 为例,来试着求解它的根. 为此. 令f(x)=x2?n, 也就是相当于求解 f(x)=0 的解.如上图所看到的. 首先随便找一个初始值 x0,假设 x0不是解,做一个经过 (x0,f(x0)) 这个点的切线,与x轴的交点为x1.相同的道理.假

一道算法题目, 二行代码, Binary Tree

June 8, 2015 我最喜欢的一道算法题目, 二行代码. 编程序需要很强的逻辑思维, 多问几个为什么, 可不可以简化.想一想, 二行代码, 五分钟就可以搞定; 2015年网上大家热议的 Homebrew 的作者 Max Howell 面试 Google 挂掉的一题, 二叉树反转, 七行代码, 相比二行代码, 情有可原! Problem: return the count of binary tree with only one child 想一想, 你要写几行, 六七行, 或小于十行? S