笔试题总结

1、ASSERT与VERIFY的有什么 相同 和不同呢 

1 ASSERT与VERIFY宏在Debug模式下作用基本一致,二者都对表达式的值进行计算,如果值为非0,则什么事也不做;如果值为0,则输出诊断信息。
2 ASSERT与VERIFY宏在Release模式下效果完全不一样。ASSERT不计算表达式的值,也不会输出诊断信息;VERIFY计算表达式的值,但不管值为0还是非0都不会输出诊断信息。VERIFY与ASSERT用在程序调试上并无本质上的区别。
此外,TRACE() 宏的编译也受 _DEBUG 控制。 所有这些断言都只在 Debug版中才被编译,而在 Release 版中被忽略。唯一的例外是 VERIFY() 。事实上,这些宏都是调用了 assert() 函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用 等),那么 Release 版都不会执行这些操作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入 #ifdef _DEBUG 之类的条件编译,也要注意一下。
顺便值得一提的是 VERIFY() 宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查 Windows API 的返回值。有些人可能为这个原因而滥用 VERIFY() ,事实上这是危险的,因为 VERIFY() 违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏


2、文件input.data中包含9999990个数字,这些数字都在1-10000000之间并且是未排序的。每个数字仅出现一次并占用一行,请给出一个程序,统计哪十个数字没有出现在input.data中,将结果输出到Output.data文件中(占用内存越小越好,运行时间越快越好) 
答: http://blog.csdn.net/v_JULY_v/article/details/6451990

位图方案。熟悉位图的朋友可能会想到用位图来表示这个文件集合。例如正如编程珠玑一书上所述,用一个20位长的字符串来表示一个所有元素都小于20的简单的非负整数集合,边框用如下字符串来表示集合{1,2,3,5,8,13}:
0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0
上述集合中各数对应的位置则置1,没有对应的数的位置则置0。

 参考编程珠玑一书上的位图方案,针对我们的10^7个数据量的磁盘文件排序问题,我们可以这么考虑,由于每个7位十进制整数表示一个小于1000万的整数。我们可以使用一个具有1000万个位的字符串来表示这个文件,其中,当且仅当整数i在文件中存在时,第i位为1。采取这个位图的方案是因为我们面对的这个问题的特殊性:1、输入数据限制在相对较小的范围内,2、数据没有重复,3、其中的每条记录都是单一的整数,没有任何其它与之关联的数据。
  所以,此问题用位图的方案分为以下三步进行解决:
第一步,将所有的位都置为0,从而将集合初始化为空。
第二步,通过读入文件中的每个整数来建立集合,将每个对应的位都置为1。
第三步,检验每一位,如果该位为1,就输出对应的整数。
    经过以上三步后,产生有序的输出文件。令n为位图向量中的位数(本例中为1000 0000),程序可以用伪代码表示如下:
 

//磁盘文件排序位图方案的伪代码//copyright@ Jon Bentley//July、updated,2011.05.29。
//第一步,将所有的位都初始化为0for i ={0,....n}    bit[i]=0;
//第二步,通过读入文件中的每个整数来建立集合,将每个对应的位都置为1。for each i in the input file    bit[i]=1;
//第三步,检验每一位,如果该位为1,就输出对应的整数。for i={0...n}    if bit[i]==1      write i on the output file  

//copyright@ yansha  
//July、2010.05.30。  
//位图方案解决10^7个数据量的文件的排序问题  
//如果有重复的数据,那么只能显示其中一个 其他的将被忽略  
#include <iostream>  
#include <bitset>  
#include <assert.h>  
#include <time.h>  
using namespace std;  
  
const int max_each_scan = 5000000;  
  
int main()  
{  
    clock_t begin = clock();  
    bitset<max_each_scan> bit_map;  
    bit_map.reset();  
      
    // open the file with the unsorted data  
    FILE *fp_unsort_file = fopen("data.txt", "r");  
    assert(fp_unsort_file);  
    int num;  
  
    // the first time scan to sort the data between 0 - 4999999  
    while (fscanf(fp_unsort_file, "%d ", &num) != EOF)  
    {  
        if (num < max_each_scan)  
            bit_map.set(num, 1);  
    }  
      
    FILE *fp_sort_file = fopen("sort.txt", "w");  
    assert(fp_sort_file);  
    int i;  
      
    // write the sorted data into file  
    for (i = 0; i < max_each_scan; i++)  
    {  
        if (bit_map[i] != 1)  
            fprintf(fp_sort_file, "%d ", i);  
    }  
      
    // the second time scan to sort the data between 5000000 - 9999999  
    int result = fseek(fp_unsort_file, 0, SEEK_SET);  
    if (result)  
        cout << "fseek failed!" << endl;  
    else  
    {  
        bit_map.reset();  
        while (fscanf(fp_unsort_file, "%d ", &num) != EOF)  
        {  
            if (num >= max_each_scan && num < 10000000)  
            {  
                num -= max_each_scan;  
                bit_map.set(num, 1);  
            }  
        }  
        for (i = 0; i < max_each_scan; i++)  
        {  
            if (bit_map[i] != 1)  
                fprintf(fp_sort_file, "%d ", i + max_each_scan);  
        }  
    }  
      
    clock_t end = clock();  
    cout<<"用位图的方法,耗时:"<<endl;  
    cout << (end - begin) / CLK_TCK << "s" << endl;  
    fclose(fp_sort_file);  
    fclose(fp_unsort_file);  
    return 0;  
}  

