google笔试题1

http://hi.baidu.com/zhanghaooy/blog/item/d417893465deec44251f148c.html吐舌头


1.两个二进制数的异或结果是多少?

2.递归函数最终会结束,那么这个函数一定(不定项选择):

选项:

1. 使用了局部变量 2. 有一个分支不调用自身
3. 使用了全局变量或者使用了一个或多个参数

这是一道简单的选择题,但包含的内容并不算简单,而不定项选择更加大了难度。我一眼看去,自然就选择了2和3。
1显然不是,局部变量只在一次调用局部范围有效,出了这次调用的范围就无效了,它不能控制递归的结束。(这个选项是考查局部变量生命周期/有效范围的问题)需要注意的就是局部变量不是局部静态变量。
对于2,很自然了,如果没有一个分支不调用自身,递归就不会结束了。(这是在考查递归的定义)
对于3,这是最有迷惑性的,因为使用全局变量或使用一个或多个参数的确可以控制递归的结束,但是不是只有这两种方式呢?所以题目中指出了"一定"。答案是并不是只有这两种方式。

  • 我们知道局部静态变量存放在堆中而不是栈中,所以它在程序生命周期内都是存在的,只是只有在函数内才能被访问,其内容是上次处理后的内容或是初始化后的内容,调用多次都同一个变量实例。所以局部静态变量是可以控制递归函数最终结束的。
    在C语言中,可以用
    static int a;
    来定义,在Delphi中可以用
    const a:integer;
    来定义(注意编译器开关$J+)
    这里会有很多人认为局部静态变量就是全局变量,这是错误的,全局变量应该是生命周期和有效作用域都有全局性,而局总静态变量只有生命周期是全局的,而作用域是只在函数体内有效。

  • 可能通过异常来控制递归的结束。其实这种情况很常见,每个应用程序的缺省栈空间大小是不会太大的,很容易因为堆栈溢出而让递归函数终止。此外,还可以会发生其它的异常,比如内存空间不足、除零等等。这些异常都可以让递归函数终止。
  • 我们一般所说的全局变量都是针对一个应用程序而言的,所以我们还可以利用BIOS或OS的一些数据或一些标准库的全局值来控制递归过程的终止。比如利用日期时间、利用库中的随机数等等。
  • 我们还可以把一些数据写入到BIOS或OS的系统数据区,也可以把数据写入到一个文件中,以此来控制递归函数的终止。
  • 还有......还没想到

呵呵,所以,正确答案是2,只有这一个。

3.T(n)=35T(n/5)+n^2时间复杂度
4.n个顶点,m个边的全连通图,至少去掉几条边才能构成一棵树?
 n个顶点的树有n-1条边,那么要去掉m-(n-1)条边
5.如何减少换页错误?

1,进程倾向于占用CPU

2,访问局部性(localilty of reference)满足进程要求

3,进程倾向于占用I/O

4,使用基于最短剩余时间(shortest remaining time)的调度机制

5,减少页大小

换页错误:

Page Fault 是在进程尝试执行代码指导,或者引用进程所映射物理内存中并不存在的数据页时,操作系统记录的事件。换句话说,进程需要的内存页实际上可能还处于物理内存中,但是由于它无法再分配到进程中,所以当进程将此页读取回到它的内存页时,就发生了Page Fault。

说白了就是想在内存里找东西,却发现不存在(不得不重新读取...),按道理这不应该算“错误”这么严重吧(简单点,“不命中”而已)。

采用最短剩余时间调度机制:

SRT算法(SPN算法的抢占式版本):总是选择剩余时间最短的进程运行

为什么会减少换页错误呢?因为时间短的结束运行快,不需要频繁切换进程(导致刷新内存),所以换页错误发生的概率就减少了......



6.实现两个N*N矩阵的乘法,矩阵由一维数组表示
#include<iostream>
using namespace std;
#define size 2

int * multi(int* a, int* b, int N)
{
   int i,j,k,temp;
   int * c = (int *)malloc(N*N);
   for(i=0;i<N;i++)
   {
       for(j=0;j<N;j++)
       {
           temp = i*N + j;
           *(c+temp) = 0;
           for(k=0;k<N;k++)
           {
               *(c+temp) += a[i*N + k]*b[k*N + j];
           }
           cout<<*(c+temp)<<" ";
           
       }
   }   
   return c;
}


int main()
{
   int a[size*size] = {2,1,4,3};
   int b[size*size] = {1,-1,3,2};
    multi(a,b,size);
   return 0;
}

7.找到单链表中间的那个元素,如果两个则取前面那个
cur = mid = head;
= j = 0;
while(cur != null ){
    
if( i / 2 > j){
          j
++;
          mid 
= mid ->next;
       }
    i
++;
    cur 
= cur->next
}

8.长度为n的整数数组,找出其中任意n-1个乘积最大的那一组,只能用乘法,不可以用除法,要求对算法的时间复杂度和空间复杂度做出分析,不要求写程序。


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

long GetMax(int array[], int len);
long GetMultiply(int array[], int len, int tag, int count);

int main()
{
     int array[] = {0, -2, -3, -4};
     printf("%ld\n", GetMax(array, 4));
     return 0;
}

long GetMax(int array[], int len)
{
     int positive_num = 0; 
     int negative_num = 0;
     int zero_num = 0;
     int positive_min = INT_MAX;
     int negative_max = INT_MIN;
     int negative_min = 0;
     int count = 1;
     int i;

     if(!array)
     {
         printf("array must not be NULL\n");
         exit(-1);
     }
     if(len < 1)
     {
         printf("len should be bigger than 0\n");
         exit(-1);
     }    

     for(i = 0; i < len; i++)
     {
         if(array[i] > 0)
         {
             positive_num++;
             positive_min = (positive_min < array[i])? positive_min: array[i];
         }
         else if(array[i] == 0)
         {
             zero_num++;
         }
         else
         {
             negative_num++;
             negative_max = (negative_max > array[i])? negative_max: array[i];
             negative_min = (negative_min < array[i])? negative_min: array[i];
         }
     }
    
     if(zero_num > 1) return 0;
     else if(zero_num == 1)
     {
         if(negative_num % 2 == 1) return 0;
         else
         {
             return GetMultiply(array, len, 0, 1);
         }
     }
     else
     {//no zero
         if(negative_num % 2 == 1)    
         {
             return GetMultiply(array, len, negative_max, 1);
         }
         else
         {
             if(positive_num > 0)    
                 return GetMultiply(array, len, positive_min, 1);
             else
                 return GetMultiply(array, len, negative_min, 1);
         }
     }
}

long GetMultiply(int array[], int len, int tag, int count)
{
     long multiply = 1;
     int i;

     if(!array)
     {
         printf("array must not be NULL\n");
         exit(-1);
     }
     if(len < 1)
     {
         printf("len should be bigger than 0\n");
         exit(-1);
     }    


     for(i = 0; i < len; ++i)
         if(array[i] == tag && count > 0)
             count--;
         else multiply *= array[i]; 
     return multiply;
}



















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值