百度笔试题,求解答

一、选择题:15分 共10题
1.    在排序方法中,关键码比较次数与记录地初始排列无关的是    .
A. Shell排序      B. 归并排序       C. 直接插入排序        D. 选择排序

2.    以下多线程对int型变量x的操作,哪几个需要进行同步:
A. x=y;         B. x++;         C. ++x;            D. x=1;

3.    代码
void func() {
        static int val;
        …
}
中,变量val的内存地址位于:
A. 已初始化数据段    B.未初始化数据段      C.堆              D.栈

4.    同一进程下的线程可以共享以下
A. stack            B. data section
C. register set        D. thread ID

5.    TCP和IP分别对应了 OSI中的哪几层?
A.  Application layer
B.  Data link layer
C.  Presentation layer
D.  Physical layer
E.  Transport layer
F.  Session layer
G.  Network layer

6.    short a[100],sizeof(a)返回?
A 2     B 4       C 100       D 200        E 400

7.    以下哪种不是基于组件的开发技术_____。
A XPCOM        B XP           C COM                D CORBA

8.    以下代码打印的结果是(假设运行在i386系列计算机上):
    struct st_t
    {
        int    status;
        short* pdata;
        char   errstr[32];
    };

    st_t  st[16];
    char* p = (char*)(st[2].errstr + 32);
    printf("%d", (p - (char*)(st)));

A 32          B 114
C 120         D 1112

9.    STL中的哪种结构是连续形式的存储
A  map      B  set         C  list      D  vector

10.    一个栈的入栈序列是A,B,C,D,E,则栈的不可能的输出序列是( )
A、EDCBA;   B、DECBA;    C、DCEAB;    D、ABCDE

二、简答题:20分,共2题

1.    (5分)重复多次fclose一个打开过一次的FILE *fp指针会有什么结果,并请解释。
考察点:导致文件描述符结构中指针指向的内存被重复释放,进而导致一些不可预期的异常。

2.    (15分)下面一段代码,想在调用f2(1)时打印err1,调用f2(2)时打印err4,但是代码中有一些问题,请做尽可能少的修改使之正确。
    
1    static int f1(const char *errstr, unsigned int flag) {
2        int copy, index, len;
3        const static char **__err = {“err1”, “err2”, “err3”, “err4”};
4    
5        if(flag & 0x10000)
6            copy = 1;
7        index = (flag & 0x300000) >> 20;
8     
9        if(copy) {
10            len = flag & 0xF;
11            errstr = malloc(len);
12            if(errstr = NULL)
13                return -1;
14            strncpy(errstr, __err[index], sizeof(errstr));
15        } else
16            errstr =  __err + index;    
17    }
18
19    void f2(int c) {
20        char *err;
21    
22        swtch(c) {
23        case 1:
24            if(f1(err, 0x110004) != -1)
25                printf(err);
26        case 2:
27            if(f2(err, 0x30000D) != -1)
28                printf(err);
29        }
30 }    

三、编程题:30分 共1题
注意:要求提供完整代码,如果可以编译运行酌情加分。

1.    求符合指定规则的数。
给定函数d(n) = n + n的各位之和,n为正整数,如 d(78) = 78+7+8=93。 这样这个函数可以看成一个生成器,如93可以看成由78生成。 
定义数A:数A找不到一个数B可以由d(B)=A,即A不能由其他数生成。现在要写程序,找出1至10000里的所有符合数A定义的数。
输出:
1
3

四、设计题:35分 共1题
注意:请尽可能详细描述你的数据结构、系统架构、设计思路等。建议多写一些伪代码或者流程说明。

1.    假设一个mp3搜索引擎收录了2^24首歌曲,并记录了可收听这些歌曲的2^30条URL,但每首歌的URL不超过2^10个。系统会定期检查这些URL,如果一个URL不可用则不出现在搜索结果中。现在歌曲名和URL分别通过整型的SONG_ID和URL_ID唯一确定。对该系统有如下需求:
1)    通过SONG_ID搜索一首歌的URL_ID,给出URL_ID计数和列表
2)    给定一个SONG_ID,为其添加一个新的URL_ID
3)    添加一个新的SONG_ID
4)    给定一个URL_ID,将其置为不可用

限制条件:内存占用不超过1G,单个文件大小不超过2G,一个目录下的文件数不超过128个。

为获得最佳性能,请说明设计的数据结构、搜索算法,以及资源消耗。如果系统数据量扩大,该如何多机分布处理? 

 

To: wchb0()
strncpy(*errstr, __err[index - 1], strlen(*errstr));
这句改改就行了吧:)
先做前10题
1,B
2,A,D
3,A
4,A,B
5,B,E
6,D
7,B
8,C
9,C
10,C

1 d
2 a c d
3 b
4 b d
5 a d e g
6 d
7 d
8 c
9 d
10 c

仅供参考
1D,
2ABD
3A
4BC
5BE
6D
7D
8C
9D
10C

1、C
2、ABC
3、A
4、B
5、E、G
6、D
7、B
8、C
9、D
10、C
1.d
2.abc
3.a
4.B
5.EG
6.D
7.b
8.B
9.d
10.c
static int f1(char **errstr, unsigned int flag) {

int copy = 0, index, len;
const static char *__err[4] = {"err1", "err2", "err3", "err4"};

if(flag & 0x10000)
copy = 1;
index = (flag & 0x300000) >> 20;

if(copy) {
len = flag & 0xF;
*errstr = (char*)malloc(len * sizeof(char));
if(*errstr == NULL)
return -1;
strncpy(*errstr, __err[index - 1], sizeof(errstr));
} else
*errstr =  (char*)(*(__err + index)); 
}

void f2(int c) {
char **err = (char**)malloc(sizeof(char*));

switch(c) //dongguo
{
case 1:
if(f1(err, 0x110004) != -1)
printf(*err);
printf("n");
break;
case 2:
if(f1(err, 0x30000D) != -1)
printf(*err);
printf("n");
break;
}
free(err);
}
简答第二题

2.    以下多线程对int型变量x的操作,哪几个需要进行同步:
A. x=y;         B. x++;         C. ++x;            D. x=1;

------------------------------------------------------------------
 只有 D 不需要。

