Thursday, 18 May 2017

Merging M sorted sequence into one sequence in Java


Suppose you have M number of List/Array/Sequence  and each one is sorted with total of N number of elements. So  best optimal way to solve it with the the complexity O(NlogM) time using a heap.

Minimum of each sequence can form a heap with the O(logM) time to insert elements in the heap and O(1) time to delete an element.

Each element would take O(logM) time to insert in the heap and with the total number of elements N, it gives an O(NlogM) time solution. 


In Java 1.5 onwards  PriorityQueue/PriorityBlockingQueue are being introduced to cater as priority heap.


We are really thankful to Joshua Bloch, father of Java Collection Framework, to enlighten with the real world of programming in Java. 


Following are the description available in the Oracle Docs Java 1.5 : 



An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used. A priority queue does not permit null elements. A priority queue relying on natural ordering also does not permit insertion of non-comparable objects (doing so may result in ClassCastException).

The head of this queue is the least element with respect to the specified ordering. If multiple elements are tied for least value, the head is one of those elements -- ties are broken arbitrarily. The queue retrieval operations poll,remove, peek, and element access the element at the head of the queue.

A priority queue is unbounded, but has an internal capacity governing the size of an array used to store the elements on the queue. It is always at least as large as the queue size. As elements are added to a priority queue, its capacity grows automatically. The details of the growth policy are not specified.

This class and its iterator implement all of the optional methods of           the Collection and Iterator interfaces. The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).


Note that this implementation is not synchronized. Multiple threads should not access a PriorityQueue instance concurrently if any of the threads modifies the queue. Instead, use the thread-safe PriorityBlockingQueueclass.
Implementation note: this implementation provides O(log(n)) time for the enqueing and dequeing methods (offer, poll, remove() and add); linear time for the remove(Object) and contains(Object) methods; and constant time for the retrieval methods (peek, element, and size).

This class is a member of the Java Collections Framework.

Lets see some example to elaborate the solution : 


/**
 * @author sachin srivastava
 * tek9g.blogspot.com
 *
 */
public class MergingSortedSequence {
public static void main(String[] args) {
int[] arr1  = {1,3,6,4,8,90,133};
int[] arr2  = {2,3,1,17,18};
int[] arr3  = {4,5,6,8,11};
int[] arr4  = {125,9,10,13,34};
int[] arr = new int[arr1.length + arr2.length + arr3.length + arr4.length];
PriorityQueue<Integer> prq = new PriorityQueue<>();
for (int i = 0; i < arr.length; i++) {
if(i<arr1.length){
prq.add(arr1[i]);
}
if(i<arr2.length){
prq.add(arr2[i]);
}
if(i<arr3.length){
prq.add(arr3[i]);
}
if(i<arr4.length){
prq.add(arr4[i]);
}
}
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}
}
}

Output : 1 1 2 3 3 4 4 5 6 6 8 8 9 10 11 13 17 18 34 90 125 133 


Output is sorted in the ascending order  using Min heap .


Point here is if we don't have the M sorted sequence even then using the PriorityQueue , we can have a sorted collection .


Let see the example using the Random number generation : 



public static void main(String[] args) {
/**
 * @author sachin srivastava
 * tek9g.blogspot.com
 *
 */
PriorityQueue<Integer> prq = new PriorityQueue<>();
Random random = new Random();
for (int i = 0; i < 20; i++) {
int rand = random.nextInt(20);
System.out.print(rand +" ");
prq.add(rand);

}
System.out.println("\n------\n");
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}

}
  
Output : 

Random generated sequence : 



8 11 18 14 6 5 10 19 7 3 3 17 14 10 18 8 17 5 5 9 
------
Sorted merged sequence : 


3 3 5 5 5 6 7 8 8 9 10 10 11 14 14 17 17 18 18 19 


If you are working in a multithreaded  environment then these thread should not have concurrent access to the PriorityQueue and if any of the thread is modifying the queue then to make it thread safe , we need to use PriorityBlockingQueue instead of PriorityQueue which has been designed to cater the concurrent modification problem.

In the above mentioned scenarios  Min heap PriorityQueue is implemented which is by default the implementation of the queue.

