Tuesday, May 6, 2014

Program for printing pemutations and combinations.

Description:
The below program prints permutation and combinations of a given string.

#include <iostream>
#include <string>

#include <stdlib.h>
#include <string.h>

using namespace std;
/*
 *  give all combinations of (abcd)
 *  {
 *   a + give all combinations of (bcd)
 *   b + give all combination of  (acd)
 *   c + give all combinations of (bad)
 *   d + give all combinations of (cba)
 *  }
 *
 */
void printPermutations(char output[], string input, int index, int searchindex, int r)
{

 
  if(1 == r)
  {
    for(int j = searchindex; j < input.length(); j++)
    {
       output[index] = input[j];
       cout << output << endl;
    }
    return;
  }

  for(int i = searchindex; i < input.length(); i++)
  {
    output[index] = input[searchindex];

     printPermutations(output, input, index + 1, searchindex + 1, r -1);

     input[searchindex] = input[i+1];
    input[i+1] = output[index];

  }
/*
 *                          abcdef
 *                         a  b c d
 *                      ab ac ad ae bc bd be cd ce de
 *      abc abd abe abf acd ace acf ade adf aef bcd bce bcf bde bdf bef cde cdf cef def
 *
 *
 *
 */
void printCombinations(char output[], string& input, int index, int searchindex,int r)
{

   //cout << index << "-" << searchindex << "-" << n << "-" << r << endl;

   if(1 == r)
   {
     for(int i = searchindex; i < input.length(); i++)
     {
       output[index] = input[i];
       cout << endl << output << " ";
     }
     return;
   }
   for(int j = searchindex; j+r <= input.length() ; j++)  // j < n
   {
     output[index] = input[j];
     printCombinations(output, input, index+1, j+1, r-1);
   }
}

int main(int argc, char** argv)
{
  int n,r;

  string input;

  cout << "Enter string:" << endl;

  cin >> input;

  cout << "How many you want to choose:" << endl;

  cin >> r;
  n = input.length();

  if(n < r)
  {
    cerr << "Invalid input" << endl;
    exit(1);
  }
  else if(n == r)
  {
    cout << "Possible combinations:" << endl << input << endl;
  }
  else
  {
   char* output = new char[r + 1];
   output[r] = '\0';

   cout << "Combinations:" << endl;

   printCombinations(output, input, 0, 0, r);

  }

   char* output = new char[n + 1];

   output[n] = '\0';
   cout << "Permutations:" << endl;
   printPermutations(output, input, 0, 0, r);

  exit(0);
}





Sample Ouput:

[root@localhost mytrials]# ./a.out
Enter string:
12345
How many you want to choose:
2
Combinations:

12
13
14
15
23
24
25
34
35
45 Permutations:
12
13
14
15
21
23
24
25
31
32
34
35
41
42
43
45
51
52
53
54
 

Saturday, March 15, 2014

Boost Thread Local Storage Example

Description: The below demonstrates the usage of thread local storages. It uses boost's implementation of thread local storage. The program creates mulitple thread which sends mulitple HTTP requests using libcurl.  In order for each thread to use a single connection to send HTTP requests, each thread should have a single CURL handle. Each thread creates his own handle in his local storage.

Progaram:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <curl/curl.h>
#include <boost/thread/tss.hpp>
#include <iostream>

using namespace std;

class HTTPHandle
{
  private:
    CURL* curl;

  public:

    HTTPHandle()
    {
      cout << "Creating curl easy handle" << endl;
      curl = curl_easy_init();
    }

    CURL* getHandle()
    {
       return curl;
    }

    ~HTTPHandle()
    {
      cout << "Cleaning up easy handle" << endl;
      curl_easy_cleanup(curl);
    }
};

void destroyHttpHandle(HTTPHandle* ptr)
{
  delete ptr;
}
void makeRequest()
{
 //We cannote directly create instance of  CURL since it is defined as 'typedef CURL void;'
  static boost::thread_specific_ptr<HTTPHandle> instance(destroyHttpHandle);
  // Create new HTTPHandle object if not already created one for this thread
  if(! instance.get())
  {
    instance.reset(new HTTPHandle);
  }

  CURL* curl = instance->getHandle();

  CURLcode res;

  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://10.10.0.1");
    // example.com is redirected, so we tell libcurl to follow redirection
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

    // Perform the request, res will get the return code
    res = curl_easy_perform(curl);
    // Check for errors
    if(res != CURLE_OK)
      cerr << "curl_easy_perform() failed:" << curl_easy_strerror(res) << endl;
  }
}

// Starting point of thread. Makes two HTTP request
void* thread_func(void* arg)
{
  for(int i = 1; i <= 2; i++)
  {
    makeRequest();
  }

  pthread_exit(NULL);
}

int main(void)
{
  pthread_t thread1, thread2;

  cout << "Global curl init." << endl;

  //initialize libcurl
  curl_global_init(CURL_GLOBAL_ALL);


  //Start two threads.

  pthread_create(&thread1, NULL, thread_func, NULL);

  pthread_create(&thread2, NULL, thread_func, NULL);

  // Wait for two threads to finish
  pthread_join(thread1, NULL);
  pthread_join(thread2, NULL);

  // Two threads completed. Each would have made two HTTP requests. No. of connection to 10.10.0.1 would be only two.
  // Since each thread creates only one curl handle. Check this using 'netstat -nap | grep 10.10.0.1'


  cout << "Check output of 'netstat -nap | grep 10.10.0.1'" << endl;

  sleep(5);

  cout << "Global curl cleanup." << endl;
  // global libcurl cleanup
  curl_global_cleanup();

}
Output:
Global curl init.
Creating curl easy handle
Creating curl easy handle
Cleaning up easy handle
Cleaning up easy handle
Check output of 'netstat -nap | grep 10.10.0.1'
Global curl cleanup.
 

[root@localhost curl]# netstat -nap | grep 10.223.3.131
tcp        0      0 10.223.3.171:45511          10.10.0.1:80             TIME_WAIT   -
tcp        0      0 10.223.3.171:45512          10.10.0.1:80             TIME_WAIT   -