x = y;
00411A25  mov         eax,dword ptr [y]
00411A28  mov         dword ptr [x],eax

x++;
00411A2B  mov         eax,dword ptr [x]
00411A2E  add         eax,1
00411A31  mov         dword ptr [x],eax

++x;
00411A34  mov         eax,dword ptr [x]
00411A37  add         eax,1
00411A3A  mov         dword ptr [x],eax

x = 1;
00411A3D  mov         dword ptr [x],1

1.    求符合指定规则的数

#include <stdio.h>

void get(int num,int a[])
{
int sum = num;
int n[4];
int i;
for(i=0;i<4;i++)
{
sum+= num%10;
num/=10;
if(num == 0) break;
}
if(sum<10000)
a[sum] = 1;
}

int main()
{
int a[10000]={0};
int i,j=0;
for(i=0;i<10000;i++)
{
get(i,a);
}
for(i=0;i<10000;i++)
{
if(a[i]==0)
{
printf("%d/t",i);
j++;
if(j%10 == 0) printf("/n");
}
}
return 0;
}

另:
3.    代码
void func() {
        static int val;
        …
}
中,变量val的内存地址位于:
A. 已初始化数据段    B.未初始化数据段      C.堆              D.栈

应该选b吧

B
ABC
A
B
EG
E
CD
B
D
C
【 在 lifeistrue (lifeistrue) 的大作中提到: 】
:四、设计题:35分 共1题
注意:请尽可能详细描述你的数据结构、系统架构、设计思路等。建议多写一些伪代码或者流程说明。

1.    假设一个mp3搜索引擎收录了2^24首歌曲,并记录了可收听这些歌曲的2^30条URL,但每首歌的URL不超过2^10个。系统会定期检查这些URL,如果一个URL不可用则不出现在搜索结果中。现在歌曲名和URL分别通过整型的SONG_ID和URL_ID唯一确定。对该系统有如下需求:
1)    通过SONG_ID搜索一首歌的URL_ID,给出URL_ID计数和列表
2)    给定一个SONG_ID,为其添加一个新的URL_ID
3)    添加一个新的SONG_ID
4)    给定一个URL_ID,将其置为不可用

限制条件:内存占用不超过1G,单个文件大小不超过2G,一个目录下的文件数不超过128个。

为获得最佳性能,请说明设计的数据结构、搜索算法,以及资源消耗。如果系统数据量扩大,该如何多机分布处理?
:================================================

内存不够存储这些url,所以将数据写入若干个文件中。

每一首歌曲对应的存储在文件中的信息格式为(url1, url2……)。

文件的总大小大约为2^24*2^10*4 =2^36 =64GB.根据SongID即可计算出在哪个文件的哪个位置,那么一个随机的查询操作耗时即是一次随机打开文件啊并执行seek操作读取数据的实际,大约是ms级别。

将每首歌曲的信息存入文件中,由于每首歌的url不超过2^10个,所以在文件中每首歌的存储结构是2^10个int数,每个int数字标识着一个url。-1表示url不存在。初始化时将文件中每个int数初始化为-1.
这样每个SongID对应的信息占用的空间为2^10*4=4KB,设每个文件大小1G,那么每个文件可存储2^18=256K个Song的信息。总共需要64个文件,把这些文件编号从0-63.

对于任意一个SongID,他所对应的url信息所在的文件编号是:SongID>>18,在文件中的位置是:(SongID&0x3FFFF)<<12.

另外内存中用一个2^24大小的short int型数组来保存每一首歌曲对应的url的个数,计数组名为urlCount[],初始化时值为-1,表示对应的Song_ID不存在。此数组占用空间2^25Byte=32MB;

url是否可用的信息用位图来标识。位图保存在内存中,占用的空间为2^30/8=2^27 Byte=128MB.


对所要求的操作:
:1)    通过SONG_ID搜索一首歌的URL_ID,给出URL_ID计数和列表
通过SONG_ID计算出文件号和对应在文件中的位置,从urlCount[]中读取url个数,读出所有的url,并对每个url_ID查询位图看是否可用,若可用,将此url加入返回列表。

:2)    给定一个SONG_ID,为其添加一个新的URL_ID
通过SONG_ID计算出文件号和对应在文件中的位置,设为start,在通过urlCount[]得到url个数,假设有n个url,那么将新的URL_ID写入文件的start+sizeof(int)*n处。修改urlCount[SONG_ID]的值。

:3)    添加一个新的SONG_ID
检查将对应的urlCount[SONG_ID],若为-1,则修改为0,若大于等于0,则表明改Song_ID已经存在。

:4)    给定一个URL_ID,将其置为不可用
修改url位图,标识URL_ID对应的位,表示为不可用。

一、选择题:15分 共10题
1.    在排序方法中,关键码比较次数与记录地初始排列无关的是(AD)
A. Shell排序      B. 归并排序       C. 直接插入排序        D. 选择排序

2.    以下多线程对int型变量x的操作,哪几个需要进行同步: (ABC?)
A. x=y;         B. x++;         C. ++x;            D. x=1;

3.    代码
void func() {
        static int val;
        …
}
中,变量val的内存地址位于: (B)
A. 已初始化数据段    B.未初始化数据段      C.堆              D.栈

4.    同一进程下的线程可以共享以下 (BC)
A. stack            B. data section
C. register set        D. thread ID

5.    TCP和IP分别对应了 OSI中的哪几层?(EG)
A.  Application layer
B.  Data link layer
C.  Presentation layer
D.  Physical layer
E.  Transport layer
F.  Session layer
G.  Network layer

6.    short a[100],sizeof(a)返回? (D)
A 2     B 4       C 100       D 200        E 400

7.    以下哪种不是基于组件的开发技术_____。(不清楚)
A XPCOM        B XP           C COM                D CORBA

8.    以下代码打印的结果是(假设运行在i386系列计算机上):(C)有人试着运行过吗?
    struct st_t
    {
        int    status;
        short* pdata;
        char   errstr[32];
    };

    st_t  st[16];
    char* p = (char*)(st[2].errstr + 32);
    printf("%d", (p - (char*)(st)));

A 32          B 114
C 120         D 1112

9.    STL中的哪种结构是连续形式的存储 (D)
A  map      B  set         C  list      D  vector

