diff --git a/README.md b/README.md index 77ac503..66eab6f 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ | Current Status| Stats | | :------------: | :----------: | -| Total Problems | 54 | -| Current Streak | 35 | -| Longest Streak | 35 ( August 17, 2015 - September 20, 2015 ) | +| Total Problems | 56 | +| Current Streak | 36 | +| Longest Streak | 36 ( August 17, 2015 - September 21, 2015 ) | @@ -60,6 +60,7 @@ Include contains single header implementation of data structures and some algori |Given a vector of numbers, only one number occurs odd number of times, find the number.| [find_odd_one_out.cpp](bit_manipulation/find_odd_one_out.cpp)| | Given two integers, determine if their sum would be interger overflow.| [integerOverflow.cpp](bit_manipulation/integerOverflow.cpp)| | How many bit flip operation would require to convert number A to B. | [countNumberOfBitFlips.cpp](bit_manipulation/countNumberOfBitFlips.cpp)| +| Given a number x and two positions (from right side) in binary representation of x, write a function that swaps n right bits at given two positions and returns the result. It is also given that the two sets of bits do not overlap.|[swapSetOfBits.cpp](bit_manipulation/swapSetOfBits.cpp)| ### Cracking the coding interview problems | Problem | Solution | @@ -109,3 +110,4 @@ Include contains single header implementation of data structures and some algori | Problem | Solution | | :------------ | :----------: | | Depth First Traversal of a Graph | [dfsDemo.cpp](graph_problems/dfsDemo.cpp) | +| Breadth First Traversal of a Graph | [bfsDemo.cpp](graph_problems/bfsDemo.cpp) | diff --git a/bit_manipulation/swapSetOfBits.cpp b/bit_manipulation/swapSetOfBits.cpp new file mode 100644 index 0000000..2abfd6d --- /dev/null +++ b/bit_manipulation/swapSetOfBits.cpp @@ -0,0 +1,46 @@ +/** + * Problem - Given a number 'num' and two positions (p1 and p2 from right side) in binary representation of num, + * write a function that swaps n bits at given two positions and returns the result. + * It is also given that the two sets of bits do not overlap. + */ + +#include + +int swapBits(unsigned int num, unsigned int p1, + unsigned int p2, unsigned int n ) +{ + //Step1 lets form a number set1 by moving n bits at position p1 to the rightmost + unsigned int set1 = (num >> p1 ) & ((1U << n) - 1); + // Lets understand what we just did. + // Part1 : (num >> p1), we just right shifted num so that bit at p1 position takes 0th postion. + // Part2 : Remember we needed n bits from position p1(which has become position 0) + // So, (1U << n) moves 1 to nth bit, i.e. it the value formed by this movement is 2^n + // Now, If we substract 1 from the (2^n), it will give us all 1's for n positions. + // For example (1U << 3) = 1000 + // and (1U << 3) - 1 = 0111 + // Part3 : Thus Part1 & Part2 will give as n bits which were at P1 (now moved to 0) + + //similarly for p2 + unsigned int set2 = (num >> p2) & ((1U << n) - 1); + + // xor two sets ( we are doing similar to xor swap algorithm ) + // https://en.wikipedia.org/wiki/XOR_swap_algorithm + unsigned int xorSets = set1 ^ set2; + + // now moving back the xor'd sets to p1 and p2 + xorSets = (xorSets << p1) | (xorSets << p2); + + unsigned int finalVal = xorSets ^ num; + return finalVal; +} + +int main() +{ + std::cout << "Swaping bits in number 28, such that 2 bits starting from 0th bit and 2 bits " + "starting from 3rd bit are swapped, 28 becomes " << swapBits(28, 0, 3, 2) + << std::endl; + + std::cout << "Swaping bits in number 47, such that 3 bits starting from 1st bit(0 based counting) and 3 bits " + "starting from 5th bit(0 based counting) are swapped, 47 becomes " << swapBits(47, 1, 5, 3) + << std::endl; +} diff --git a/graph_problems/bfsDemo.cpp b/graph_problems/bfsDemo.cpp new file mode 100644 index 0000000..f4d85fe --- /dev/null +++ b/graph_problems/bfsDemo.cpp @@ -0,0 +1,29 @@ +#include +#include "graph.h" + +/** + * Implementation of BFS algorithm is in ../include/graph.h + */ + +int main() +{ + std::vector vec{ 0, 1, 2, 3, 4, 5, 6, 7 }; + algo::Graph g(vec); + g.setEdge(0, 1); + g.setEdge(0, 2); + g.setEdge(1, 0); + g.setEdge(1, 2); + g.setEdge(1, 3); + g.setEdge(2, 4); + g.setEdge(2, 6); + g.setEdge(3, 1); + g.setEdge(3, 7); + g.setEdge(4, 6); + g.setEdge(5, 1); + g.setEdge(5, 3); + g.setEdge(6, 5); + g.setEdge(7, 5); + g.display(); + g.breadth_first_search(0); + return 0; +} diff --git a/graph_problems/dfsDemo.cpp b/graph_problems/dfsDemo.cpp index 863c325..5b38f0e 100644 --- a/graph_problems/dfsDemo.cpp +++ b/graph_problems/dfsDemo.cpp @@ -1,5 +1,10 @@ #include -#include +#include "graph.h" + + +/** + * Implementation of BFS algorithm is in ../include/graph.h + */ int main() { diff --git a/include/graph.h b/include/graph.h index 4bab893..3bfb1cd 100644 --- a/include/graph.h +++ b/include/graph.h @@ -2,12 +2,15 @@ #define _GRAPH_H #include +#include + namespace algo { template // Type of data vertex will hold class Graph { int numOfVertices; // number of vertices. struct Vertex; // forward declaration of vertex structure + struct Node { // linkedlist for mapping edges in the graph Vertex * vertexPtr; // points to the vertex to which the edge is adjecent Node * next; // points to the next edge belonging to same vertex @@ -26,116 +29,190 @@ namespace algo { std::vector vertices; // vector of all vertices. - Node * getNode(Vertex * v) // allocate and initialize a newnode for the adj list. - { - Node * newNode = new Node; - newNode->vertexPtr = v; - newNode->next = nullptr; - return newNode; - } - - void insertAtEnd( Node * & node, Vertex * v) //insert at the end of adjacency list of vertex. - { - Node *newNode = getNode(v); - if ( node == nullptr ) { - node = newNode; - } else { - Node * temp = node; - while( temp->next != nullptr ) { - temp = temp->next; - } - temp->next = newNode; + //private methods + Node * getNode( Vertex * ); // allocate and initialize a newnode for the adj list. + void insertAtEnd( Node * & , Vertex * ); // insert at the end of adjacency list of vertex. + void deleteAllAfter( Node * ); // delete the adjacency list of the vertex. + void depth_first_traversal_util(Vertex * ); // Private utility function for DFS + + public: + Graph() = default; // Default constructor + Graph(std::vector &); // Constructor which takes vector of vertex data + void setEdge(dataType, dataType); // For setting a edge of graph + void display() const; // Print current config of the graph. + void breadth_first_search(dataType); // Breadth first traversal of the graph + void depth_first_search(dataType); // Depth first traversal of the graph + ~Graph(); + }; //end of class Graph + + + template + typename Graph::Node * + algo::Graph::getNode(Vertex * v) // allocate and initialize a newnode for the adj list. + { + Node * newNode = new Node; + newNode->vertexPtr = v; + newNode->next = nullptr; + return newNode; + } + + template + void Graph::insertAtEnd( Node * & node, Vertex * v) // insert at the end of adjacency list of vertex. + { + Node *newNode = getNode(v); + if ( node == nullptr ) { + node = newNode; + } else { + Node * temp = node; + while( temp->next != nullptr ) { + temp = temp->next; } + temp->next = newNode; } - - void deleteAllAfter( Node * node ) // delete the adjacency list of the vertex. - { - Node * nextNode; - while( node != nullptr ) { - nextNode = node->next; - delete(node); - node = nextNode; + } + + template + void Graph::deleteAllAfter( Node * node ) // delete the adjacency list of the vertex. + { + Node * nextNode; + while( node != nullptr ) { + nextNode = node->next; + delete(node); + node = nextNode; + } + } + + + template + Graph::Graph(std::vector & values) // Non default constructor, takes a vector of vertices data + : numOfVertices(values.size()), + vertices(numOfVertices) + { + for ( int i = 0; i < numOfVertices; ++i ) { + vertices[i].data = values[i]; + vertices[i].list = nullptr; + vertices[i].state = WHITE; + } + } + + template + void Graph::setEdge(dataType data1, dataType data2) // Setting individual edge of the graph. + { + for (int i = 0; i < numOfVertices; ++i) { + if (vertices[i].data == data1) { + for ( int j = 0; j < numOfVertices; ++j) { + if (vertices[j].data == data2) { + insertAtEnd(vertices[i].list, &vertices[j]); + break; + } + } + break; } } - - void depth_first_traversal_util(Vertex * v) { - v->state = GRAY; - std::cout << v->data << " "; - Node * node = v->list; + } + + template + void Graph::display() const // Prints the current config of the graph + { + Node * node; + for ( int i = 0; i < numOfVertices; ++i ) { + std::cout << "Vertex:" << vertices[i].data << " "; + std::cout << "Connections: "; + node = vertices[i].list; while( node != nullptr ) { - if (node->vertexPtr->state == WHITE) { - depth_first_traversal_util(node->vertexPtr); - } + std::cout << node->vertexPtr->data << " "; node = node->next; } - v->state = BLACK; + std::cout << std::endl; + } + } + + template + void Graph::breadth_first_search(dataType startElem) // Breadth first traversal of the graph + { + //mark all vertices as not visited, i.e. state = WHITE + for ( int i = 0; i < numOfVertices; ++i ) { + vertices[i].state = WHITE; } - public: - Graph() = default; - Graph(std::vector & values) - : numOfVertices(values.size()), - vertices(numOfVertices) - { - for ( int i = 0; i < numOfVertices; ++i ) { - vertices[i].data = values[i]; - vertices[i].list = nullptr; - vertices[i].state = WHITE; + // search for the vertex containing start element + Vertex * startVertex = nullptr; + for ( int i = 0; i < numOfVertices; ++i ) { + if ( vertices[i].data == startElem ) { + startVertex = &vertices[i]; + break; } } - void setEdge(dataType data1, dataType data2) - { - for (int i = 0; i < numOfVertices; ++i) { - if (vertices[i].data == data1) { - for ( int j = 0; j < numOfVertices; ++j) { - if (vertices[j].data == data2) { - insertAtEnd(vertices[i].list, &vertices[j]); - break; - } - } - break; - } - } + //Return if start vertex not found + if ( startVertex == nullptr ) { + return; } - void display() - { - Node * node; - for ( int i = 0; i < numOfVertices; ++i ) { - std::cout << "Vertex:" << vertices[i].data << " "; - std::cout << "Connections: "; - node = vertices[i].list; - while( node != nullptr ) { - std::cout << node->vertexPtr->data << " "; - node = node->next; + //Create a queue for traversing breadth wise. + std::queue vertexQueue; + + //mark the first vertex as being processed + startVertex->state = GRAY; + //push the first vertex + vertexQueue.push(startVertex); + Vertex * currVertex = nullptr; + + while( !vertexQueue.empty() ) { + currVertex = vertexQueue.front(); + vertexQueue.pop(); + currVertex->state = BLACK; + std::cout << currVertex->data << " "; + Node * adjVertex = currVertex->list; + while( adjVertex != nullptr ) { + if ( adjVertex->vertexPtr->state == WHITE ) { + adjVertex->vertexPtr->state = GRAY; + vertexQueue.push(adjVertex->vertexPtr); } - std::cout << std::endl; + adjVertex = adjVertex->next; } } - - void depth_first_search(dataType startElem) - { - for( int i = 0; i < numOfVertices; ++i ) { - vertices[i].state = WHITE; + std::cout << std::endl; + } + + template + void Graph::depth_first_traversal_util(Vertex * v) // Depth first search private utility function + { + v->state = GRAY; + std::cout << v->data << " "; + Node * node = v->list; + while( node != nullptr ) { + if (node->vertexPtr->state == WHITE) { + depth_first_traversal_util(node->vertexPtr); } - for ( int i = 0; i < numOfVertices; ++i) { - if (vertices[i].data == startElem) { - depth_first_traversal_util(&vertices[i]); - break; - } - } - std::cout << std::endl; + node = node->next; } - - ~Graph() - { - for( int i = 0; i < numOfVertices; ++i ) { - deleteAllAfter(vertices[i].list); + v->state = BLACK; + } + + template + void Graph::depth_first_search(dataType startElem) // Public function for depth first traversal + { + for( int i = 0; i < numOfVertices; ++i ) { + vertices[i].state = WHITE; + } + for ( int i = 0; i < numOfVertices; ++i) { + if (vertices[i].data == startElem) { + depth_first_traversal_util(&vertices[i]); + break; } } + std::cout << std::endl; + } + - }; //end of class graph + template + Graph::~Graph() + { + for( int i = 0; i < numOfVertices; ++i ) { + deleteAllAfter(vertices[i].list); + } + } } //end of namespace algo