2013网易实习生招聘笔试题

选择题:ios

一、二维数组int a[3][4],下列能表示a[1][2]的是?程序员

A.*(*(a+1)+2)    B.*(a+3)    C.(&a[0]+1)[2]    D.(a[0]+1)算法

二、short a[100],则sizeof(a)的值是?编程

A.2     B.4    C.200    D.400数组

问答题:函数

一、解释说明static、const和volatile两个关键字的做用?工具

关键字static有三个明显的做用:
一、在函数体,一个被声明为静态的变量在这一函数被调用过程当中维持其值不变。
二、 在模块内(但在函数体外),一个被声明为静态的变量能够被模块内全部函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
三、在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。测试

const 有什么用途?
一、能够定义 const 常量
二、const能够修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,能够预防意外的变更,能提升程序的健壮性。优化

volatile问题:spa

volatile的做用: 做为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。。。
volatile的语法与const是同样的,可是volatile的意思是“在编译器认识的范围外,这个数据能够被改变”。不知何故,环境正在改变数据(可能经过多任务处理),因此,volatile告诉编译器不要擅自做出有关数据的任何假设——在优化起家这是特别重要的。若是编译器说:“我已经把数据读入寄存器,并且在没有与寄存器接触。”在通常状况下,它不须要再读入这个数据。可是,若是数据是volatile修饰的,编译器则是不能作出这样的假定,由于数据可能被其余进程改变了,编译器必须从新读这个数据而不是优化这个代码。就像创建const对象同样,程序员也能够创建volatile对象,甚至还创建const volatile对象。这个对象不能被程序员改变,但可经过外面的工具改变。
volatile对象每次被访问时必须从新读取这个变量的值,而不是用保存在寄存器中的备份。下面时volatile变量的几个例子:
.并行设备的硬件寄存器(如状态寄存器);
.一个中断服务子程序中会访问到的非自动变量(Non-automatic variables);
.多现成应用中被几个任务共享的变量。
一个参数能够const同时也是volatile,一个指针也是能够为volatile的,可是具体编程时要当心,要保证不被意外修改。

一、static关键字的做用,我的经验主要有如下几种:1)函数局部static变量,第一次函数调用被初始化,后续每次调用将使用上次调用后保存的值;2)全局变量中static变量,能够防止被其余文件的代码使用这个变量,有点将这个全局变量设置为private的意味;3)对于static函数来讲,效果和2中的变量相同;4)C++类中static方法,不须要实例化访问;5)C++定义static类成员变量,不须要实例化访问,不过须要先定义,定义的时候能够初始化数组。

二、volatile用来声明一个变量,并强制程序在每次使用变量的从新从变量地址读取数据,这是为了防止变量在其余地方被改变,而程序仍然使用没有更新的数据。

 二、说明C++内存分配方式有几种?每种使用都有哪些注意项?

1.从静态存储区域分配内存在程序编译时候就已经分配好,这块内存在程序整个运行期间都存在。例如全局变量,static变量。   
2.在栈上建立。在执行函数时,函数内局部变量存储单元均可以在栈上建立,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器指令集中,效率很高,可是分配内存容量有限。   
3.从堆上分配,亦称动态内存分配程序在运行时候用malloc或new申请任意多少内存,程序员本身负责在什么时候用free或delete释放内存。动态内存生存期由咱们决定,使用很是灵活,但问题也最多。
----------------------------------------
通常所说堆栈(stack)每每是指栈,先进后出,它是一块内存区。用以存放程序局部变量,临时变量,函数参数,返回地址等。在这块区域中变量分配和释放由系统自动进行。不须要用户参与。   
   而在堆(heap,先进先出)空间则是由用户进行分配,并由用户负责释放

编程题:

一、给定一个升序排列的天然数数组,数组中包含重复数字,例如:[1,2,2,3,4,4,4,5,6,7,7]。问题:给定任意天然数,对数组进行二分查找,返回数组正确的位置,给出函数实现。注:连续相同的数字,返回第一个匹配位置仍是最后一个匹配位置,由函数传入参数决定。

分析:既然是二分查找的变形,那么先写个正确的二分查找吧:

#include<iostream>
using namespace std;
int bin_search(int arr[],int n,int value)
{
    if(arr==NULL||n<1)
        return -1;
    int left=0;
    int right=n-1;
    while(left<=right)
    {
        int mid=left+((right-left)>>1);
        if(arr[mid]>value)
        {
            right=mid-1;
        }
        else if(arr[mid]<value)
        {
             left=mid+1;
        }
        else
            return mid;
    }
    return -1;
}
int main()
{
    int arr[]={1,2,3,4,5,6,7,8,9};
    int b=bin_search(arr,9,9);
    cout<<b<<endl;
    system("pause");
    return 0;
}

代码以下:

/*
* 测试样例
* 11
* 1 2 2 3 4 4 4 5 7 7 7
*/
#include<stdio.h>
#include<stdlib.h>
#define MAX 20
int n;
int sets[MAX];
enum MATCH_POS{PRE,POST};//分别为第一个匹配和最后一个匹配

int bi_search(int *arr,int b,int e,int v,MATCH_POS pos)
{
    int left,right,mid;
    left=b-1;right=e;
    while(left+1 < right)
    {
        mid=left+(right - left)/2;
        if(v < arr[mid])
        {
            right = mid;
        }else if(v > arr[mid])
        {
            left=mid;
        }else
        {
            if(pos==PRE)
            {//如寻找第一个匹配,right向左移动
                right = mid;
            }
            else
                left = mid;
        }
    }
    if(arr[right] == v)
        return right;
    else if(arr[left] == v)
        return left;
    return -1;
}

int main(){
    int i;
    int sets[]={1, 2, 2, 3, 4, 4, 4, 5, 7, 7, 7};
    int t=bi_search(sets,0,10,7,PRE);
    printf("%d\n",t);
    system("pause");
    return 0;
}

二、一个无序天然数数组,好比[100,2,1,3]求在0(n)时间复杂度内求出最大的连续天然数个数:输出应该是3,要求算法的时间复杂度为O(n)
方法一:排序
能够采用一些排序方法好比基数排序、桶排序、记数排序等先进行排序。而后遍历一遍全部元素便可。当前这些排序有一些限制条件的。

方法二:维持一个hash表
维持一个hash表,大小为最大整数。遍历一次数组,用hash表记录出如今原始数组中的数。
而后设置四个个指示变量start,end,length,bestLength = 0。初始,start = end = 数组中第一个数,length = 1。而后不断执行下列操做:
end = end + 1.而后ziahash表中寻找end,若是可以找到,说明end存在原始数组中。一直到找不到end位置。
而后设置length = end - start。若是length大于bestLength,则更新:bestLength = length。
而后将start和end都设置为刚才为查找到的那个数,length = 1,接着重复上面的操做,最终的bestLength 即是最大的连续天然数个数。
因为hash的查找等操做都能在O(1)时间复杂度内完成,所以hash方法可以知足O(n)时间复杂度。

方法三:位图
用位图。相似方法二。
位图大小和最大的整数有关。位图中每一位为0或者1。位图某个位置index上为1表示index出如今原始数组中,反之不存在。遍历一遍原始数组创建位图以后,采用相似方法二中遍历hash表的方法遍历位图,找出最大的连续天然数个数。
位图的方法存在一个问题就是:可能最大的数很大,可是数的数目有很小,这时候要申请的位图的空间依然是很大,时候复杂度不是O(n)。

方法四:维持两个hash表

维持两个hash表tables:
Start表,其中的条目都是以下格式(start-point,length),包含的某个连续序列起始数以及序列长度。
End表,其中的条目都是以下格式(end-point,length),包含的某个连续序列结束数以及序列长度。

扫描原始数组,作以下操做:
对于当前值value,
判断value + 1是否存在于start表中。
若是存在,删除相应的条目,建立一个新条目(value,length + 1),同时更新end表相应条目,结束数不变,该对应长度加一。
判断value - 1是否存在于end表中。
若是存在,删除相应的条目,建立一个新条目(value,length + 1),同时更新start表相应条目,开始数不表,该对应长度加一。
若是在两个表中都存在,则合并两个已经存在的连续序列为一个。将四个条目删除,新建两个条目,每两个条目表明一个连续序列。
若是都不存在,则只须要在两个表中建立一个新的长度为1的条目。