10.    一个栈的入栈序列是A,B,C,D,E,则栈的不可能的输出序列是(C )
A、EDCBA;   B、DECBA;    C、DCEAB;    D、ABCDE

to XINYONGHUCSDN(柯风):
和你做的不同的选择题:
1。D
4。C
6。C
7。B

TO cpfly8421() 
1.
归并排序最根本的操作是将两个排好序的文件合并成一个更大的排好序的文件,那么出示输入的数据对合并的影响是哪些数据比较的次数比较多,哪些少一定,对总体来说比较的次数是不变的(对一个特定的写好的归并程序来说)。归并排序只与数据的数目有关,与顺序无关。
因此我选(BD)

上面好像写成了AD,笔误了。是BD.

4.同一进程中的不同线程是共享数据段的,要不然线程相对于进程的线程间通信的优势就没有了。所以我选BD。

6.sizeof得到的是字节数。

7.我清楚。
8。C st[2].errstr + 32的地址p实际上与st[3]的地址相同, sizeof(st) = 4 + 4 + 32 = 40;
6。D  sizeof(short)× 100 = 200
三:求符合的数字

void main(void)
{
   func(10000);
}
void func(int n)
{
   for(int i = 1; i <= n; i++)
   {
      check(i);
   }
}

void check(int n)
{
   int i = 0, j = 0;
   int sum = 0;

   for(int i = 1; i < n; i++)   //这个地方有没有更好的办法判断退出,减少循环?
   {
       sum = i;
 
       for(j = i; j > 0; j / 10)
       {
          sum += j % 10;
       }
      
       if(sum == n)
       {
          break;
       }   
   }
   if(sum != n)
   {
      printf("find one! n = %d", n);
   }
}

if(sum != n)
   {
      printf("find one! n = %d", n);
   }
}
1.    求符合指定规则的数。
给定函数d(n) = n + n的各位之和,n为正整数,如 d(78) = 78+7+8=93。 这样这个函数可以看成一个生成器,如93可以看成由78生成。 
定义数A:数A找不到一个数B可以由d(B)=A,即A不能由其他数生成。现在要写程序,找出1至10000里的所有符合数A定义的数。
输出:
1
3

//========================
#include <string.h>
#include <stdio.h>

int main()
{
  return find_num();
}

int find_num()
{
#define N 10000
        char num[N+1];
        int sum=0, j=0, i=0;

        memset(num, 0, sizeof num);

        for(i=1; i<=N; ++i)
        {
                sum = j = i;
                while(j!=0)
                {
                        sum += j%10;
                        j /= 10;
                }
                if(sum <= N) num[sum] = 1;
        }

        for(i=1; i<=N; ++i)
                if(num[i]==0) printf("%d/n", i);
        return 0;
}

//==================
输出结果:
1
3
5
7
9
20
31
42
53
64
75
86
97
108
110
121
132
143
154
165
176
187
198
……
#include <iostream>
using namespace std;

const int MAX = 10000;

int main()
{
bool result[MAX];
memset(result, 1, MAX);
int q = 0;
int b = 0;
int s = 0;
int g = 0;
for (q = 0; q < 10; ++q)
{
for (b = 0; b < 10; ++b)
{
for (s = 0; s < 10; ++s)
{
for (g = 0; g < 10; ++g)
{
int num = q * 1000 + b * 100 + s * 10 + g + q + b + s + g;
if (num > 0 && num < MAX)
{
result[num - 1] = false;
}
}
}
}
}
for (int i = 0; i < MAX; ++i)
{
if (result[i])
{
cout << i + 1 << endl;
}
}
return 0;
}

1 ?
2 a,d
3 a
4 b
5 e,g
6 d
7 b
8 c
9 d
10 c

程序题,我做的.

#include <stdio.h>
#include <stdlib.h>

//
#define total 200

int main(int argc, char* argv[])
{
    int result[total];
    for (int i = 1; i <= total; i++)
        result[i] = i;
      
    //
    for (int j = 1; j <= total; j++)
    {
        int v = j;
        unsigned int k = j;
        while( k > 0 )
        {
            v += k % 10; 
            k = k / 10; 
        }
       
        //
        if ((v != j) && (v <= total))
        {
            result[v] = -1;
            result[0]++;
        }
    }  
   
    int dd  = 0;
    for (int m = 1; m <= total; m++)
    {
        if(result[m] != -1)
        {
            if (dd % 10 == 0)
                printf("%d/n", m);
            else
                printf("%d ", m);
        }     
    }
   
    return 0;   
}