If we want to create Max heap using the PriorityQueue then we need to pass the comparator to it and then output will be in the descending order. 

Consider the above random number problem : 

public static void main(String[] args) {
/**
 * @author sachin srivastava
 * tek9g.blogspot.com
 *
 */
//Max heap by passing a comparator
PriorityQueue<Integer> prq = new PriorityQueue<>((x,y)-> y-x);
Random random = new Random();
for (int i = 0; i < 20; i++) {
int rand = random.nextInt(20);
System.out.print(rand +" ");
prq.add(rand);

}
System.out.println("\n------\n");
while (!prq.isEmpty()) {
System.out.print(prq.poll()+" ");
}

}
  
Output : 

Random generated sequence : 



17 0 4 12 9 11 5 12 12 12 3 18 19 9 9 17 8 19 1 14  
------
Sorted merged sequence using the max heap in the descending order : 



19 19 18 17 17 14 12 12 12 12 11 9 9 9 8 5 4 3 1 0  


Enjoy the beautiful world of Java and coding !!!!!!

Saturday, 13 May 2017

Choosing MongoDB - an awesome NoSQL database!!!!





MongoDB, a NoSQL database, is leading the market with many commendable features to its credit. These include exemplary features of MongoDB such as JSON or BSON Data Storage, Power Performance, and Horizontal Scaling. These features come together to create the most powerful database that can monitor, manage, and process huge volume of data in a rather systematic way.     

Lets see first of all NoSQL databases popularity trend which is as shown in the following chart :        

                                                                                  


From the above chart , MongoDB  clearly a winner in terms of popularity and its rank among top 5 DBMS  of the world and have DB-Engine score more than 300 which is an outstanding score for a DBMS.


MongoDB as compared to traditional RDBMS have some very unique features which are vital in the web applications development and its growth is many fold day by day and its user base is getting strong with the strong community of user . Making it a fastest growing NoSQL DB for the development world. 

Best MongoDB features are:

Pros : 
  • Schema less or Dynamic schemas which makes it very flexible and highly helpful in solution of highly complex problem. 
  • Structure of a single object is clear
  • No complex joins
  • Deep query-ability
  • Easy tuning.
  • Ease of scale-out.
  • Conversion / mapping of application objects to database objects not needed.
  • Uses internal memory for storing the (windowed) working set, enabling faster access of data.
  • Document Oriented and NoSQL database.
  • Supports Aggregation
  • Uses JSON like  BSON format which is binary JSON
  • Sharding (Helps in Horizontal Scalability)
  • Supports Ad Hoc Queries
  • Indexing (Any field in MongoDB can be indexed)
  • MongoDB Replica Set (Provides high availability)
  • Supports Multiple Storage Engines
  • Capped Collection
  • High Availability
  • Load Balancing
  • Easy Scalability
  • Powerful Security
  • Automatic Fail-over
  • Advanced User Management
  • Powerful query engine
  • Geospatial support with the geospatial indexing capability - very useful feature for those product which uses geo location to build their logic . Many application can be made using this feature.
  • High Performance
  • Can store big files without changing your data structure - GridFS is main core for managing files and wonderfully handle the big size files.
  • Has Text search integrated facility also helpful is searching 
  • Map Reduce - One of the key feature increasing the capability of processing of large volumes data set into aggregated result set. 
  • Master Slave Replication  - In case of any failure of Master  Slave becomes the Master and Master becomes Slave. So a great fail over support in it.
  • Data Center Awareness - MongoDB provides a number of features that allow application developers and database administrators to customize the behaviors of a sharded cluster or replica set deployment so that MongoDB may be more  "data center aware" or allow operational  and location-based separation.
  • Replica Sets Distributed Across Two or More Data Centers 
  • Easy Deployment 
  • Simple to maintain and not necessary to have DBA for it.
  • Very useful in the case where  high write load is more 

Cons :

  • A downside of NoSQL is that most solutions are not as strongly ACID-compliant (Atomic, Consistency, Isolation, Durability) as the more well-established RDBMS systems.
  • Complex transaction
  • No function or stored procedure exists where you can bind the logic

