25.给定一个文件,包含40亿个非负整数
设计一种产生一个不在该文件中整数的算法
面试金典246页原题
思路是采用位向量
最后从索引0开始查找第一个0值的索引
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
/**
* Created by tangchen on 2016/10/6.
*/
public class findOpenNumber {
private long numberOfInts = ((long)Integer.MAX_VALUE + 1);
private byte[] bitfield = new byte[(int)(numberOfInts/8)];
void findOpenNumbers() throws FileNotFoundException {
Scanner in = new Scanner(new FileReader("file.txt"));
while(in.hasNextInt()){
int n = in.nextInt();
bitfield[n/8] |= 1<<(n%8);
}
for(int i=0;i<bitfield.length;i++){
for(int j=0;j<8;j++){
if((bitfield[i] & (1<<j)) == 0){
System.out.println(i*8+j);
return;
}
}
}
}
}
如果内存受限
那么要把数据分成一个个区块,逐个扫描
那么分布扫描
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
/**
* Created by tangchen on 2016/10/6.
*/
public class findOpenNumber {
private int bitsize = 1048576;//2^20bit
private int blockNum=4096;//2^12
private byte[] bitfield = new byte[bitsize/8];
private int[] blocks = new int[blockNum];
void findOpenNumbers() throws FileNotFoundException {
int starting = -1;
Scanner in = new Scanner(new FileReader("file.txt"));
while(in.hasNextInt()){
int n = in.nextInt();
blocks[n/(bitfield.length*8)]++;
}
for(int i=0;i<blocks.length;i++){
if(blocks[i]<bitfield.length*8){
starting = i*bitfield.length*8;
break;
}
}
in = new Scanner(new FileReader("file.txt"));
while(in.hasNextInt()) {
int n = in.nextInt();
if(n>=starting && n<starting+bitfield.length*8){
bitfield[(n-starting)/8] |= 1 << ((n-starting)%8);
}
}
for(int i=0;i<bitfield.length;i++){
for(int j=0;j<8;j++){
if((bitfield[i] & (1<<j)) == 0){
System.out.println(i*8+j);
return;
}
}
}
}
}
26.C语言标准库中库函数实现
尤其是string.h中库函数的实现
整理了主要函数如下:
函数名 | 含义 | 原型 |
---|---|---|
strcpy | 将字符串包括‘\0’复制到字符串s中并返回s | char *strcpy(s, ct) |
strcat | 将字符串连接到s的尾部,并返回s | char *strcat(s,ct) |
strcmp | 字符串比较 | int strcmp(cs,ct) |
strstr | 返回一个指针,它指向字符串ct第一次出现在字符串cs中的位置 | char *strstr(cs,ct) |
memcpy | 字符串拷贝 | void *memcpy(s,ct,n) |
strcpy实现链式返回,故有指针
char *strcpy(char *dest, const char *src)
{
if((!dest)||(!src)) return;
char *result = dest;
while((*dest++=*src++)!='\0');
return result;
}
再来一个strstr的实现:
char *mystrstr(const char *s, const char *find)
{
char *cp = s;
char *s1;
char *s2;
if(!*find) return s;
while(*cp)
{
s1 = cp;
s2 = find;
while(*s1 && *s2 && !(*s1-*s2))
{
s1++;
s2++;
}
if(!*s2) return cp;
cp++;
}
return NULL;
}
27.大数乘法实现
void multiply(int *a,int *b, int *c, int na,int nb, int nc)
{
int i,j,k;
int tmp;
int *result= new int[na*nb];
for(int i=0;i<na;i++)
{
k=i;
for(j=0;j<nb;j++)
{
result[k++]+=a[i]*b[j];
}
}
//translate result
for(k=nc-1;k>=0;--k)
{
if(result[k]>9)
{
if(k!=0)
{
c[k-1] += c[k]/10;
c[k]%=10;
}else
{
tmp = result[k]/10;
result[k]%=10;
}
}
}
}
这里面有个缺陷,分配了内存没有释放。
- 实现atoi(char *s)
int atoi(char *s)
{
int c;
int result;
int sign;
while(isspace(*s))
{
s++;
}
sign = (*s=='-')?-1:1;
if(*s=='+'||*s=='-') s++;
result = 0;
while(isdigit(*s))
{
result = 10*result + (*s - '0');
s++;
}
return sign*result;
}