YeTimmy(啥时候才能为国家做点贡献-_-#) 的代码不错。只是这里:
if (num > 0 && num < MAX)
{
result[num - 1] = false;
}
条件可以稍微改进一下。把数组大小整成MAX+1,然后把num>0去掉。
if (num <= MAX)
{
result[num] = false;
}
result[0]自然地成了FALSE,也就不会输出了。多用一个空间,省掉两个条件,划算!

求符合指定规则的数

int szElements[10045];
int szAddValue[] = { 2, 11, 101, 1001};

void Calculate(int iBaseValue, int iPos)
{
if ( iPos != 0)
        {
Calculate( iBaseValue, iPos - 1);
for ( int i = 1; i <= 9; i ++)
         {
    iBaseValue += szAddValue[iPos];
    szElement[iBaseValue] = 1;
    Calculate(iBaseValue, iPos - 1);
         }
     }
}

void PrintResult()
{
for ( int i = 0; i < 10000; i ++)
     {
if ( !szElement[i] )
        {
cout << i << endl;
        }
     }
}


第二题:
我想了两个小时,结果出来了但不知道考什么,请高手指教!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static int f1(char * errstr, unsigned int flag)
{//字符串函数不支持常指针,故修改传递的指针errstr和__err
int copy = 0, index, len;
static char *__err[] = {"err1", "err2", "err3", "err4"};//VC支持此种定义
if(flag & 0x10000)
copy = 1;
index = (flag & 0x300000) >> 20;
if(copy) //copy表示要做什么???请高手解释哈!!!
{
len = flag & 0xF; //len是做下用途吗???
//重新从原堆开始的地方分配空间,以便f2读取
//errstr = (char*)realloc(errstr, strlen(__err[index]) + len);
errstr = (char*)realloc(errstr, strlen(__err[index]) + 1);//请教高手是否更好???
if(errstr == NULL)
return -1;
strcpy(errstr, __err[index]);//strncpy不会在后边添加'/0'
}
else
strcpy(errstr, __err[index]); //修改 
}

void f2(int c) {
char *err = (char*)malloc(5); //不能指向栈空间!
switch(c)
{
case 1:
if(f1(err, 0x010004) != -1) //0x110004->0x010004第六位是数组__err的索引
printf("f(1)= %s",err);
printf("/n");
break;
case 2:
if(f1(err, 0x30000D) != -1)
printf("f(2)= %s",err);
printf("/n");
break;
}
free(err);
}
void main()
{
f2(1);
f2(2);
}
//是不是考察栈,堆与全局数据之间的操作???如用C++的string类实现就容易多了


三、解答
#include <iostream>
using std::cout;
using std::endl;

int main()
{
int a,b,c,d;//1~10000里各个位数
         int j=0;//计数器

for(int n=1;n<=10000;n++)
{
j=0;
for(int i=1;i<=n;i++)
{
a=i%10;
b=(i%100-a)/10;
c=(i%1000-b)/100;
d=(i-c)/1000;//求出各个数位

e=a+b+i;//c+d+i;//求出函数
if(e!=n)
j++;//统计不符合要求的个数
}
if(j==n)//当完全找不到符合要求的数打印数
cout<<n<<"/n";
}

cout<<endl;
return 0;

}

上面漏写一行:
         int a,b,c,d;//1~10000里各个位数
/
         int e;//所求函数数
/
         int j=0;//计数器

在VC6.0下测试有效


综合下选择题,有意见请指出
1.    在排序方法中,关键码比较次数与记录地初始排列无关的是    .  (BD,上面高手的意见)
A. Shell排序      B. 归并排序       C. 直接插入排序        D. 选择排序

2.    以下多线程对int型变量x的操作,哪几个需要进行同步: (ABC,上面用汇编证明)
A. x=y;         B. x++;         C. ++x;            D. x=1;

3.    代码                  B,没有异议
void func() {
        static int val;
        …
}
中,变量val的内存地址位于:
A. 已初始化数据段    B.未初始化数据段      C.堆              D.栈

4.    同一进程下的线程可以共享以下      BC,也没异议吧
A. stack            B. data section
C. register set        D. thread ID

5.    TCP和IP分别对应了 OSI中的哪几层? EG,通常只用在传输与网络层吧
A.  Application layer
B.  Data link layer
C.  Presentation layer
D.  Physical layer
E.  Transport layer
F.  Session layer
G.  Network layer


6.    short a[100],sizeof(a)返回? (D)
A 2     B 4       C 100       D 200        E 400

VC6下测试,不过这应该与编译器有关,不一定都为2字节

7.    以下哪种不是基于组件的开发技术_____。(B是说极限编程吗,CORBA是LINUX下滴COM,算吧)
A XPCOM        B XP           C COM                D CORBA

8.    以下代码打印的结果是(假设运行在i386系列计算机上):
    struct st_t
    {
        int    status;
        short* pdata;
        char   errstr[32];
    };

    st_t  st[16];
    char* p = (char*)(st[2].errstr + 32);
    printf("%d", (p - (char*)(st)));

A 32          B 114
C 120         D 1112

VC6下测试,答案为120
个人理解:st[2].errstr + 32 这个就是st[3]的地址啊!
而st_t的大小为 4+4+32 = 30,所以st[3]的地址就为 3*40 = 120
不正确请指出


9.    STL中的哪种结构是连续形式的存储  (D)
A  map      B  set         C  list      D  vector

10.    一个栈的入栈序列是A,B,C,D,E,则栈的不可能的输出序列是( 不用说 C )
A、EDCBA;   B、DECBA;    C、DCEAB;    D、ABCDE

结合下自己的理解与上面各仁兄滴高见,请路过再指点


1. 归并排序的比较次数可能不同,例如1 2 3 4, 需要比较4次(12 34 13 23),而1 4 2 3 需要比较5次(14 23 12 42 43),应该只有D


用动态规划方法做的编程题
#include <iostream>
using namespace std;


int szElement[10036];
int szAddValue[] = { 2, 11, 101, 1001};

void CalculateElement( int iPos )
{
int iMaxElementPre = 0;
if ( iPos != 0)
{
iMaxElementPre = 10 * szAddValue[iPos - 1] + iPos * 9 - 11;
}

for ( int i = iMaxElementPre; i >= 0; i --)
{
if ( szElement[i] )
{
int iNewElement = i;
for ( int i = 1; i <= 9; i ++)
{
iNewElement += szAddValue[iPos];
szElement[iNewElement] = 1;
}
}
}
}

void PrintResult()
{
for ( int i = 0; i < 10000; i ++)
{
if ( !szElement[i] )
{
cout << i << endl;
}
}
}

int _tmain(int argc, _TCHAR* argv[])
{
for ( int i = 1; i < 10036; i ++)
{
szElement[i] = 0;
}
szElement[0] = 1;

for ( int i = 0; i < 4; i ++)
{
CalculateElement(i);
}

PrintResult();

return 0;
}

下面的程序更加简洁:
#include <iostream>
using namespace std;


int szElement[10036];
int szAddValue[] = { 2, 11, 101, 1001};
int szAssist[9];

void CalculateElement( int iPos )
{
int iMaxElementPre = szAddValue[iPos] + iPos * 9 - 2;

szAssist[0] = szAddValue[iPos];
for ( int i = 1; i < 9; i ++)
{
szAssist[i] = szAssist[i-1] + szAddValue[iPos];
}

for ( int i = iMaxElementPre; i >= 0; i --)
{
if ( szElement[i] )
{
for ( int j = 0; j < 9; j ++)
{
szElement[i + szAssist[j]] = 1;
}
}
}
}

void PrintResult()
{
for ( int i = 0; i < 10000; i ++)
{
if ( !szElement[i] )
{
cout << i << endl;
}
}
}

int _tmain(int argc, _TCHAR* argv[])
{
for ( int i = 1; i < 10036; i ++)
{
szElement[i] = 0;
}
szElement[0] = 1;

for ( int i = 0; i < 4; i ++)
{
CalculateElement(i);
}

PrintResult();

return 0;
}


d
bc
a
ab
ge
d
b
c
d
c
YeTimmy(啥时候才能为国家做点贡献-_-#) 的思路很清晰,稍做修改:

void calcElement()
{   
    char a[10036] = {0, };
    for (int q = 0; q < 10; q++)
    {
        for (int b = 0; b < 10; b++)
        {
            for (int s = 0; s < 10; s++)
            {
                for (int g = 0; g < 10; g++)
                {
                    a[q * 1000 + b * 100 + s * 10 + g + q + b + s + g] = 1;
                }
            }
        }
    }
    for (int i = 0; i < 10000; ++i)
    {
        if (!a[i])
        {
            cout << i << " ";
        }
    }
}
1 D (查了书籍,直接插入肯定不是,shell依赖直接插入,归并排序与分组有关,书上指出直接选择的算法与初始键值排序无关)
2 A B C (三者都有读内存,然后写内存的操作)
3 A (?不是很确定,但是VC编译器是这样的。如果是B的话,那么在函数内部就没有意义了)
4 B  (线程都有独立的寄存器、栈空间、线程ID)
5 E G
6 D (100*sizeof(short) => 200)
7 B (?不是很确定, XPCOM望文生义,应该给予COM。COM自身就是COM。COBRA是基于COM的)
8 C (细心算算应该没问题)
9 D (应该考查的是对STL的理解)
10 C

大家有什么不同的看法
1、C
2、ABC
3、A
4、B
5、E、G
6、D
7、B
8、C
9、D
10、C
很多题是应试教育的产物,下面给出一个1分钟想出的最后一个问题的处理方法,但是如果不查资料,要把细节写出来,那考的就不是技巧,而是背功了:
四、设计题:35分 共1题
注意:请尽可能详细描述你的数据结构、系统架构、设计思路等。建议多写一些伪代码或者流程说明。

1.    假设一个mp3搜索引擎收录了2^24首歌曲,并记录了可收听这些歌曲的2^30条URL,但每首歌的URL不超过2^10个。系统会定期检查这些URL,如果一个URL不可用则不出现在搜索结果中。现在歌曲名和URL分别通过整型的SONG_ID和URL_ID唯一确定。对该系统有如下需求:
1)    通过SONG_ID搜索一首歌的URL_ID,给出URL_ID计数和列表
2)    给定一个SONG_ID,为其添加一个新的URL_ID
3)    添加一个新的SONG_ID
4)    给定一个URL_ID,将其置为不可用