一直这样等到数组中全部元素处理完毕,而后扫描start表寻找length值最大的那个便可。

这里要达到O(n)时间复杂度,start表和end表都用hash表实现,并且必须知足相关操做查找/添加/删除可以在O(1)时间复杂度内完成。

实例分析:
int[] input = {10,21,45,22,7,2,67,19,13,45,12, 11,18,16,17,100,201,20,101};

初始化状态:
Start table:{}
End table:{}
开始遍历数组:
10:两个数组中都不存在,添加条目。
Start table:{(10,1)}
End table:{(10,1)}
21:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,1)}
End table:{(10,1),(21,1)}
45:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,1),(45,1)}
End table:{(10,1),(21,1),(45,1)}
22:22-1=21存在于end表中须要进行更新。
Start table:{(10,1),(21,2),(45,1)}
End table:{(10,1),(22,2),(45,1)}
7:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(7,1)}
End table:{(10,1),(22,2),(45,1),(7,1)}
2:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1)}
End table:{(10,1),(22,2),(45,1),(7,1),(2,1)}
67:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1),(67,1)}
End table:{(10,1),(22,2),(45,1),(7,1),(2,1),(67,1)}
19:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1),(67,1),(19,1)}
End table:{(10,1),(22,2),(45,1),(7,1),(2,1),(67,1),(19,1)}
13:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)}
End table:{(10,1),(22,2),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)}
45:两个数组中都不存在,添加条目。
Start table:{(10,1),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)}
End table:{(10,1),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(13,1)}
12:12+1=13存在start表中,更新。
Start table:{(10,1),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(12,2)}
End table:{(10,1),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1),(13,2)}
11:11+1=12都存在,合并。
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1)}
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,1)}
18:18+1=19存在start表中,更新。
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(18,2)}
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,2)}
16:都不存在,添加条目。
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(18,2),(16,1)}
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,2),(16,1)}
17:都存在,合并。
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(16,4)}
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,4)}
100:都不存在,添加条目。
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(16,4),(100,1)}
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,4),(100,1)}
201:都不存在,添加条目。
Start table:{(10,4),(21,2),(45,1),(45,1),(7,1),(2,1),(67,1),(16,4),(100,1),(201,1)}
End table:{(13,4),(22,2),(45,1),(45,1),(7,1),(2,1),(67,1),(19,4),(100,1),(201,1)}
20:都存在,合并。
Start table:{(10,4),(16,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1)}
End table:{(13,4),(22,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1)}
101:都存在,合并。
Start table:{(10,4),(16,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1),(101,1)}
End table:{(13,4),(22,7),(45,1),(45,1),(7,1),(2,1),(67,1),(100,1),(201,1),(201,1)}

最后搜索start表,找到length值最大的,为7.连续天然数序列是:(16,17,18,19,20,21,22).
结束。

 

#include <stdio.h>

int array[]={100, 2, 1, 3, 8, 5, 4};
int size = sizeof(array) / sizeof(int);

//构造两个简陋的hash表,一个是用来查询数字是否存在,一个用于标记数字是否使用过
char hash_exist[1024];
char hash_used[1024];

int main()
{
    int i, j, n, max = 0, maxnum = array[0], minnum = array[0];
    for(i = 0; i < size; i++)
    {
        //标记数字存在
        hash_exist[array[i]] = 1;
        //找出数组最大元素
        if(maxnum < array[i]) maxnum = array[i];
        //找出数组最小元素
        if(minnum > array[i]) minnum = array[i];
    }
    for(i = 0; i < size; i++)
    {
        j = array[i];
        //若是已经统计过,就跳过
        if(hash_used[j])
            continue;
        //标记自己
        n = 1;
        hash_used[j] = 1;
        //比array[i]大的连续元素统计
        while(++j <= maxnum)
        {
            if(hash_exist[j])
            {
                n++;
                hash_used[j] = 1;
            }
            else
                break;
        }
        //比array[i]小的连续元素统计
        j = array[i];
        while(--j >= minnum)
        {
            if(hash_exist[j])
            {
                n++;
                hash_used[j] = 1;
            }
            else
                break;
        }
        //更新最大连续数字
        if(n > max) max = n;
    }
    printf("%d\n", max);
    return 0;
}
相关文章
相关标签/搜索