1、ASSERT与VERIFY的有什么 相同 和不同呢
位图方案。熟悉位图的朋友可能会想到用位图来表示这个文件集合。例如正如编程珠玑一书上所述,用一个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、跨媒体检索方向:图形、图像、音频、视频检索