Sunday, July 22, 2012

Eliminate duplicates and sort the list

Recently I received a List of zipcodes from a carrier. The zipcodes were duplicated and were not sorted. So I just wrote a small C++ code to sort and eliminate the duplicates from the list of zipcodes.

The program simply uses the set container in C++ STL, for the task. The set has the property that, it doesn't store duplicates. So, all we need to do is, insert all the elements (from the input file), into the set. And since set is also ordered in nature (implemented as a Red Black Tree), we can iterate over it to yield a sorted list. Below is the code-

#include <fstream>
#include <sstream>
#include <string>
#include <set>

using namespace std;

inline int convert(string &s)
{
int out;
istringstream ss(s);
ss >> out;
return out;
}

int main()
{
ifstream infile("input.txt");
ofstream outfile("output.txt");

string line;
int zipcode; //zipcode is just a integer

set<int> zipcodes;

while (getline(infile, line))
{
zipcode = convert(line);
zipcodes.insert(zipcode);
}

for (auto i = zipcodes.begin(); i != zipcodes.end(); i++)
outfile << *i << '\n';

infile.close();
outfile.close();

return 0;
}

To some, one keyword might have confused, that is "auto", in the for loop as -
auto i = zipcodes.begin() ;
Well, it was introduced in C++11 standard, to let the programmer omit typing the type of variable. The compiler well deduce the type by looking at the type of RHS. And I believe it is rather nice introduction, seeing how it can save you from rather ugly expressions. If you are using gcc with version prior to 4.7, you need to add a flag -std=c++0x while compiling in terminal or enable this flag in your IDE (if it is not already).

Wednesday, July 18, 2012

The stack that could give minimum in O(1)

This is one of my favorite interview question-
You have to create a stack which gives the smallest element in constant (or O(1)) time. 
You can be asked for the largest element instead of smallest also.

Take some time to think. Or read the grayed hint below, followed by the solution and explanation-
You can use linear amount of (extra) memory.
    Ok now the solution. You take a separate stack, call it min-stack. The other stack is the main-stack

    When you push a element in main-stack, compare the new element with top (using peek, not pop) of min-stack. Following cases are possible-
    1. The min-stack is empty => simply push the new element in min-stack as well.
    2. The min-stack top is smaller => do nothing.
    3. The min-stack top is larger => push the new element in min-stack as well.
    4. The min-stack top is equal => push the new element in min-stack as well. 
    When you pop the element from the main-stack, again compare the popped element with the min-stack top. There are only 2 cases now-

    1. The min-stack top is equal => pop from min-stack as well.
    2. The min-stack top is not equal => do nothing
    When the time comes for get minimum, just return the top of min-stack (taking care of underflow).

    For completeness, here is the C++ code

    void stack::push(int a)
    {
    main_stack.push(a);

    if (min_stack.is_empty())
    min_stack.push(a);
    else if (a <= min_stack.top())
    min_stack.push(a);
    }

    int stack::pop()
    {
    //take care of underflow here

    int e = main_stack.top();
    if (min_stack.top() == e)
    min_stack.pop();

    return e;
    }

    int stack::minimum()
    {
    //take care of underflow here

    return min_stack.top();
    }