限制条件:内存占用不超过1G,单个文件大小不超过2G,一个目录下的文件数不超过128个。

为获得最佳性能,请说明设计的数据结构、搜索算法,以及资源消耗。如果系统数据量扩大,该如何多机分布处理?

 

本人认为可以采用建立两个 song_id 和 url_id 的 B-Tree 树 ..., 其它的东西也许不需要细说了, 如那些放在内存中, 哪些放在文件中 .... , 熟悉软件的人, 查一下数据结构和算法的书, 就可以了, 个人认为这些东西只要理解就可以了, 不要去背,  Donald.E.Knuth 做东西也是查找和推论出来的, ... rootkitkernel@163.com
8.    以下代码打印的结果是(假设运行在i386系列计算机上):
    struct st_t
    {
        int    status;
        short* pdata;
        char   errstr[32];
    };

    st_t  st[16];
    char* p = (char*)(st[2].errstr + 32);
    printf("%d", (p - (char*)(st)));

A 32          B 114
C 120         D 1112
大家注意一下,是在i386下 int变量应该是2字节吧~。觉得应该是B(114)

1.    求符合指定规则的数。
给定函数d(n) = n + n的各位之和,n为正整数,如 d(78) = 78+7+8=93。 这样这个函数可以看成一个生成器,如93可以看成由78生成。 
定义数A:数A找不到一个数B可以由d(B)=A,即A不能由其他数生成。现在要写程序,找出1至10000里的所有符合数A定义的数。
输出:
#include <stdio.h>

void get(int A)
{
  int sum =0;
  int i,j,k,X;
    for(i=1;i<4;i++)
    {
      X=A;
      A/=10;
      if(A == 0) break;
    }   
   /*备注1:此时i表示A是几位数*/
  
    if(i*9>=A)               
      k=1;        /*备注2:当num<=它的位数*9时,让k从1开始查找*/
    else
      k=A-(9*(i-1)+X);    /*备注3:当num>它的位数*9时,让k从A-(9*(i-1)+X)  开始查找*/ 
 
  for(;k<=A;k++)
  {
    for(j=1;j<=i;j++)
     {
      sum+=k%10;     /*求出此时k各个位数字的和*/
     }
   
    if(sum+k=A)      /*发现k的各个位数的和+k=A时,既A可以找到d(B)=A中的B,此时B就是k*/
     {
      return();
     }
   }
  printf("%d/n",A);
}

int main()
{

  int i,
  for(i=0;i<10000;i++)
  {
    get(i);
  }


}
4  abc
编程求数:
abcde转换后10000a+1000b+100c+10d+e+a+b+c+d+e
#define NUM_SAVE_MAX 2000
#define INTBYTES 4
static int save[NUM_SAVE_MAX];
void search(int *arr,int n)
{
   for(int *p=arr;p<arr+INTBYTES*n;p++)
      {
         int x=*p;
         x=x%10001;
         x=x%1001;
         x=x%101;
         x=x%11;
         x=x%2;
        if(x!=0)
        int savenum=0;
        save[savenum]=x;
        savenum++;
    }
}

4 abc
编程求数:
abcde转换后10000a+1000b+100c+10d+e+a+b+c+d+e
#define NUM_SAVE_MAX 2000
#define INTBYTES 4
static int save[NUM_SAVE_MAX];
void search(int *arr,int n)
{
for(int *p=arr;p<arr+INTBYTES*n;p++)
{
int x=*p;
int savenum=0;
x=x%10001;
x=x%1001;
x=x%101;
x=x%11;
x=x%2;
if(x!=0)
{
save[savenum]=x;
savenum++;
}
}
}