产生随即数的函数:

//purpose:  生成随机的不重复的测试数据  
//copyright@ 2011.04.19 yansha  
//1000w数据量,要保证生成不重复的数据量,一般的程序没有做到。  
//但,本程序做到了。  
//July、2010.05.30。  
#include <iostream>  
#include <time.h>  
#include <assert.h>  
using namespace std;  
  
const int size = 10000000;  
int num[size];  
  
int main()  
{  
    int n;  
    FILE *fp = fopen("data.txt", "w");  
    assert(fp);  
  
    for (n = 1; n <= size; n++)    
        //之前此处写成了n=0;n<size。导致下面有一段小程序的测试数据出现了0,特此订正。  
        num[n] = n;  
    srand((unsigned)time(NULL));  
    int i, j;  
  
    for (n = 0; n < size; n++)  
    {  
        i = (rand() * RAND_MAX + rand()) % 10000000;  
        j = (rand() * RAND_MAX + rand()) % 10000000;  
        swap(num[i], num[j]);  
    }  
  
    for (n = 0; n < size; n++)  
        fprintf(fp, "%d ", num[n]);  
    fclose(fp);  
    return 0;  
}



3、现有一个函数,功能是: 将英文字符串S中所有A子串换成B。要求:1、写出这个函数的合理定义形式(不用写出实现);2、给出白盒测试代码。注意:尽可能在测试代码中包含典型测试用例,实现代码覆盖率高,并满足功能验证 

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

int get_next(char* t,int next[])
{
  int i = 0;
  int k = -1;
  int len = strlen(t);
   next[0] = k;
  
  while(i<len-1)
  {
   if( k==-1 || t[i]==t[k] )
     {
       k++;
       i++;
      if(t[i] != t[k])
         next[i] = k;
      else
         next[i] = next[k]; 
      }
    else
       k = next[k]; 
   } 
}

int kmp_find(char* s,char* t)
{
  int i = 0;
  int j = 0;
  int len1 = strlen(s); 
  int len2 = strlen(t); 
  int next[len2];
   get_next(t,next);
  
  while(i<len1 && j<len2) 
   {
     if( j==-1 || s[i] == t[j])
      {
        i++;
        j++;
      }
     else
       j = next[j]; 
   }
   
   if(j>=len2)
     return i-len2;
   else
   return -1;
}

char* substr(char* s,char* a,char* b)
{
    int len = strlen(a);
    
    int index = kmp_find(s,a);
    //kmp find where is a in s or you can use strstr
    char* head = s;
    *(head+index) = '\0';
    char* tail = s + index + len;
    //把字符串s分为 head a tail三部分
    sprintf(s,"%s%s%s",head,b,tail);
  
    if(kmp_find(s,a) != -1)//如果替换一个后还含有a继续
     return substr(s, a, b);
    else
     return s;
}
     
int main(int argc, char *argv[])
{
  char* s = (char*)malloc(100);
  memset(s,0,100);
  sprintf(s,"%s",argv[1]);

  printf("str:%s\n",s); 
  printf("sub:%s by %s\nafter:%s\n",argv[2],argv[3],substr(s, argv[2], argv[3]));

  free(s);
   s=NULL;
  system("PAUSE");    
  return 0;
}
#include   <stdio.h> 
#include   <string.h> 
#include   <stdlib.h> 