Who are using MongoDB : 

Currently more than 4500 customers() are using mongo  and some of them are : 

Expedia , MetLife , Cisco, Facebook , Adobe, IBM, SAP, Twitter , Forbes , BusinessInsider and many more big names of the world.

One can see through the complete list of users link 

Good For:

  • E-commerce product catalog.
  • Blogs and content management.
  • Real-time analytics and high-speed logging, caching, and high scalability.
  • Configuration management.
  • Maintaining location-based data — Geospatial data.
  • Mobile and social networking sites.
  • Evolving data requirements.
  • Loosely coupled objectives — the design may change by over time.

Not so Good For:

  • Highly transactional systems or where the data model is designed up front.
  • Tightly coupled systems
  • Multi-Object Transactions: MongoDB only supports ACID transactions for a single document.
  • SQL: SQL is well-known and a lot of people know how to write very complex queries to do lots of things. This knowledge is transferrable across a lot of implementations where MongoDB's queries language are specific to it.
  • Strong ACID guarantees: MongoDB allows for things like inconsistent reads which is fine in some applications, but not in all.
  • Traditional BI: A lot of very powerful tools exist that allow for OLAP and other strong BI applications and those run against traditional SQL database.

Enjoy the Mongo!!!!

Wednesday, 10 May 2017

Compressing a String - An Amazon Problem



Problem Statement : 
Compress a given string "aabbbccc" to "a2b3c3" constraint: inplace compression, no extra space to be used  assumption : output size will not exceed input size.. ex input:"abb" -> "a1b2" buffer overflow.. such inputs will not be given.
Solution : 
Since no extra is to be use hence we can't use recursion in this case . we need to operate on array to make the operation in place . lets see a simple solution to this problem though many ways of doing it possible so one of them I am mentioning here : 
public  static String compressString(String input){
/*
* @sachin srivastava
* tek9g.blogspot.com
* */
StringBuilder sb = new StringBuilder();
if(input == null || input.isEmpty()){
return null;
} else if(input.length() <= 2){
return input;
}
char[] ch = input.toCharArray();
int lenght = ch.length;
int count = 1;
for (int i = 0; i <=lenght-1; i++) {
if(i!=lenght-1 && ch[i] == ch[i+1] ){
count++;
} else {
sb.append(ch[i] + "" +count);
count = 1;
}
}
if(input.length() < sb.toString().length()){
System.out.println("invalid input buffer overflow");
}
return sb.toString();
}

Input1 : aaaaaaaabbcccccccgggggggaaaaaaaeeeeeef

Output1 : a8b2c7g7a7e6f1
Input2 :  abb
Output : invalid input buffer overflow

a1b2

Input3 : abbrrrrtttttgggaaawwww

Output3 : a1b2r4t5g3a3w4

Time Complexity : O(n)
Space Complexity : O(1)  -- in place 

Enjoy coding !!!!


Saturday, 6 May 2017

Finding distinct field data and its count in the MongoDB



MongoDB  is very interesting NoSQL DB  supporting schema less structure  and allow all type of data structures to be saved in BSON (Binary  JSON) format  which is becoming boon for the programming community .  It serves  mind boggling speed in terms of searching  and help to product to scale at a very high level. Its Master Slave replication and load sharding  features makes it an awesome NoSql database  , very useful in the web development industry.

Mongo shell has many collections methods  and support following methods :

-----------------------------------
db.collection.aggregate()
db.collection.bulkWrite()
db.collection.count()
db.collection.copyTo()
db.collection.createIndex()
db.collection.dataSize()
db.collection.deleteOne()
db.collection.deleteMany()
db.collection.distinct()
db.collection.drop()
db.collection.dropIndex()
db.collection.dropIndexes()
db.collection.ensureIndex()
db.collection.explain()
db.collection.find()
db.collection.findAndModify()
db.collection.findOne()
db.collection.findOneAndDelete()
db.collection.findOneAndReplace()
db.collection.findOneAndUpdate()
db.collection.getIndexes()
db.collection.getShardDistribution()
db.collection.getShardVersion()
db.collection.group()
db.collection.insert()
db.collection.insertOne()
db.collection.insertMany()
db.collection.isCapped()
db.collection.latencyStats()
db.collection.mapReduce()
db.collection.reIndex()
db.collection.replaceOne()
db.collection.remove()
db.collection.renameCollection()
db.collection.save()
db.collection.stats()
db.collection.storageSize()
db.collection.totalSize()
db.collection.totalIndexSize()
db.collection.update()
db.collection.updateOne()
db.collection.updateMany()
db.collection.validate()
-----------------------------------------------


