Saturday, November 12, 2016

Given an input file with four billion integers, provide an algorithm to generate an integer which is not contained in the file.

//Given an input file with four billion integers, provide an algorithm to generate an integer which is not contained in the file. Assume you have 1 GB memory. Follow up with what you would do if you have only 10 MB of memory.
//reference source:
//in that page MEMORY LIMITS SECTION
//below is c++solution
//Note : please create a file with name appropriately or download one from https://github.com/careercup/CtCI-6th-Edition/tree/master/Java/Ch%2010.%20Sorting%20and%20Searching/Q10_07_Missing_Int


PARTA:



#include <iostream>
#include <bitset>
#include <fstream>
#include <iomanip>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0X1F
#define N 2147483647

using namespace std;

void setBit(int i, int *a)
{
    a[i>>SHIFT] |= (1<<(i&MASK));
}

void clearBit(int i,int *a)
{
    a[i>>SHIFT] &= ~(1<<(i&MASK));
}

int testBit(int i,int *a)
{
    return a[i>>SHIFT] & (1<<(i&MASK));
}

void findNumber(){
    int a[1+N/BITSPERWORD];
   
    const char* filename = "input1.txt";
    ifstream inFile(filename,std::ios::in);
    
    // Make sure the file stream is good
    if(!inFile) {
        cout << endl << "Failed to open file " << filename;
        
    }
    
    int n = 0;
    while(inFile)
    {
        inFile>>n;
        clearBit(n,a);
        setBit(n,a);
        
    }
    for(int i=0;i<N;i++)
    {
        if(!testBit(i, a))
        {
            cout<<i;
        }
    }
}


int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    findNumber();
    return 0;

}



partB Follow UP:






#include <iostream>
#include <bitset>
#include <fstream>
#include <iomanip>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0X1F
#define N 2147483647
#define RANGESIZE 100

/* 1 << (i & MASK): left shift from 0 to 31, represents 2^i
 i >> SHIFT: array index
 0-31   a[0]
 32-63  a[1]
 64-95  a[2]
 ...    ...
 */

//set rangeSIZE as 1048576 which == 2power20 if the array can hols size of 10MB which == 2power 20
//#define RANGESIZE 1048576

using namespace std;


void setBit(int i, int *a)
{
    a[i>>SHIFT] |= (1<<(i&MASK));
}

//below function will clear the bit as below
//for eg if we have
//i 32 a is the bitvector

//i>>SHIFT will shift the i from 32 to 1 so we are accessing index =1 in the array a
//i&MASK will transform MASK  from 31 to 23

//1<<(i&MASK) will left shift 1 and make 23 bit position as 1
//hence a[i>>SHIFT] & (1<<(i&MASK)) which check if 23rd position is 0 or 1 which indictes the presence of the number throught bit position

void clearBit(int i,int *a)
{
    a[i>>SHIFT] &= ~(1<<(i&MASK));
}

int testBit(int i,int *a)
{
    return a[i>>SHIFT] & (1<<(i&MASK));
}
bool checkFile(ifstream *inFile)
{
    if(!(*inFile))
    {
        
        return false;
    }
    return true;
}
void getCountPerBlock(const char* filename,int *blocks)
{
    ifstream inFile(filename,std::ios::in);
   
        if(checkFile(&inFile)==true)
        {
            int n = 0;
            while(!inFile.eof())
            {
                inFile>>n;
                blocks[n/RANGESIZE]++;
                
            }
        }
        else
        {
            cout << endl << "Failed to open file ";
        }
    
}
int getMissingIndex(int *blocks,int size)
{
    for(int i=0;i<size;i++)
    {
        if(blocks[i]<RANGESIZE)
        {
            return i;
        }
    }
    return -1;
}
void setBitVector(int missingIndex,const char* fileName,int *blocks,int size,int *bitVector,int bitVectorSize)
{
    int startRange = RANGESIZE*missingIndex;
    int endRange   = RANGESIZE*missingIndex+RANGESIZE-1;
    int offSet = 0;
    ifstream inFile(fileName,std::ios::in);
    if(checkFile(&inFile)==true)
    {
        int n = 0;
        while(!inFile.eof())
        {
            inFile>>n;
            if(n>=startRange && n<=endRange)
            {
                offSet = n - (missingIndex*RANGESIZE);
                clearBit(offSet,bitVector);
                setBit(offSet,bitVector);
            }
        }
    }
    else
    {
        cout << endl << "Failed to open file ";
    }
}
int findZeroBit(int *bitArray,int size)
{
    
    for(int i=0;i<RANGESIZE;i++)
    {
        if(!testBit(i,bitArray))
        {
            return i;
        }
    }
    return -1;
}
void disp(int *blocks,int size)
{
    for(int i=0;i<size;i++)
    {
        cout<<blocks[i];
    }
}
void setArray(int *blocks,int size)
{
    for(int i=0;i<size;i++)
    {
        blocks[i]=0 ;
    }
}
void findNumber(){
    
    //change this value to INT_MAX when we test for a file which contains 1GB of consecutive numbers
    int maxInt = 500;
    //if the RAM size is 10 MB or the array size is of 2power20 == 10 MB set the rangesize as below
    
    
    
    
    const char* filename = "input2.txt";
    int blocks[maxInt/RANGESIZE+1];
    int bitVector[RANGESIZE/BITSPERWORD+1];
    int bitVectorSize = (int)(sizeof(blocks)/sizeof(blocks[0]));
    int size = (int)(sizeof(blocks)/sizeof(blocks[0]));
    
    setArray(blocks,size);
    
    getCountPerBlock(filename,blocks);
   
    
    int missingIndex = getMissingIndex(blocks,size);
    
    if(missingIndex!=-1)
    {
        cout<<missingIndex;
        
        setBitVector(missingIndex,filename,blocks,size,bitVector,bitVectorSize);
        
        int offset = findZeroBit(bitVector,bitVectorSize);
        
        if(offset!=-1)
        {
            int missingValue = RANGESIZE*missingIndex +offset;
            cout<<"missig value is"<<missingValue;
        }
    }
    else{
        cout<<"There is no missing value";
    }
    

}


int main(int argc, const char * argv[]) {
    findNumber();
    return 0;
}

No comments:

Post a Comment