char   *   replace(const   char   *   str,   const   char   *   str1,   const   char   *   str2)   { 
        char     *   pstr1,   *   pstr2,   *   pbuf1,   *   pbuf2; 
        char         ch; 
        pbuf1   =   NULL; 
        pbuf2   =   NULL; 
        pstr1   =   strstr(str,   str1); 
        while(pstr1   !=   NULL)   
	{ 
            ch   =   *pstr1; 
            *pstr1   =   0; 
            if(pbuf1   ==   NULL)  
	    { 
               pbuf1   =   (char   *)malloc(strlen(str)   +   strlen(str2)   +   1); 
               pbuf1[0]   =   0; 
            }       
	    else  
	   { 
               pbuf2   =   (char   *)malloc(strlen(pbuf1)   +   strlen(str)   +   strlen(str2)   +   1); 
               strcpy(pbuf2,   pbuf1); 
               free(pbuf1); 
               pbuf1   =   pbuf2; 
            } 
            strcat(pbuf1,   str); 
            strcat(pbuf1,   str2); 
            *pstr1   =   ch; 
            str   =   pstr1   +   strlen(str1); 
            pstr1   =   strstr(str,   str1); 
        } 
        if(str&&str[0])  
	{ 
            if(pbuf1   ==   NULL)  
	    { 
                pbuf1   =   (char   *)malloc(strlen(str)   +   strlen(str2)   +   1); 
                pbuf1[0]   =   0; 
             }       
	     else   
	     { 
               pbuf2   =   (char   *)malloc(strlen(pbuf1)   +   strlen(str)   +   strlen(str2)   +   1); 
               strcpy(pbuf2,   pbuf1); 
               free(pbuf1); 
               pbuf1   =   pbuf2; 
             } 
            strcat(pbuf1,   str); 
        } 
        return   pbuf1; 
} 

int   main(int   argc,   char   **   argv)   { 
        char   *   pstr; 
        if(argc   !=   4)  
	{ 
                fprintf(stderr,   "Error,   parameter\n "); 
                return   1; 
        } 
        pstr   =   replace(argv[1],   argv[2],   argv[3]); 
        fprintf(stdout,   "replace(\ "%s\ ",   \ "%s\ ",   \ "%s\ ")   =   \ "%s\ "\n ", 
                        argv[1],   argv[2],   argv[3],   pstr); 
        free(pstr); 
        return   0; 
} 


4、有一个整数n,写一个函数f(n),返回0到n之间出现的"1"的个数。如:f(1)=1     f(11)=4    f(13)=6  请编写程序,实现f(n)。要求:写出核心算法,表达清晰,可用伪代码 

# 0~99 中含有一的数字为 01 11(不含十位1) 21 31 41 51 61 71 81 91 和 10 11(不含个位1) 12 13 14 15 16 17 18 19 共20个
# 这样的话,每100 个数之间会有20个1  
# 但是 100 ~ 199 是个特例,这中间除了这20个1 还有100个百位开头的1 这和10~19 其实是差不多的
# 其实昨天算错了,不应该算 0~100 是多少 应该算 0~99 为多少,凡是1作为首位的 都需要特殊处理

0~9 之间有1 个 个位1 ,10~19之间也有1个 个位1 也就是说 每10位中有1位个位1 (当个位大于1时也会有1个个位1)
# 0~99之间有 1类10位1(10~19) 每百位有一位10位1
# 同理,每千位有1位 百位1  
# 可能有点乱,没事 找个实例实验一下 253怎么样?呵呵
#
# 按照上面的分析,253 拆分如下 m为总数:
# 有25 + 1(这里加1 因为3>1)个 个位1 (01,11,21……251) || m=26
# 有2 + 1(这里加1 因为 5>1)个 十位1 (1*,11*,21*) || m=26 + 3*10 =56
# 有1(因为 2>1)个百位1 (1**) || m=56 + 1*100 = 156
#  
# 呵呵 这样就出来了 程序就好写了 但是为1的时候要特殊处理下 将后面所有的数+1(因为是 00~53) 算做1的数量 比如 153
# m = 16 + 2*10 + (53+1) = 90 这个结果对吧。


#include <IOSTREAM>
/*
* 
*/
int main(int argc, char* argv[])
{
	int n,i,j,k,f,m,s=0;
	i=0;
	m=1;
	printf("Please input a number:");
	scanf("%d",&n);
	k=n;
	f=n;
	while(k!=0)
	{
		k/=10;
		i++;
	}
	if(f<=9&&f>=1)
	{
		s=1;
	}
	else
	{
		for(j=0;j<=i;j++)
		{
			if((n/m)%10==0)
			{
				s=s+(n/(m*10))*m;
			}
			else if((n/m)%10==1)
			{
				s=s+(n/(m*10))*m+n%m+1;
			}else if((n/m)%10>1)
			{
				s=s+((n/(m*10))+1)*m;
			}
			m*=10;	
		}	
	}
	printf("The result is:%d\n",s);
	return 0;
}


5、1、搜索引擎方向:全文检索、自然语言处理、云计算 2、XML数据库方向:XQuery实现、XML存储、索引 3、跨媒体检索方向:图形、图像、音频、视频检索 

你可能感兴趣的:(笔试题总结)