One of the very interesting and frequently used collection method  which is widely useful  is

db.collection.distinct() method. How its work lets see  that :

Suppose you have a product collection having 4 documents as follow :

{ 
    "_id" : NumberInt(1), 
    "account" : "abc", 
    "vendor" : "amazon", 
    "category" : "mobile"
}
{ 
    "_id" : NumberInt(2), 
    "account" : "abc", 
    "vendor" : "overstock", 
    "category" : "mobile"
}
{ 
    "_id" : NumberInt(3), 
    "account" : "xyz", 
    "vendor" : "fashionStreet", 
    "category" : "fashion"
}
{ 
    "_id" : NumberInt(4), 
    "account" : "pqr", 
    "vendor" : "foodTruck", 
    "category" : "food"

}

On executing    db.product.distinct("category") gives output an array of the category object as 

[ "mobile", "fashion", "food" ]

If you want to find the total of distinct  elements count  , you need to execute the following command : 

db.product.distinct("category").length

output : 3 

> db.product.distinct("vendor");
output : [ "amazon", "overstock", "fashionStreet", "foodTruck" ]

> db.product.distinct("vendor").length;

output : 4


There is another way of finding the distinct elements using Aggregation framework which is yet another brilliant feature of MongoDB  , see the following examples to have a glimpse of it .



> db.product.aggregate([{$group: {_id : "$category" } }])
{ "_id" : "food" }
{ "_id" : "fashion" }
{ "_id" : "mobile" }

Using group operator  , collection is grouped in distinct elements , if you notice distinct() & $group both are giving same output. This is a beauty of aggregation .


If you want each distinct category along with the its count use : 

> db.product.aggregate([{$group: {_id : "$category" , count : {$sum : 1}} }])
{ "_id" : "food", "count" : 1 }
{ "_id" : "fashion", "count" : 1 }
{ "_id" : "mobile", "count" : 2 }

If you want categories to  be in descending order  along with their counts  use as : 

> db.product.aggregate([{$group: {_id : "$category" , count : {$sum : 1}} } , {$sort : {count : -1}}])
{ "_id" : "mobile", "count" : 2 }
{ "_id" : "food", "count" : 1 }
{ "_id" : "fashion", "count" : 1 }

So how did it work :  

1. Using $group operator  category column is grouped in distinct category elements 

2. $sum operator count the total number of elements belonging to each categories

3. using $sort data pipelines  output of above 1 & 2 is sorted on the descending order  on the count field.


Hopefully above details are helpful in understanding the collection methods of mongo shell and also help in reaching one step ahead in the aggregation framework.