2.    以下多线程对int型变量x的操作,哪几个需要进行同步:
A. x=y;         B. x++;         C. ++x;            D. x=1;


我怎么觉得是ACD

/*
  Name: 编程题:求符合指定规则的数。
  Copyright: 2006年
  Author: 崔卫兵
  Date: 11-10-06 14:36
  Description: 求符合指定规则的数。
  给定函数d(n) = n + n的各位之和,n为正整数,如 d(78) = 78+7+8=93。 这样这个函数可以看成一个生成器,如93可以看成由78生成。 
  定义数A:数A找不到一个数B可以由d(B)=A,即A不能由其他数生成。现在要写程序,找出1至10000里的所有符合数A定义的数。
  输出:
  1
  3
*/

#include <iostream>

using namespace std;
short NumSum(short);

int main(int argc, char *argv[])
{
    short sArr[10000]={0};
    short len=10000;//sizeof(sArr)/sizeof(short)
    for(int i=1;i<len;i++){
        short tmp=NumSum(i);
        if(tmp<=10000){
            sArr[tmp-1]=1;
        }   
    }
    for(int i=0;i<len;i++){
        if(sArr[i]==0)
            cout<<i+1<<endl;
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}

short NumSum(short num){
      short newNum=num;
      newNum+=num/1000+num%1000/100+num%100/10+num%10;
      return newNum;
}
三、编程题:30分 共1题
1.    求符合指定规则的数。
    class Program
    {
        static ArrayList allNum=new ArrayList();
        static void Main(string[] args)
        {
            int buffer;
            for (int i = 1; i <= 10000; i++)
            {
                buffer=jisuan(i);
                if (check(buffer)) allNum.Add(buffer);
            }
            for (int j = 1; j <= 10000; j++)
            {
                if (check(j)) Console.WriteLine(j);
            }
        }

        static bool check(int i)
        {
            foreach (int num in allNum)
            {
                if (i == num) return false;
            }
            return true;
        }

        static int jisuan(int i)
        {
            int sum = i;
            foreach (char c in i.ToString().ToCharArray())
            {
                sum += int.Parse(c.ToString());
            }
            return sum;
        }
    }

三 1   POJ 1316

my code:

Source

Problem Id:1316  User Id:jiang5448
Memory:192K  Time:0MS
Language:G++  Result:Accepted

Source

#include <iostream>
using namespace std;
bool e[10000];
int d (int n)
{
    int s=n;
    while (n)
    {
          s+=n%10;
          n/=10;
    }
    return s;
}
int main()
{
    int i;
    for (i=0;i<10000;i++)
    e[i]=false;
    for (i=1;i<10000;i++)
    if (d(i)<10000)
    e[d(i)]=true;
    for (i=1;i<10000;i++)
    if (!e[i])
    cout<<i<<endl;
    return 0;
}

ans:

1
3
5
7
9
20
31
42
53
64
75
86
97
108
110
121
132
143
154
165
176
187
198
209
211
222
233
244
255
266
277
288
299
310
312
323
334
345
356
367
378
389
400
411
413
424
435
446
457
468
479
490
501
512
514
525
536
547
558
569
580
591
602
613
615
626
637
648
659
670
681
692
703
714
716
727
738
749
760
771
782
793
804
815
817
828
839
850
861
872
883
894
905
916
918
929
940
951
962
973
984
995
1006
1021
1032
1043
1054
1065
1076
1087
1098
1109
1111
1122
1133
1144
1155
1166
1177
1188
1199
1210
1212
1223
1234
1245
1256
1267
1278
1289
1300
1311
1313
1324
1335
1346
1357
1368
1379
1390
1401
1412
1414
1425
1436
1447
1458
1469
1480
1491
1502
1513
1515
1526
1537
1548
1559
1570
1581
1592
1603
1614
1616
1627
1638
1649
1660
1671
1682
1693
1704
1715
1717
1728
1739
1750
1761
1772
1783
1794
1805
1816
1818
1829
1840
1851
1862
1873
1884
1895
1906
1917
1919
1930
1941
1952
1963
1974
1985
1996
2007
2022
2033
2044
2055
2066
2077
2088
2099
2110
2112
2123
2134
2145
2156
2167
2178
2189
2200
2211
2213
2224
2235
2246
2257
2268
2279
2290
2301
2312
2314
2325
2336
2347
2358
2369
2380
2391
2402
2413
2415
2426
2437
2448
2459
2470
2481
2492
2503
2514
2516
2527
2538
2549
2560
2571
2582
2593
2604
2615
2617
2628
2639
2650
2661
2672
2683
2694
2705
2716
2718
2729
2740
2751
2762
2773
2784
2795
2806
2817
2819
2830
2841
2852
2863
2874
2885
2896
2907
2918
2920
2931
2942
2953
2964
2975
2986
2997
3008
3023
3034
3045
3056
3067
3078
3089
3100
3111
3113
3124
3135
3146
3157
3168
3179
3190
3201
3212
3214
3225
3236
3247
3258
3269
3280
3291
3302
3313
3315
3326
3337
3348
3359
3370
3381
3392
3403
3414
3416
3427
3438
3449
3460
3471
3482
3493
3504
3515
3517
3528
3539
3550
3561
3572
3583
3594
3605
3616
3618
3629
3640
3651
3662
3673
3684
3695
3706
3717
3719
3730
3741
3752
3763
3774
3785
3796
3807
3818
3820
3831
3842
3853
3864
3875
3886
3897
3908
3919
3921
3932
3943
3954
3965
3976
3987
3998
4009
4024
4035
4046
4057
4068
4079
4090
4101
4112
4114
4125
4136
4147
4158
4169
4180
4191
4202
4213
4215
4226
4237
4248
4259
4270
4281
4292
4303
4314
4316
4327
4338
4349
4360
4371
4382
4393
4404
4415
4417
4428
4439
4450
4461
4472
4483
4494
4505
4516
4518
4529
4540
4551
4562
4573
4584
4595
4606
4617
4619
4630
4641
4652
4663
4674
4685
4696
4707
4718
4720
4731
4742
4753
4764
4775
4786
4797
4808
4819
4821
4832
4843
4854
4865
4876
4887
4898
4909
4920
4922
4933
4944
4955
4966
4977
4988
4999
5010
5025
5036
5047
5058
5069
5080
5091
5102
5113
5115
5126
5137
5148
5159
5170
5181
5192
5203
5214
5216
5227
5238
5249
5260
5271
5282
5293
5304
5315
5317
5328
5339
5350
5361
5372
5383
5394
5405
5416
5418
5429
5440
5451
5462
5473
5484
5495
5506
5517
5519
5530
5541
5552
5563
5574
5585
5596
5607
5618
5620
5631
5642
5653
5664
5675
5686
5697
5708
5719
5721
5732
5743
5754
5765
5776
5787
5798
5809
5820
5822
5833
5844
5855
5866
5877
5888
5899
5910
5921
5923
5934
5945
5956
5967
5978
5989
6000
6011
6026
6037
6048
6059
6070
6081
6092
6103
6114
6116
6127
6138
6149
6160
6171
6182
6193
6204
6215
6217
6228
6239
6250
6261
6272
6283
6294
6305
6316
6318
6329
6340
6351
6362
6373
6384
6395
6406
6417
6419
6430
6441
6452
6463
6474
6485
6496
6507
6518
6520
6531
6542
6553
6564
6575
6586
6597
6608
6619
6621
6632
6643
6654
6665
6676
6687
6698
6709
6720
6722
6733
6744
6755
6766
6777
6788
6799
6810
6821
6823
6834
6845
6856
6867
6878
6889
6900
6911
6922
6924
6935
6946
6957
6968
6979
6990
7001
7012
7027
7038
7049
7060
7071
7082
7093
7104
7115
7117
7128
7139
7150
7161
7172
7183
7194
7205
7216
7218
7229
7240
7251
7262
7273
7284
7295
7306
7317
7319
7330
7341
7352
7363
7374
7385
7396
7407
7418
7420
7431
7442
7453
7464
7475
7486
7497
7508
7519
7521
7532
7543
7554
7565
7576
7587
7598
7609
7620
7622
7633
7644
7655
7666
7677
7688
7699
7710
7721
7723
7734
7745
7756
7767
7778
7789
7800
7811
7822
7824
7835
7846
7857
7868
7879
7890
7901
7912
7923
7925
7936
7947
7958
7969
7980
7991
8002
8013
8028
8039
8050
8061
8072
8083
8094
8105
8116
8118
8129
8140
8151
8162
8173
8184
8195
8206
8217
8219
8230
8241
8252
8263
8274
8285
8296
8307
8318
8320
8331
8342
8353
8364
8375
8386
8397
8408
8419
8421
8432
8443
8454
8465
8476
8487
8498
8509
8520
8522
8533
8544
8555
8566
8577
8588
8599
8610
8621
8623
8634
8645
8656
8667
8678
8689
8700
8711
8722
8724
8735
8746
8757
8768
8779
8790
8801
8812
8823
8825
8836
8847
8858
8869
8880
8891
8902
8913
8924
8926
8937
8948
8959
8970
8981
8992
9003
9014
9029
9040
9051
9062
9073
9084
9095
9106
9117
9119
9130
9141
9152
9163
9174
9185
9196
9207
9218
9220
9231
9242
9253
9264
9275
9286
9297
9308
9319
9321
9332
9343
9354
9365
9376
9387
9398
9409
9420
9422
9433
9444
9455
9466
9477
9488
9499
9510
9521
9523
9534
9545
9556
9567
9578
9589
9600
9611
9622
9624
9635
9646
9657
9668
9679
9690
9701
9712
9723
9725
9736
9747
9758
9769
9780
9791
9802
9813
9824
9826
9837
9848
9859
9870
9881
9892
9903
9914
9925
9927
9938
9949
9960
9971
9982
9993

编程题,算法复杂度为O(lgn * lgn)

char szElements[10036];
int szAddValue[] = {2, 11, 101, 1001};
char szAssist[27];
void Calculate( int iPos )
{
int iCurAddValue = szAddValue[iPos];
int iMaxElementPre = iCurAddValue + iPos * 9 - 2;
int nMergeElements = iMaxElementPre - iCurAddValue + 1;

if ( nMergeElements > 0 )
{
memcpy(szAssist, szElements + iCurAddValue, nMergeElements);
memcpy(szElements + iCurAddValue * 10, szAssist, nMergeElements);
}

memcpy(szElements + iCurAddValue, szElements, iCurAddValue);

for ( int i = 0; i < nMergeElements; i ++)
{
if (szAssist[i])
{
szElements[i + iCurAddValue ] = 1;
}
}

for ( int i = 2, iOffset = 2 * iCurAddValue; i <= 9; i ++)
{
memcpy(szElements + iOffset, szElements + iCurAddValue, iCurAddValue);
}
}

void main()
{
memset( szElements, 0, 10036);
szElements[0] = 1;

for ( int i = 0; i < 4; i ++)
{
Calculate(i);
}

for ( int i = 1; i <= 10000; i ++)
{
if (!szElements[i])
{
printf("%d/n", i);
}
}
}

上面少写了一句 for ( int i = 2, iOffset = 2 * iCurAddValue; i <= 9; i ++)
改为 for ( int i = 2, iOffset = 2 * iCurAddValue; i <= 9; i ++, iOffset += iCurAddValue)
修改代码的结果如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#define DEBUG
static int f1( char **errstr, unsigned int flag)  //change    char *errstr  -->char **errstr
{
int copy, index, len;
int i=0;
//const static char **__err = {"err1", "err2","err3","err4"};  //此行换为下行
const char __err[4][10] = {"err1", "err2","err3","err4"};

if(flag & 0x10000)
copy = 1;
index = (flag & 0x300000) >> 20;

#ifdef DEBUG
printf("copy %u index:%u/n",copy,index);
#endif

if(copy)
{
len = flag & 0xf;
    *errstr = malloc(len);
if(*errstr == NULL) //change =  ->  ==
return -1;
strncpy(*errstr, __err[index-1], len); //change -1 sizeof(errstr)=4 -->len

}
else
{
 *errstr = __err + index;
}
 }
 
void f2(int c)
{
char *err;
 
switch(c)
{
case 1:

if(f1(&err, 0x110004) != -1)
printf("%s/n",err);
break;    //add
case 2:

if(f1(&err, 0x30000D) != -1)   //change  f2 ->f1
printf("%s/n",err);

break; //add
 }
free(err); //add
}

int main(int argc,char *argv[])
{

f2(1);
f2(2);
return 0;
}

四、设计题:35分 共1题
注意:请尽可能详细描述你的数据结构、系统架构、设计思路等。建议多写一些伪代码或者流程说明。

1.    假设一个mp3搜索引擎收录了2^24首歌曲,并记录了可收听这些歌曲的2^30条URL,但每首歌的URL不超过2^10个。系统会定期检查这些URL,如果一个URL不可用则不出现在搜索结果中。现在歌曲名和URL分别通过整型的SONG_ID和URL_ID唯一确定。对该系统有如下需求:
1)    通过SONG_ID搜索一首歌的URL_ID,给出URL_ID计数和列表
2)    给定一个SONG_ID,为其添加一个新的URL_ID
3)    添加一个新的SONG_ID
4)    给定一个URL_ID,将其置为不可用

