[心得]面试题分析与整理7

本文介绍了一种使用位向量在大型文件中寻找未出现整数的方法,针对内存限制还提出了分区扫描策略。此外,还提供了C语言标准库中几个常用字符串操作函数的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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中并返回schar *strcpy(s, ct)
strcat将字符串连接到s的尾部,并返回schar *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;
            }
        }
    }
}

这里面有个缺陷,分配了内存没有释放。

  1. 实现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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值