Enjoy Mongo  ...its awesome !!!!!!!




    Thursday, 24 November 2016

    Printing characters with their count in a String

    Total number of Character in ASCII table is 256 (0 to 255). 0 to 31(total 32 character ) is called as ASCII control characters (character code 0-31). 32 to 127 character is called as ASCII printable characters (character code 32-127). 128 to 255 is called as The extended ASCII codes (character code 128-255)

    There are multiple solution available with O(n) time and space complexity using Set,Map , O(n2) using Brute force iterating each character element of a String.

    Solution 1 : 

    But I am representing a solution with O(n) time complexity and In place O(1) space complexity as follow : 



    /**
    
    
     * @author sachin
     *
     */
    public class CountDuplicates {
    public static void charsCount(String str){
    int[] intArr = new int[256];
    char[] charArrInput =  str.toCharArray();
    int charLength = charArrInput.length;
    for (int i = 0; i < charLength; i++) {
    intArr[charArrInput[i]]++;
    }
    int j =0;
    for (int c : intArr) {
    if(c > 0){
    System.out.println( "char=" + (char)j + " and count=" + c );
    }
    j++;
    }
    }
    public static void main(String[] args) {
    String a = "My Name Is Sachin Srivastava and I am a Java Architect passionate "
    + "about writing,blogging & coding , author of tek9g.blogspot.com and vedology.blogspot.com";
    charsCount(a);
    }
    }
    
    
    Output :
    
    
    
    char=  and count=21
    char=& and count=1
    char=, and count=2
    char=. and count=4
    char=9 and count=1
    char=A and count=1
    char=I and count=2
    char=J and count=1
    char=M and count=1
    char=N and count=1
    char=S and count=2
    char=a and count=15
    char=b and count=4
    char=c and count=6
    char=d and count=4
    char=e and count=5
    char=f and count=1
    char=g and count=9
    char=h and count=3
    char=i and count=8
    char=k and count=1
    char=l and count=4
    char=m and count=4
    char=n and count=7
    char=o and count=14
    char=p and count=3
    char=r and count=4
    char=s and count=6
    char=t and count=10
    char=u and count=2
    char=v and count=4
    char=w and count=1
    char=y and count=2


    Solution 2 :

    Using a HashMap : O(n) time and space complexity


           
    
    Map<Character, Integer> map = new HashMap<>();
    char[] charArrInput =  str.toCharArray();
    for (char c : charArrInput) {
    if(!map.containsKey(c)){
    map.put(c, 1);
    } else {
    map.put(c, map.get(c)+1);
    }
    }
    for (Entry<Character, Integer> entry : map.entrySet()) {
    System.out.println("char=" + entry.getKey() + " and count=" + entry.getValue());
    }
    Output:
    char=A and count=1
    char=I and count=2
    char=J and count=1
    char=M and count=1
    char=N and count=1
    char=S and count=2
    char=  and count=21
    char=a and count=15
    char=b and count=4
    char=c and count=6
    char=d and count=4
    char=e and count=5
    char=& and count=1
    char=f and count=1
    char=g and count=9
    char=h and count=3
    char=i and count=8
    char=k and count=1
    char=, and count=2
    char=l and count=4
    char=m and count=4
    char=n and count=7
    char=. and count=4
    char=o and count=14
    char=p and count=3
    char=r and count=4
    char=s and count=6
    char=t and count=10
    char=u and count=2
    char=v and count=4
    char=w and count=1
    char=y and count=2
    char=9 and count=1


    Solution 3 :   Using brute force in the O(n2)   , basically iterating each  n element and comparing and counting remaining  n-1 element  making it quadratic solution with respect to time.

    Solution 3 is not recommended , Solution 1 is the best solution and if one not able to do like solution1 then Solution 2 would be simple to use.

    Enjoy tek9g  blog and coding !!!!!!!!!

    Sunday, 20 November 2016

    Making PDF Password protected in Java


    There are various libraries available through to which a pdf can protected with password encryption.

    Full maven repository is available here - 

    But as a developer , I am using here itextpdf library and bouncyCastle libraries to make the PDF password protection.

    Following is pom.xml for the dependencies : 

        <dependencies>
               <dependency>
               <groupId>com.itextpdf</groupId>
               <artifactId>itextpdf</artifactId>
              <version>5.2.1</version>
      </dependency>
      <dependency>
           <groupId>org.bouncycastle</groupId>
          <artifactId>bcprov-jdk15on</artifactId>
          <version>1.46</version>
        </dependency>

    </dependencies>


    So most import libraries to use are :

    1 . itextpdf-5.2.1.jar 
    2 . bcprov-jdk15on-1.46.jar 

    Code to implement : 

           
    
    
    /**
     * @author sachin
     *
     */
    public class PdfEncryption {
    public static void main(String[] args) {
    try {
    String outputPdfFile = "/Users/sachin/Desktop/testing.pdf";
    String userPassword = "testing_user";
    String ownerPassword ="testing_owner"; 
    String pdfContent = "This is the demonstration of the pdf password protection";
    Document document = new Document(PageSize.A4);
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(outputPdfFile));
    writer.setEncryption(userPassword.getBytes(), ownerPassword.getBytes(),
    PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
    document.open();
    document.addAuthor("Sachin Srivastava");
    document.addCreator("Sachin Srivastava");
    document.addSubject("Thanks for your support");
    document.addTitle("Please read this");
    HTMLWorker htmlWorker = new HTMLWorker(document);
    htmlWorker.parse(new StringReader(pdfContent));
    document.close();
    writer.close();
    System.out.println("pdf created from content");
    } catch (Exception e) {
    System.out.println("error occured in creating pdf from content");
    }
    }
    }


    Above  code generates a PDF named testing.pdf with the password protection.

    Here PDFWriter setEncryption is used to encrypt the pdf using user password byte
    array as a first parameter, owner password byte array as a second parameter, 3rd
    parameter as the PDF permission(PdfWriter.ALLOW_PRINTING - 2052 ) and 4th is the
    encryption type which is of two type

    ENCRYPTION_AES_128
    ENCRYPTION_AES_256


    So enjoy coding with tek9g tips of encrypting PDF and making it password protected.

    Wednesday, 16 November 2016

    Next higher number with same digits

    Finding a next higher number with the same digits is one of the challenging problem to identify a solution with respect to  time space complexity . Any solution which provides in least time and least space would be suitable for the best fit of the solution.

    There are multiple solution to this problem :

    Solution 1 :

    Simplest solution is to find the all permutations of the digits and sort the numbers and then compare with the given number to find next higher number .

    Time complexity O(n!) for the solution and not at all suitable for practical cases.It would be worst solution to this problem.

    Solution 2 :

    Another solution with the O(n) time complexity and O(1) space would be as follow :

           
    
    public static void swap(char[]  charArray, int j , int k){
    char temp = charArray[j];
    charArray[j] = charArray[k];
    charArray[k] = temp;
    }
    public static void nextHigherInteger(Integer input){
    if(input == null || input<=0 ){
    return;
    }
    String s = input.toString();
    char[] charArr = s.toCharArray();
    int charLength = charArr.length;
    int breakPoint = 0;
    for (int i = charLength-1; i > 0; i--) {
    char last = charArr[i];
    char secondLast = charArr[i-1];
    if(secondLast < last ){
    breakPoint = i-1;
    break;
    } 
    }
    if(breakPoint == 0){
    System.out.println("This is the highest number");
    return;
    }
    String first = s.substring(0, breakPoint+1);
    String second = s.substring(breakPoint+1, charLength);
    char[] secondCharArra = second.toCharArray();
    Arrays.sort(secondCharArra);//sorting to the second substring
    StringBuffer sb2 =new StringBuffer();
    sb2.append(first);
    for (char c : secondCharArra) {
    sb2.append(c);
    }          
    char[] charArray = sb2.toString().toCharArray();
    int j = breakPoint;
    int k = ++breakPoint;
    while(true){
    if(charArray[j] < charArray[k]){
    swap(charArray, j, k);
    break;
    } else {
    k++;
    }
    }
    StringBuffer sb3 = new StringBuffer();
    for (char c : charArray) {
    sb3.append(c);
    }  
    System.out.println(sb3.toString());
    }
    public static void main(String[] args) {
    //nextHigherInteger(34722641);//34724126
    //nextHigherInteger(1234675);//1234756
    //nextHigherInteger(23514);//23541
    nextHigherInteger(38276);//38627
    }

    Above mention solution is simple in terms of understanding the logic ,it uses following main points :

    1 .  Traverse from tail till the higher sequence is break means from left to right traverse and check that left digit must be higher than right digit , at any point of its less , its a break/pivot point.

    2. Divide two substring one for left to the break/pivot point and one for the right of the pivot point.

    3. Sort the second string in the ascending order  and compare the first char to rightmost character of first string(x) , if its higher then swap them . If its is less then go for next char of the second string and compare them if its correct then swap it , similarly till the next higher number to  x is found. 

    4. Merge first and second string  and your required number would this string.

    Time complexity  : O(n) and space O(1) 
    Sorting Method : Merge sort of Default Java