限制条件:内存占用不超过1G,单个文件大小不超过2G,一个目录下的文件数不超过128个。

为获得最佳性能,请说明设计的数据结构、搜索算法,以及资源消耗。如果系统数据量扩大,该如何多机分布处理?
================================
一点想法
因为“每首歌的URL不超过2^10个”,似乎在提示每个SONG_ID的URL_ID占用同样的内存,那么1g内存每个SONG_ID仅有64byte,而2^10个URL_ID即使一个bit存一个,也需要128byte,显然行不通的。

存2^30条URL_ID,即一个URL_ID最多1byte的内存。而由于每个SONG_ID占用的内存不同,所以至少还得存储这个信息。以最少信息论,假设每个URL_ID占一个bit,则一个SONG_ID占用内存的长度最大会有2^20bit(转换成字节、字等占用的内存更多,但计算会方便一些,快一些)...即长度最少要占用21bit。

另外,需要一个bit存一个URL_ID,至少还需要存一个MIN_URL_ID(然后第nbit为1代表MIN_URL_ID+n这个URL_ID也属于这个SONG_ID),SONG_ID因为基本可以认为不会删除,所以不于保存,直接按index来。

也就是说,要存储一个SONG_ID,至少需要内存 32+21+URL_ID_CNT bits.所以总内存需:

(32+21) × 2^24  + 2^30  > 1G
<汗一个,写到这里忽然发现1G内存存1g个URL_ID,很明显直接就是不够...>

所以,要占用1g以下内存,基本上可以认为需要用硬盘做数据交换,但似乎总感觉不爽,毕竟从题意上看,是不适合这样的。当然了,1个文件2g最大,也不明白意思。直觉上认为跟分布运算有关。

PS:因为URL_ID变化较大,(很可能随时增加或者减少一个)所以不适合用连续存储的方式。
假设有如下数据段,进行二路归并:
A:1 2 3 4 5 6
B:7
比较次数:6次
A:1 2 3 4 5 6
B:0
比较次数:1次
看到那个求小于100000的那个题的没一个对的!
看看14可以合成不?
f(a)=b;
f(a+1)=c;
b到c之间的都是不可合成的数。
原因:如果b与c间有d可以由合成即f(x)=d;
=> x>a && x<a+1
=> ...........
我觉得3.1应该倒着推!从0到1000,看看都可以生成什么数,然后把生成的数标志位置为true,最后检查一下有那些数仍然为false就可以了。

#include <iostream>

using namespace std;

bool flag[2000]={false};  //1-2000

int main()
{
for(int i=0;i<10;++i)
for(int j=0;j<10;++j)
for(int k=0;k<10;++k)
flag[i*100+j*10+k*1 + i+j+k]=true;
for(int num=0;num<1000;++num)
if(flag[num]==false)
cout<<num<<" ";
return 0;
}

3。1题
以100 为例子
一个容易看懂的:

#include <iostream>
#include <cmath>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
  vector<int> a;
  list<int> b;
  for ( int  n = 1; n < 100; ++n )
    {
      int j = ( (n%10) + (n/10) + n  );
      if ( j < 100 )
{
  a.push_back(j);
}
    }   
  sort( a.begin(), a.end() );
  for ( int i = 1; i <= 100; ++i )
    b.push_back(i);
  for ( int j = 0; j < a.size(); ++j )
    {
      b.remove( a[j] );
    }
  ostream_iterator<int,char> out ( cout, "/n" );
  copy( b.begin(), b.end(), out );
  cout << " Done!" << endl;
  return 0;
}


/
output:
 >g++ baidu.C
 > ./a.out
1
3
5
7
9
20
31
42
53
64
75
86
97
100
 Done!
这样就没有100啦

#include <iostream>
#include <cmath>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
vector<int> a;
list<int> b;
for ( int n = 1; n < 100; ++n )
{
int j = ( (n%10) + (n/10) + n );
if ( j <= 100 )
{
a.push_back(j);
}
}
sort( a.begin(), a.end() );
for ( int i = 1; i <= 100; ++i )
b.push_back(i);
for ( int j = 0; j < a.size(); ++j )
{
b.remove( a[j] );
}
ostream_iterator<int,char> out ( cout, "/n" );
copy( b.begin(), b.end(), out );
cout << " Done!" << endl;
return 0;
}
/
output:
>g++ baidu.C
> ./a.out
1
3
5
7
9
20
31
42
53
64
75
86
97
Done!
TO qdyongge:
         =====================================================
         ||晕,看到那个求小于100000的那个题的没一个对的!
         ||看看14可以合成不?
         ||f(a)=b;
         ||f(a+1)=c;
         ||b到c之间的都是不可合成的数。
         ||原因:如果b与c间有d可以由合成即f(x)=d;
         ||=> x>a && x<a+1
         ||=> ...........
         =====================================================

你的说法不对噢!认真的思考一下: 14=7+7;
其次:你的这个理论:"(a)=b;f(a+1)=c;b到c之间的都是不可合成的数"有什么数学根据吗?
用一个简单证伪:
     f(999)=999+9+9+9=1026;
     f(999+1)=1000+1=1001;
     在1001--1026之间可合成的数很多,就列一个吧.如:1024=998+9+9+8;


 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值