Saturday 25 October 2014

Data Structure and Algorithm - Find the largest Palindrome in String

1. Problem Description

"Write a function which gives the length of the largest palindrome found within a string."

2. Solution
This solution provides algorithm complexity of O(N) and space complexity of O(1). The idea is to go through the string and compare the current character with its previous one and the one before the last. If they are equal, then set the flag that a palindrome is to start and set the a temporary index points to either the previous one or the one before the last. Then increment current index and decrement the temporary index if the characters that they are pointing to are equal. If not, then clear the flag and increment the current pointer only until a new palindrome is found or reaches the end of the string.

Pseudo-code
    1. If the string is empty, then return -1.
    2. If the string has only one character, then return 1.
    4. If the string has two characters,
        return 2, if two characters are equal,
        return 1, if they are not
    5. Assign tempIndex = 0; curIndex = 1; foundPalindrome = false and palindromeLength = 1
    6. If str[curIndex] is equal to str[curIndex - 1], then set tempIndex = curIndex -1 and foundPalindrome = true. Increment curIndex until str[curIndex] is equal to str[tempIndex] and str[curIndex + 1] is not euqal to str[tempIndex], Go to Step 8,
    7. If str[curIndex] is equal to str[curInex - 2] (only if curIndex - 2 is valid index), then set tempIndex = curIndex - 2 and foundPalindrome = true. 
    8. Increment curIndex anyway, If str[curIndex]  is euqal to str[tempIndex - 1] (only if tempIndex -1 is a valid Index), decrement tempIndex.
    9. Repeat Step 8 until
        9. 1 curIndex reaches the end of str: then save the result if (curIndex - tempIndex) > palindromeLength and return.
        9.2 tempIndex - 1 reaches beyond the start of str or str[curIndex] != str[tempIndex - 1]:  then clear foundPalindrome and save the result if (curIndex - tempIndex) > palindromeLength. Then go to Step 6.

Corner cases:
Empty string: no palindrome found
One character string: regarded as a palindrome with only one character

Therefore any non-empty string will return a length >= 1. For instance a string is composed of all different characters will return 1.

Explanation on Step 6:
Initially I was not doing this - "Increment curIndex until str[curIndex] is equal to str[tempIndex] and str[curIndex + 1] is not euqal to str[tempIndex],", but simply go to Step 8 directly.

It turns out that not doing this hides a bug when working on a string like "AAAAAAAAA". It returns 8 rather than 9. Because Step 6 is done before Step 7.  

Complexity analysis:
4 temporary variables are used, therefore the space complexity is O(1). And the largest palindrome can be found with one traversing the string, hence the algorithm complexity is O(N).

3. C++ Implementation
// Implementation
// This implementation returns more than just the length of the largest palindrome.
// It returns the start position and the length of the first largest palindrome, if it has
// more than one candidates.
// ********************************************************************************
#include <string>

struct PalindromeInString
{
    int pos;    // start position in string
    int len;    // length of palindrome
};

PalindromeInString FindLargestPalindromeInString(const std::string& str)
{
    if (str.empty()) {
        return PalindromeInString{ -1, -1 };
    }
    
    if (str.length() == 1) {
        return PalindromeInString{ 0, 1 };
    }

    if (str.length() == 2) {
        if (str[0] == str[1]) {
            return PalindromeInString{ 0, 2 };
        }
        else {
            return PalindromeInString{ 0, 1 };
        }
    }

    PalindromeInString result = { 0, 1 };
    bool found = false;
    size_t tempIndex;
    size_t curIndex;
    for (tempIndex = 0, curIndex = 1; curIndex < str.length(); ++curIndex) {
        if (!found) {
            if (str[curIndex] == str[curIndex - 1]) {
                // Step 6
                found = true;
                tempIndex = curIndex - 1;
                while ((curIndex + 1) < str.length()) {
                    if (str[curIndex + 1] != str[tempIndex]) {
                        break;
                    }
                    else {
                        ++curIndex;
                    }
                }
            }
            else if (curIndex > 1 && str[curIndex] == str[curIndex - 2]) {
                // Step 7
                found = true;
                tempIndex = curIndex - 2;
            }
            else {
                continue;
            }
        }
        else {
            // Step 9
            if (tempIndex > 0 && str[curIndex] == str[tempIndex - 1]) {
                --tempIndex;
            }
            else {
                found = false;
                // save the palindrome with max length found so far
                if (result.len < (curIndex - tempIndex)) {
                    result = { tempIndex, curIndex - tempIndex };
                }
            }
        }
    }

    if (found && result.len < (curIndex - tempIndex)) {
        result = { tempIndex, curIndex - tempIndex };
    }

    return result;
}

// ********************************************************************************
// Test
// ********************************************************************************
#include <cassert>

void TestCornerCases()
{
    PalindromeInString result = FindLargestPalindromeInString("");
    assert(result.pos == -1 && result.len == -1);

    result = FindLargestPalindromeInString("A");
    assert(result.pos == 0 && result.len == 1);

    result = FindLargestPalindromeInString("AA");
    assert(result.pos == 0 && result.len == 2);

    result = FindLargestPalindromeInString("AB");
    assert(result.pos == 0 && result.len == 1);
}

void TestCase1()
{
    PalindromeInString result = FindLargestPalindromeInString("123ABCDEFGGFEDCBA123");
    assert(result.pos == 3 && result.len == 14);

    result = FindLargestPalindromeInString("123ABCDEFGFEDCBA123");
    assert(result.pos == 3 && result.len == 13);
}

void TestCase2()
{
    PalindromeInString result = FindLargestPalindromeInString("123XYZZYXABCDEFGGFEDCBA123");
    assert(result.pos == 9 && result.len == 14);

    result = FindLargestPalindromeInString("123XYZYXABCDEFGFEDCBA123");
    assert(result.pos == 8 && result.len == 13);
}

void TestCase3()
{
    PalindromeInString result = FindLargestPalindromeInString("123AAAAAAAAAAAA123");
    assert(result.pos == 3 && result.len == 12);

    result = FindLargestPalindromeInString("123AAAAAAAAAAA123");
    assert(result.pos == 3 && result.len == 11);
}

void TestCase4()
{
    PalindromeInString result = FindLargestPalindromeInString("AAA");
    assert(result.pos == 0 && result.len == 3);

    result = FindLargestPalindromeInString("AAAAAAAAAA");
    assert(result.pos == 0 && result.len == 10);

    result = FindLargestPalindromeInString("AAAAAAAAAAA");
    assert(result.pos == 0 && result.len == 11);
}

void TestCase5()
{
    PalindromeInString result = FindLargestPalindromeInString("ABACCDCCAEFBFEACCD");
    assert(result.pos == 5 && result.len == 13);

    result = FindLargestPalindromeInString("abac");
}
// ********************************************************************************

Saturday 18 October 2014

Data Structure and Algorithm - Linked List: Palindrome

1. Problem Description
This is an Amazon Interview Question for Software Engineer/Developers from careercup.

"Implement bool isPalindrome(SingleLinkList *node) in constant Space. "

2. Solution
This solution has O(N) algorithm complexity and O(1) space complexity. The idea is to divide the linked list into two halves. Reverse the second half and compare two halves if they match. If yes, then the list is a palindrome and otherwise not. Afterwards reverse the second half again and restore to the original linked list.

Pseudo-code:
    1. Divide the linked list into two parts, as introduced in Section 3 of Linked List: Circle Detection. (1x pointer and 2x pointer, finally the first half will have either the same amount nodes as the second half or have one more.)
    2. Reverse the second half
    3. Compare the first half and the second half with the length of the second, because the first half may have one more element.
    4. Reverse the second half again and restore to the original linked list
    5. return the result of the comparison of Step 3

Complexity analysis:
The division and reverse need no or a couple/few temporary node pointer, based on the implementation of Linked List: Circle Detection and Linked List: Common API. The comparison of two linked list will be implemented in this solution and it does not need any extra space. Sot the space complexity is guaranteed to be O(1).
For the algorithm complexity, the division need to go through half of the linked list via 2x pointer, N/2. The reverse of the second half is done twice, N. And the comparison needs to go through the whole of the second list, N/2. In total N/2 + N + N/2 = 2*N, so it is O(N).

3. C++ Implementation
// Implementation
// ********************************************************************************
// LinkedListPalindromeDetector.h
#ifndef LINKED_LIST_PALINDROME_DETECTOR_H
#define LINKED_LIST_PALINDROME_DETECTOR_H

#pragma once

#include "LinkedListAlgo.h"
#include "LinkedListElement.h"


class LinkedListPalindromeDetector
{
public:
    LinkedListPalindromeDetector() = default;
    ~LinkedListPalindromeDetector() = default;
    LinkedListPalindromeDetector(
                            const LinkedListPalindromeDetector& other) = delete;
    LinkedListPalindromeDetector(
                            const LinkedListPalindromeDetector&& other) = delete;
    LinkedListPalindromeDetector& operator=(
                            const LinkedListPalindromeDetector& rhs) = delete;
    LinkedListPalindromeDetector& operator=(
                            const LinkedListPalindromeDetector&& rhs) = delete;

    template<typename T>
    static bool IsPalindrome(LinkedListElement<T>* head)
    {
        if (head == nullptr) {
            return false;
        }

        LinkedListElement<T>* slow = head;
        LinkedListElement<T>* fast2x = head->next;

        if (fast2x == nullptr) {
            return true;
        }

        while (fast2x != nullptr) {
            if (fast2x->next != nullptr) {
                fast2x = fast2x->next->next;
                slow = slow->next;
            }
            else {
                break;
            }
        }

        // split the LinkedList
        LinkedListElement<T>* firstHalf = head;
        LinkedListElement<T>* secondHalf = slow->next;
        slow->next = nullptr;

        // reverse the second half and compare with the first half
        LL_Reverse(&secondHalf);
        // firstHalf shoud have either the amount of elments as secondHalf
        // or have one more element.
        bool isPalindrome = LL_StartWith(firstHalf, secondHalf);

        // recover to the original LinkedList
        LL_Reverse(&secondHalf);
        slow->next = secondHalf;

        return isPalindrome;
    }
};

#endif

// Two extra functions are added in LinkedListAlgo.h
// See more about this on Linked List: Common API
/*
 * Refer to std::string compare
 * Return 0: =
 *        1: >
 *       -1: <
 */
template<typename T>
int LL_Compare(LinkedListElement<T>* lhs, LinkedListElement<T>* rhs)
{
    if (lhs == nullptr && rhs == nullptr) {
        return true;
    }

    while (lhs != nullptr) {
        if (rhs == nullptr) {
            // lhs has more elements
            return 1;
        }

        if (lhs->data > rhs->data) {
            return 1;
        }
        else if (lhs->data < rhs->data) {
            return -1;
        }

        // if the same, compare the next element
        lhs = lhs->next;
        rhs = rhs->next;
    }

    if (rhs == nullptr) {
        // rhs has the same amount elements as lhs
        // and so fare they are all equal
        return 0;
    }

    // rhs has more elements
    return -1;
}

template<typename T>
bool LL_StartWith(LinkedListElement<T>* source, LinkedListElement<T>* pattern)
{
    if (source == nullptr && pattern == nullptr) {
        return true;
    }

    while (source != nullptr) {
        if (pattern == nullptr) {
            // source has more elements
            return true;
        }

        if (source->data != pattern->data) {
            return false;
        }

        // if the same, compare the next element
        source = source->next;
        pattern = pattern->next;
    }

    // pattern has the same amount elements as source
    // and so fare they are all equal, then return true
    // pattern has more elements, return false
    return pattern == nullptr;
}

// ********************************************************************************
// Test
// ********************************************************************************
void TestLinkedListPalindromeDetectorCase1()
{
    LinkedListElement<char>* head = nullptr;

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == false);
}

void TestLinkedListPalindromeDetectorCase2()
{
    LinkedListElement<char>* head = nullptr;
    LL_PushFront(&head, 'A');

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == true);
}

void TestLinkedListPalindromeDetectorCase3()
{
    LinkedListElement<char>* head = nullptr;
    LL_PushFront(&head, 'A');
    LL_PushFront(&head, 'A');

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == true);
}

void TestLinkedListPalindromeDetectorCase4()
{
    LinkedListElement<char>* head = nullptr;
    LL_PushFront(&head, 'A');
    LL_PushFront(&head, 'B');

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == false);
}

void TestLinkedListPalindromeDetectorCase5()
{
    LinkedListElement<char>* head = nullptr;
    LL_PushFront(&head, 'A');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'E');
    LL_PushFront(&head, 'E');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'A');

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == true);
}

void TestLinkedListPalindromeDetectorCase6()
{
    LinkedListElement<char>* head = nullptr;
    LL_PushFront(&head, 'A');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'E');
    LL_PushFront(&head, 'F');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'A');

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == false);
}

void TestLinkedListPalindromeDetectorCase7()
{
    LinkedListElement<char>* head = nullptr;
    LL_PushFront(&head, 'A');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'E');
    LL_PushFront(&head, 'F');
    LL_PushFront(&head, 'E');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'A');

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == true);
}

void TestLinkedListPalindromeDetectorCase8()
{
    LinkedListElement<char>* head = nullptr;
    LL_PushFront(&head, 'A');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'E');
    LL_PushFront(&head, 'F');
    LL_PushFront(&head, 'G');
    LL_PushFront(&head, 'D');
    LL_PushFront(&head, 'C');
    LL_PushFront(&head, 'B');
    LL_PushFront(&head, 'A');

    assert(LinkedListPalindromeDetector::IsPalindrome(head) == false);
}
//********************************************************************************

Data Structure and Algorithm - Linked List: Order Array into Positive and Negative Numbers Consecutively

1. Motivation

As I responded the thread, some started questioning about the algorithm complexity on memcpy. Argue that memcpy takes algorithm complexity of O(N) and therefore the solution on Data Structure and Algorithm - Order Array into Positive and Negative Numbers Consecutively does not have linear algorithm complexity. My answer to this question is that memcpy has much faster performance than for-loop and usually it is target-dependent because most of CPU architecture support chunk memory relocation. More or less continuous memory shifting is optimized by hardware like SIMD and Intel Vectorisation.

Motivated by this questioning, I started to think about what other data structure will eliminate this chunk memory movement target-dependent performance issue. The linked list comes out as no surprise. As well I intended to expand my collections of linked list problems.

2. C++ Implementation
// Implementation
// ********************************************************************************
// Use some common functions in LinkedListAlgo.h
// See more about this on Linked List: Common API
/*
 * This function is only for signed arithmetic type
 * double, float, long, int, short, char
 */
template<typename T>
void OrderElementsIntoNegativePositiveSeries(LinkedListElement<T>* head)
{
    if (head == nullptr ||
        head->next == nullptr ||
        head->next->next == nullptr){
        return;
    }

    // if first value is negative, then find a positive value next
    bool positiveValToFind = head->data < 0;
    LinkedListElement<T>* outOfOrderNode = head;
    LinkedListElement<T>* curNode = head;
    LinkedListElement<T>* tempNode;

    /* Slightly implementation difference:
     * curNode->next : CurrentPlaceTracker 
     * outOfOrderNode->next : OutOfPlaceTracker 
     * Simply this is simple and does not need two extra pointers
     * to track the two previous nodes of two trackers, as they are
     * needed to swap the position of elements.
     */
     while (curNode->next != nullptr) {
        if ((curNode->next->data > 0 && positiveValToFind) ||
            (curNode->next->data < 0 && !positiveValToFind)) {
            if (outOfOrderNode->next == curNode->next) {
                // Scenario 1
                positiveValToFind = !positiveValToFind;
                outOfOrderNode = outOfOrderNode->next;
                curNode = curNode->next;
            }
            else {
                // Scenario 2
                // No memory shifting. only need to re-arrange
                // the pointers
                tempNode = curNode->next;
                curNode->next = tempNode->next;
                tempNode->next = outOfOrderNode->next;
                outOfOrderNode->next = tempNode;
                outOfOrderNode = tempNode->next;
            }
        }
        else {
            curNode = curNode->next;
        }
    }
}

// A few other functions implemented in LinkedListAlogCpp.h
// Simply to make the tests easier
// LinkedListAlogCpp.h

#ifndef LINKED_LIST_ALGO_CPP_H
#define LINKED_LIST_ALGO_CPPH

#pragma once

#include "LinkedListAlgo.h"

#include <vector>

template<typename T>
void LL_PushFrontFromStdVector(LinkedListElement<T>** head, const std::vector<T>& dataVec)
{
    if (dataVec.empty()) {
        return;
    }

    for (std::vector<T>::const_reverse_iterator cRIter = dataVec.rbegin();
         cRIter != dataVec.rend(); ++cRIter) {
        LL_PushFront(head, *cRIter);
    }
}

template<typename T>
void LL_PushBackFromStdVector(LinkedListElement<T>** head, const std::vector<T>& dataVec)
{
    if (dataVec.empty()) {
        return;
    }

    for (std::vector<T>::const_iterator cIter = dataVec.begin();
        cIter != dataVec.end(); ++cIter) {
        LL_Pushback(head, *cIter);
    }
}

template<typename T>
void LL_CopyDataToStdVector(LinkedListElement<T>* head, std::vector<T>& dataVec)
{
    if (head != nullptr) {
        dataVec.clear();
        dataVec.reserve(LL_GetSize(head));
    }

    LinkedListElement<T>* curNode = head;
    while (curNode != nullptr) {
        dataVec.push_back(curNode->data);
        curNode = curNode->next;
    }
}

#endif

// ********************************************************************************
// Test
// The same test cases as in 
// ********************************************************************************
void TestOrderElementsCornerCase()
{
    {
        std::vector<int> testArr;

        LinkedListElement<int>* head = nullptr;
        LL_PushFrontFromStdVector(&head, testArr);
        OrderElementsIntoNegativePositiveSeries(head);

        std::vector<int> result;
        LL_CopyDataToStdVector(head, result);
        assert(result.empty());
    }

    {
        std::vector<int> testArr = { 1 };

        LinkedListElement<int>* head = nullptr;
        LL_PushFrontFromStdVector(&head, testArr);
        OrderElementsIntoNegativePositiveSeries(head);

        std::vector<int> result;
        LL_CopyDataToStdVector(head, result);
        assert(testArr == result);
    }

    {
        std::vector<int> testArr = { 1, -1 };

        LinkedListElement<int>* head = nullptr;
        LL_PushFrontFromStdVector(&head, testArr);
        OrderElementsIntoNegativePositiveSeries(head);

        std::vector<int> result;
        LL_CopyDataToStdVector(head, result);
        assert(testArr == result);
    }
}

void TestOrderElementsCase1()
{
    std::vector<int> testArr = { 2, -1, -3, -7, -8, 9, 5, -5, -7 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, -8, -5, -7 };

    LinkedListElement<int>* head = nullptr;
    LL_PushFrontFromStdVector(&head, testArr);
    OrderElementsIntoNegativePositiveSeries(head);

    std::vector<int> result1;
    LL_CopyDataToStdVector(head, result1);
    assert(result1 == result);
}

void TestOrderElementsCase2()
{
    std::vector<int> testArr = { 2, 9, 5, 3, 2, 1, -1, -3, -7, -8, -5, -7 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, 3, -8, 2, -5, 1, -7 };

    LinkedListElement<int>* head = nullptr;
    LL_PushFrontFromStdVector(&head, testArr);
    OrderElementsIntoNegativePositiveSeries(head);

    std::vector<int> result1;
    LL_CopyDataToStdVector(head, result1);
    assert(result1 == result);
}

void TestOrderElementsCase3()
{
    std::vector<int> testArr = { 2, -1, -3, -7, -8, -5, -7, 9, 5, 3, 2, 1 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, 3, -8, 2, -5, 1, -7 };

    LinkedListElement<int>* head = nullptr;
    LL_PushFrontFromStdVector(&head, testArr);
    OrderElementsIntoNegativePositiveSeries(head);

    std::vector<int> result1;
    LL_CopyDataToStdVector(head, result1);
    assert(result1 == result);
}

void TestOrderElementsCase4()
{
    std::vector<int> testArr = { 2, -1, -3, -7, 9, 5, 3, 2, 1, -8, -5, -7 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, 3, -8, 2, -5, 1, -7 };

    LinkedListElement<int>* head = nullptr;
    LL_PushFrontFromStdVector(&head, testArr);
    OrderElementsIntoNegativePositiveSeries(head);

    std::vector<int> result1;
    LL_CopyDataToStdVector(head, result1);
    assert(result1 == result);
}

void TestOrderElementsCase5()
{
    std::vector<int> testArr = { -1, -3, -7, 2, 9, 5, 3, 2, 1, -8, -5, -7 };
    const std::vector<int> result = { -1, 2, -3, 9, -7, 5, -8, 3, -5, 2, -7, 1 };

    LinkedListElement<int>* head = nullptr;
    LL_PushFrontFromStdVector(&head, testArr);
    OrderElementsIntoNegativePositiveSeries(head);

    std::vector<int> result1;
    LL_CopyDataToStdVector(head, result1);
    assert(result1 == result);
}

void TestOrderElementsCase6()
{
    std::vector<int> testArr = { -1, -3, -7, -8, -5, -7, 2, 9, 5, 3, 2, 1 };
    const std::vector<int> result = { -1, 2, -3, 9, -7, 5, -8, 3, -5, 2, -7, 1 };

    LinkedListElement<int>* head = nullptr;
    LL_PushFrontFromStdVector(&head, testArr);
    OrderElementsIntoNegativePositiveSeries(head);

    std::vector<int> result1;
    LL_CopyDataToStdVector(head, result1);
    assert(result1 == result);
}
// ********************************************************************************

Sunday 12 October 2014

Data Structure and Algorithm - Order Array into Positive and Negative Numbers Consecutively

1. Problem Description
This is an Amazon Interview Question for Software Engineer/Developer from careercup.

"Given an array of positive and negative numbers(no zeroes),i have to arrange them in such a way that the positive and negative numbers should be arranged consecutively.The number of positive and negative numbers may not be equal i.e. if there is no positive number(or negative) left,then all the remaining negative numbers(or positive) are appended to the end of the array.The order is important i.e.if input array is { 2,-1,-3,-7,-8,9,5,-5,-7},then the output array should be {2,-1,9,-3,5,-7,-8,-5,-7}.The code is done in O(n) without using another array.I came up with a solution in which i chose 0 as pivot element and separate the numbers (using quicksort) but in this case the order is not preserved."

2. Solution
As the interview requested, the solution has computation complexity of O(N) and space complexity of O(1). The idea is to have two trackers and one indicator. The two trackers, one is to track the next to the position that is in the order so far, and the other is track the current value to explore. Call the two trackers "OutOfPlaceTracker" and "CurrentPlaceTracker". The indicator is to indicate what value is to find, negative or positive, or what value is needed in the position of OutOfPlaceTracker. Call this indicate as "IsPostiveValueToFind".

When the size of the array is less than 3, then no need any work because all the elements are already in right place. When the array has more than 2 elements, then there are  two scenarios in this cease.

Scenarios 1: both trackers points to the same position
This scenario is always the starting point, because the first element is always in the right place. Both trackers are pointing to the second elements. Set the indicator "IsPositiveValueToFind", true/false, if the first element is negative/positive.
    - If the CurrentPlaceTracker points a value  that the indicator wants, then both trackers moves one step ahead. Flip the indicator and go into Scenario 1 again.
    - If the CurrentPlaceTracker points a value that the indicator does NOT want, then OutOfPlaceTracker stays still and the CurrentPlaceTracker moves one step ahead. Then go into Scenario 2.

Scenario 2: CurrentPlaceTracker is ahead of OutOfPlaceTracker
This scenario happens when negative/positive values appears in row.
    - CurrentPlaceTracker moves ahead and OutOfPlaceTracker stays still until CurrentPlaceTracker points to a value that the indicator likes.
    - Save the element that CurrentPlaceTracker points to into a temporary variable. Shift the memory from position [OutOfPlaceTracker, CurrentPlaceTracker - 1] to [OutOfPlaceTracker + 1,  CurrentPlaceTracker] in the right direction by one step.
    - Save the temporary variable into where OutOfPlaceTracker points to
    - OutOfPlaceTracker moves ahead 2 steps and CurrentPlaceTracker moves ahead 1 step
        - If both trackers point to the same location, go to Scenario 1
        - If CurrentPlaceTracker is ahead, then go to Scenario 2
        - (CurrentPlaceTracker can NOT be behind)

Continue Scenario 1 or Scenario 2 until CurrentPlaceTracker reaches the end of the array.


The above picture shows how the two trackers and indicator update as this solution works on the example shown on an Amazon Interview Question for Software Engineer/Developer from careercup


3. C++ Implementation
// Implementation
//********************************************************************************
#include <vector>

#include <cassert>

template<typename type>
void OrderArrayIntoNegativePositiveSeries(std::vector<type>& arr)
{
    if (arr.empty()){
        return;
    }

    const size_t SizeOfArr = arr.size();
    if (SizeOfArr < 3) {
        return;
    }

    // if first value is negative, then find a positive value next
    bool positiveValToFind = arr[0] < 0;
    type nextValue;
    for (size_t outOfOrderPos = 1, curIndex = 1; curIndex < SizeOfArr; ++curIndex) {
        if ((arr[curIndex] > 0 && positiveValToFind) ||
            (arr[curIndex] < 0 && !positiveValToFind)) {
            if (outOfOrderPos == curIndex) {
                // Scenario 1: curIndex is increment by the for loop
                positiveValToFind = !positiveValToFind;
                ++outOfOrderPos;
            }
            else {
                // Scenario 2: curIndex is increment by the for loop
                nextValue = arr[curIndex];
                memcpy(&arr[outOfOrderPos + 1],
                               &arr[outOfOrderPos],
                               (curIndex - outOfOrderPos) * sizeof(type));
                arr[outOfOrderPos] = nextValue;
                outOfOrderPos += 2;
            }
        }
    }
}
//********************************************************************************
// Test
//********************************************************************************
void TestCornerCases()
{
    std::vector<int> testArr;

    OrderArrayIntoNegativePositiveSeries(testArr);

    assert(testArr.empty());

    testArr = { 1 };
    OrderArrayIntoNegativePositiveSeries(testArr);
    assert(testArr.size() == 1);
    assert(testArr[0] = 1);

    testArr = { 1, -1 };
    OrderArrayIntoNegativePositiveSeries(testArr);
    assert(testArr.size() == 2);
    assert(testArr[0] == 1);
    assert(testArr[1] == -1);
}

void TestCase1()
{
    std::vector<int> testArr = { 2, -1, -3, -7, -8, 9, 5, -5, -7 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, -8, -5, -7 };

    OrderArrayIntoNegativePositiveSeries(testArr);

    assert(testArr == result);
}

void TestCase2()
{
    std::vector<int> testArr = { 2, 9, 5, 3, 2, 1, -1, -3, -7, -8, -5, -7 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, 3, -8, 2, -5, 1, -7 };

    OrderArrayIntoNegativePositiveSeries(testArr);

    assert(testArr == result);
}

void TestCase3()
{
    std::vector<int> testArr = { 2, -1, -3, - 7, -8, -5, -7, 9, 5, 3, 2, 1 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, 3, -8, 2, -5, 1, -7 };

    OrderArrayIntoNegativePositiveSeries(testArr);

    assert(testArr == result);
}

void TestCase4()
{
    std::vector<int> testArr = { 2, -1, -3, - 7, 9, 5, 3, 2, 1, -8, -5, -7 };
    const std::vector<int> result = { 2, -1, 9, -3, 5, -7, 3, -8, 2, -5, 1, -7 };

    OrderArrayIntoNegativePositiveSeries(testArr);

    assert(testArr == result);
}

void TestCase5()
{
    std::vector<int> testArr = { -1, -3, - 7, 2, 9, 5, 3, 2, 1, -8, -5, -7 };
    const std::vector<int> result = { -1, 2, -3, 9, -7, 5, -8, 3, -5, 2, -7, 1};

    OrderArrayIntoNegativePositiveSeries(testArr);

    assert(testArr == result);
}

void TestCase6()
{
    std::vector<int> testArr = { -1, -3, - 7, -8, -5, -7, 2, 9, 5, 3, 2, 1 };
    const std::vector<int> result = { -1, 2, -3, 9, -7, 5, -8, 3, -5, 2, -7, 1 };

    OrderArrayIntoNegativePositiveSeries(testArr);

    assert(testArr == result);
}
//********************************************************************************

Data Structure and Algorithm - Find the Least Sum of Absolute Value of Difference of Each Value from Three Arrays

1. Problem Description
It is an Amazon's interview question for software engineer/developer on careercup.

"Given three arrays A,B,C containing unsorted numbers. Find three numbers a, b, c from each of array A, B, C such that |a-b|, |b-c| and |c-a| are minimum 
Please provide as efficient code as you can. 
Can you better than this ???"

2. Solution
The idea is to combine these 3 arrays into a single array and in its data structure there has to be something to record which array the value comes from originally. Then sort this big array. After sorting, go through each element, together with last two values from different arrays, to calculate the sum of the absolute values. If it is less than the minimum found so far, then update the result. For instance if the current value is from C, then calculate the sum of the absolute values with last value from A and B visited so far. If it is less, then update the result. Otherwise update last C to the current and visit the next.

Here is the pseduo-code
    1. Combine the 3 arrays into one with data structure to indicate which array the value comes from
    2. Sort this big array (of data structure) with the value from A, B and C as key
    3. Assign minAbsSum,  prevA, prevB and prevC as invalid (to track last A, B and C visited so far)
    4. Go through each element in the big array.(Loop the big array)
        4.1 If curVal is from array A, pick curVal, prevB and prevC. Go to 4.4
        4.2 If curVal is from array B, pick curVal, prevA and prevC. Go to 4.4
        4.3 If curVal is from array C, pick curVal, prevA and prevB. Go to 4.4
        4.4 Calculate the sum of the absolute values of difference
              if prevB and prevC are valid in case of 4.1
              if prevA and prevC are valid in case of 4.2
              if prevA and prevB are valid in case of 4.3
        4.5 Update the minAbsSum if absSum < minAbsSum,
        4.6 Return if minAbsSum = 0, otherwise continue

The way to calculate |a - b| + |b - c| + |c - a|
As a, b , c are numbers and we always can have the relationship of smaller, big and bigger among 3. Assuming that a >= b >= c, then |a - b| + |b - c| = |a - c| = |c-a|. This is telling us that no matter what the values of a, b and c, the sum of the absolute values is equal to 2*(max(a, b, c) - min(a, b, c)).

Optimization 1
Suppose a list of sorted values like: a1, a2, b1, c1, b2, c2, ..., ai, ai+1, ai+2, ai+3, bj, ck, ...
Any combinations that has ai+1 and a+2 can be skipped, because it will be always larger than the combinations of (ai, bj-1, ck-1) and (ai+3, bj, ck). Because
    ai+1 >= ai
    For combination of (ai+1, bj-1, ck-1) and (ai, bj-1, ck-1)
    2*(ai+1 - min(bj-1, ck-1)) >= 2*(ai - min(bj-1, ck-1)
As well,
    For combination of (ai+2, bj, ck) and (ai+3, bj, ck)
    ai+2 <= ai+3
    2*(max(bj, ck) - ai+2) >= 2*(max(bj, ck) - ai+3)
Therefore any value with the same type repeating can be ignored for calculation.

Optimization 2
Suppose Array A, B and C has size of L, M, N. And we have a list of sorted value like:
a1, a2, b1, c1, c2, ..., aL, bj, ck, ..., bM, ..., cN. In this case aL, bM and cN is th maximal value of Array A, B and C. Between bj and cK there can be any number of b but no c.
Between aL to cN, we do not need to go through every elements to calculate the sum of absolute values. We only need to calculate two combination at most.
In this case bj is the first value from Array B and ck is the first value of Array C after aL, if any of them exists. Any combination later from them will be larger than (aL, bj, cK). And one more combination needs to evaluated is (cj-1, aL, bj) in this case.
Therefor as long as hit the end of one array, then at most there are two combinations remaining to be evaluated.

Optimization 3
Because the absolute value is always not less than zero. For any combination of (a, b, c), if these three values are equal, then the minimal value has been reached - zero. There is no better combination than this, therefore stop and return the combinations.

3. C++ Implementation

// Implementation
//********************************************************************************
#include <map>
#include <vector>

#include <cassert>
#include <cmath>

struct ResultTuple{
    int val[3];          // the combination of (a, b, c)
    size_t absSum;
};

// Array A, B and C are mapped into CombinedArrayMap
// the value has type of "char" to indicate which array the key
// comes from.
typedef std::multimap<int, char> CombinedArrayMap;
typedef CombinedArrayMap::const_iterator CAMIterator;

void UpdateResult(CAMIterator& abc1,
                  CAMIterator& abc2,
                  CAMIterator& abc3,
                  size_t absSum,
                  ResultTuple& result)
{
    result.absSum = absSum;
    result.val[abc1->second - 'A'] = abc1->first;
    result.val[abc2->second - 'A'] = abc2->first;
    result.val[abc3->second - 'A'] = abc3->first;
}

void CalculateAndUpdateAbsSum(CAMIterator& itEnd,
                              CAMIterator& prev1,
                              CAMIterator& prev2,
                              CAMIterator& curVal,
                              ResultTuple& result)
{
    if (prev1 == itEnd || prev2 == itEnd || curVal == itEnd) {
        return;
    }
    // calculate the sum of the absolute values of difference
    // 2*(max(a, b, c) - min(a, b, c))
    size_t absSum = (prev1->first < prev2->first) ?
        (curVal->first - prev1->first) << 1 :
        (curVal->first - prev2->first) << 1;
    if (absSum < result.absSum) {
        UpdateResult(prev1, prev2, curVal, absSum, result);
    }
}

// Find ck in Optimization 2 in Section 2
void FindNextNotXandY(CAMIterator& itEnd,
                      const char x,
                      const char y,
                      CAMIterator& notXYIter)
{
    for (; notXYIter != itEnd; ++notXYIter) {
        if (notXYIter->second != x &&
            notXYIter->second != y) {
            break;
        }
    }
}

// Find bj in Optimization 2 in Section 2
void FindNextNotX(CAMIterator& itEnd,
                  const char x,
                  CAMIterator& notXIter)
{
    for (; notXIter != itEnd; ++notXIter) {
        if (notXIter->second != x) {
            break;
        }
    }
}

// Step 4 in psedo-code
void CalculateAndUpdateAbsSum(CAMIterator& itEnd,
                              CAMIterator& prevA,
                              CAMIterator& prevB,
                              CAMIterator& prevC,
                              CAMIterator& curABC,
                              ResultTuple& result)
{
    switch (curABC->second){
    case 'A':
        CalculateAndUpdateAbsSum(itEnd, prevB, prevC, curABC, result);
        break;
    case 'B':
        CalculateAndUpdateAbsSum(itEnd, prevA, prevC, curABC, result);
        break;
    case 'C':
        CalculateAndUpdateAbsSum(itEnd, prevA, prevB, curABC, result);
        break;
    default:
        assert(false);
    }
}

// Optimization 2 in Section 2
void FindLastTwoCombinationsAndUpdate(CAMIterator& itEnd,
                                      CAMIterator& prev1,
                                      CAMIterator& prev2,
                                      CAMIterator& curIter,
                                      ResultTuple& result)
{
    CAMIterator notXIter = curIter;
    FindNextNotX(itEnd, curIter->second, notXIter);
    if (notXIter != itEnd) {
        if (prev1 != itEnd && prev1->second != notXIter->second) {
            CalculateAndUpdateAbsSum(itEnd, prev1, curIter, notXIter, result);
        }
        if (prev2 != itEnd && prev2->second != notXIter->second) {
            CalculateAndUpdateAbsSum(itEnd, prev2, curIter, notXIter, result);
        }

        CAMIterator notXYIter = notXIter;
        FindNextNotXandY(itEnd, curIter->second,
            notXIter->second, notXYIter);
        CalculateAndUpdateAbsSum(itEnd, curIter, notXIter, notXYIter, result);
    }
}

ResultTuple CalculateLeastAbsSum(const std::vector<int>& aVec,
                                 const std::vector<int>& bVec,
                                 const std::vector<int>& cVec)
{
    CombinedArrayMap valueVecMap;

    for (auto val : aVec) {
        valueVecMap.insert(std::make_pair(val, 'A'));
    }

    for (auto val : bVec) {
        valueVecMap.insert(std::make_pair(val, 'B'));
    }

    for (auto val : cVec) {
        valueVecMap.insert(std::make_pair(val, 'C'));
    }

    CAMIterator itStart = valueVecMap.begin();
    CAMIterator itEnd = valueVecMap.end();
    CAMIterator prevA = itEnd;
    CAMIterator prevB = itEnd;
    CAMIterator prevC = itEnd;
    char prevType = 0;
    size_t SizeOfA = aVec.size();
    size_t SizeOfB = bVec.size();
    size_t SizeOfC = cVec.size();
    size_t visitedA = 0;
    size_t visitedB = 0;
    size_t visitedC = 0;

    ResultTuple result = { { INT_MAX, INT_MAX, INT_MAX }, SIZE_MAX }; // SIZE_MAX?
    for (CAMIterator curIter = itStart; curIter != itEnd; ++curIter) {
        // Optimization 1 in Section 2
        if (prevType != curIter->second) {
            CalculateAndUpdateAbsSum(itEnd, prevA, prevB, prevC, curIter, result);
            // Optimization 3 in Section 2
            if (result.absSum == 0) {
                return result;
            }
        }

        if (curIter->second == 'A') {
            prevA = curIter;
            if (++visitedA == SizeOfA) {
                // Optimization 2 in Section 2
                FindLastTwoCombinationsAndUpdate(itEnd, prevB, prevC,
                                                 curIter, result);
                break;
            }
        }
        else if (curIter->second == 'B') {
            prevB = curIter;
            if (++visitedB == SizeOfB) {
                // Optimization 2 in Section 2
                FindLastTwoCombinationsAndUpdate(itEnd, prevA, prevC,
                                                 curIter, result);
                break;
            }
        }
        else if (curIter->second == 'C') {
            prevC = curIter;
            if (++visitedC == SizeOfC) {
                // Optimization 2 in Section 2
                FindLastTwoCombinationsAndUpdate(itEnd, prevA, prevB,
                                                 curIter, result);
                break;
            }
        }
        else {
            assert(false);
        }
        prevType = curIter->second;
    }

    return result;
}
//********************************************************************************

// Test
//********************************************************************************
void testCase1()
{
    std::vector<int> aVec = { 9, 7, 5, 7, 4, 8, 12, 30, 50 };
    std::vector<int> bVec = { 30, 5, 9, 20, 35, 70, 50, 12 };
    std::vector<int> cVec = { 8, 10, 30, 21, 6, 3, 6, 10, 0 };

    ResultTuple result = CalculateLeastAbsSum(aVec, bVec, cVec);
    assert(result.absSum == 0);
    assert(result.val[0] == 30);
    assert(result.val[1] == 30);
    assert(result.val[2] == 30);
}

void testCase2()
{
    std::vector<int> aVec = { 9, 7, 6, 8, 4, 5, 3, 1, 2 };
    std::vector<int> bVec = { 20, 10, 19, 12, 15, 17, 14, 12 };
    std::vector<int> cVec = { 30, 31, 21, 40, 25, 23, 36, 40, 50 };

    ResultTuple result = CalculateLeastAbsSum(aVec, bVec, cVec);
    assert(result.absSum == 24);
    assert(result.val[0] == 9);
    assert(result.val[1] == 10);
    assert(result.val[2] == 21);
}

void testCase3()
{
    // 3 vectors has 4 and 9, this case should return 4
    std::vector<int> aVec = { 9, 7, 6, 8, 4, 5, 3, 1, 2 };
    std::vector<int> bVec = { 20, 4, 19, 2, 15, 17, 9, 12 };
    std::vector<int> cVec = { 3, 13, 9, 40, 25, 23, 6, 4, 5 };

    ResultTuple result = CalculateLeastAbsSum(aVec, bVec, cVec);
    assert(result.absSum == 0);
    assert(result.val[0] == 4);
    assert(result.val[1] == 4);
    assert(result.val[2] == 4);
}

void testCase4()
{
    // 3 vectors has two sets result
    // (90, 89, 91) and (3, 4, 5)
    // in this case, it should return (3, 4, 5)
    std::vector<int> aVec = { 90, 3, 16, 28, 45, 35, 63, 71, 82 };
    std::vector<int> bVec = { 89, 4, 19, 26, 48, 37, 69, 72, 86 };
    std::vector<int> cVec = { 91, 5, 15, 29, 43, 33, 66, 74, 85 };

    ResultTuple result = CalculateLeastAbsSum(aVec, bVec, cVec);
    assert(result.absSum == 4);
    assert(result.val[0] == 3);
    assert(result.val[1] == 4);
    assert(result.val[2] == 5);
}

void testCase5()
{
    std::vector<int> aVec = { 90, 83, 16, 28, 45, 35, 63, 71, 3 };
    std::vector<int> bVec = { 95, 88, 19, 26, 48, 37, 69, 72, 1 };
    std::vector<int> cVec = { 91, 85, 15, 29, 43, 33, 66, 74, 2 };

    ResultTuple result = CalculateLeastAbsSum(aVec, bVec, cVec);
    assert(result.absSum == 4);
    assert(result.val[0] == 3);
    assert(result.val[1] == 1);
    assert(result.val[2] == 2);
}
//********************************************************************************

Saturday 4 October 2014

C++11 Features - Exception: function-try-block

As currently I am reviewing the code structure on API, modulization and exception across the models, I started to study/review the new techniques of handling exceptions introduced in C++11. Learning/refreshing these techniques is absolutely vital for nowadays C++ software development.

Firstly for most C++ applications encountering exceptions seems inevitable, because some of most fundamental operations are embedded with exceptions, such as std::bad_alloc when allocating memory in heap and std::bad_cast in dynamic casting, not even mentioning Standard Template Library. Hence completely removing C++ exception features and using error code only seems no longer a valid option for most C++ applications.

Secondly utilizing exceptions in C++ is such an easy/convenient option when software application involves user interaction, in order to respond with meaningful and helpful feedback to users. Comparing with error-code approach in multiple software modules, exception approach is more flexible to provide multiple levels of logging/debugging facilities and recover from user errors.

Of course misusing exceptions is error-prone as well especially across the boundary of modules, given the fact that currently C++ exception specification is not very friendly. I found that one occasion is very error prone, most of time causing unnecessary software crash. Introducing new exceptions where its host function is called a lot of places, for instance compiled as static library and used in multiple modules as a par of DLLs or dynamic libraries. Therefore it is not easy job to capture this exception properly in all occasions, especially this exception can be propagated into its caller modules, as this same exception may need variable user feedback/interactions. In a few cases I found that I have to analyze the code path in order to make sure the newly introduced exceptions are caught in all possibilities. 

But this does not prevent the legitimate use of exceptions. In my experience it is vital to combine both exception and error-code approach. Apply error-code approach to internal error and throw exceptions only for user errors. Another good practice to limit the exceptions thrown across the models and provide good documentation at least. As currently C++ exception specification is not very friendly. Use good documentation style and naming convention to remind developers propagating exceptions. (Some good practice about exception please refer to Herb Sutter's book, like exception level and single responsibility)

Here I would like to learn function-try-block together with you. Go through its key points with some code snippets. 

1. Used with constructor
Constructor is one of the special functions in C++. It has global, non-virtual and static semantics because it can be called anyway in the code given the assumption that it is has public accessibility and the header of its declaration is included. What's more it has call hierarchy to follow when the derived class constructor is called (please refer to The order of object initialization/destruction). This call hierarchy is defined by the standard and the compiler has to do the tricks to meet the standard. Therefore there is something in hidden that has to be done by the compiler.

As a matter of fact of this hidden code is out of control of developers what if the hidden-code/call-hierarchy throws exception before reaching the constructor body. With the conventional try-block there is no way to catch it and therefore developers have to write specific code to manage the potential resource leaking.

With the introduction of function-try-block, it can be used with constructor's initialization list, such as base class initialization and member variables initialization. It can catch the exceptions thrown in these code. More importantly it guarantees that all the well-constructed base class object and member variables will be destroyed before hitting the catch-section.

What purpose is function-try-block used for together with constructor? Or what can we achieve if the exception is thrown and caught in the constructor's initialization list. In my personal experience its main purpose servers for the debugging/logging facility and providing user feedback via exception in different levels and across modules, if some critical requirements in constructing objects is violated and triggers the exception. In this blog on drdobbs, it provides another scenario for function-try-block used with copy constructor when the creation constructor is too expensive for the purpose of the code efficiency and performance. It is a valid point if the code design demonstrated in the example is the only choice. (This validity of this example is arguable. In my opinion any creation constructor should not be expensive at the first place. In this blog on drdobbs its object construction should be tailored into two parts. The first part should be exception free in constructor for inexpensive initialization and the second part for the expensive initialization should be implemented as a public function, for such a "Init()" function.)

Base-derived constructors:
All the well-constructed member variables are to be destroyed before hitting the catch-section in the function-try-block in constructor. All the well constructed based classes and their member variables are to be destroyed too before hitting the catch-section in the derived class.

//********************************************************************************
class MyException : public std::exception {
public:
    MyException(const std::string& msg) : m_Msg(msg)
    {}

    virtual ~MyException() {}

    // MSVC12 does not support noexcept yet
    virtual const char* what() const throw() {
        return m_Msg.c_str();
    }

    void AppendMessage(const std::string& msg) {
        m_Msg.append(msg);
    }

protected:
    std::string m_Msg{ "" };
};

class CreationException : public MyException {
public:
    CreationException(const std::string& msg)
        : MyException("CreationException: ")
    {
        m_Msg.append(msg);
    }
};

class DestructionException : public MyException {
public:
    DestructionException(const std::string& msg)
        : MyException("DestructionException: ")
    {
        m_Msg.append(msg);
    }
};

class MyNonEmptyString {
public:
    MyNonEmptyString(const std::string& str)
        : m_Str(str) {
        if (m_Str.empty()) {
            throw CreationException("MyNonEmptyString");
        }
    }

    ~MyNonEmptyString() {
        std::cout << "~MyNonEmptyString()" << std::endl;
    }

private:
    std::string m_Str;
};

class MyString {
public:
    MyString(const std::string& str)
        : m_Str(str) {
    }

    ~MyString() {
        std::cout << "~MyString()" << std::endl;
    }

private:
    std::string m_Str;
};

class Base {
public:
    Base(const std::string& name, const int* val)
        try : m_Name(name), m_ValPtr(val) {
        if (m_ValPtr == nullptr) {
            throw CreationException("Base");
        }
    }
    catch (CreationException& ce){
        std::cout << ce.what() << std::endl;
    }

    virtual ~Base() {
        std::cout << "~Base()" << std::endl;
    }
private:
    MyNonEmptyString m_Name;
    const int* m_ValPtr;
};

class Derived : public Base {
public:
    Derived(const std::string& name, const int* valPtr, const double* data)
        try : Base(name, valPtr), m_Data(data) {
        if (m_Data == nullptr) {
            throw CreationException("Derived");
        }
    }
    catch (CreationException& ce) {
        std::cout << ce.what() << std::endl;
    }

    ~Derived() {
        std::cout << "~Derived()" << std::endl;
    }

private:
    MyString m_Version{ "1.0" };
    const double* m_Data;
};

// test
int _tmain(int argc, _TCHAR* argv[])
{
    try {
        Base b1(std::string(""), nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating Base b1: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating Base b1: " << "unknown" << std::endl;
    }

    try {
        Base b2(std::string("Base"), nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating Base b2: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating Base b2: " << "unknown" << std::endl;
    }

    try {
        Derived d1(std::string(""), nullptr, nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating Derived d1: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating Derived d1: " << "unknown" << std::endl;
    }

    try {
        Derived d2(std::string("Derived"), nullptr, nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating Derived d2: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating Derived d2: " << "unknown" << std::endl;
    }

    try {
        int intBuf[2];
        Derived d3(std::string("Derived"), intBuf, nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating Derived d3: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating Derived d3: " << "unknown" << std::endl;
    }

    return 0;
}
// Output
//********************************************************************************

In the creation of "Derived d1" the creation exception thrown in MyNonEmptyString was caught 3 times in the constructor of Base, Derived and main(). The exception caught in function-try-block in constructor will be automatically re-thrown and the caller function to create the object has to catch the exception. Any logging/debugging information can be closely located in the catch-section together with the constructor. Easy to maintain and read.

In the creation of "Derived d3" before hitting catch-section of Derived constructor the member variables of its base class, its base class and its own member variables are all destroyed. This behavior is exactly what we wanted.

Delegate/target constructors:
I have briefly talked about delegate/target constructor and the motivation behind it. Please refer to C++11 features - Improvement on object construction. Using function-try-block in delegate constructor will guarantee that the well-constructed object and its member variables by target constructor are to be destroyed before hitting the catch-section in the delegate constructor.

//********************************************************************************
class BaseEx {
public:
    // target constructor
    BaseEx(const std::string& name, const int* val)
        : m_Name(name), m_ValPtr(val) {
        if (m_ValPtr == nullptr) {
            throw CreationException("BaseEx");
        }
    }

    // delegate constructor
    BaseEx(const int* val)
        try : BaseEx("BaseEx", val) {

        }
    catch (CreationException& ce) {
        ce.AppendMessage("-Invalid pointer");
        std::cout << ce.what() << std::endl;
    }

    virtual ~BaseEx() {
        std::cout << "~BaseEx()" << std::endl;
    }
private:
    MyNonEmptyString m_Name;
    const int* m_ValPtr;
};

class DerivedEx : public BaseEx {
public:
    DerivedEx(const std::string& name, const int* valPtr, const double* data)
        : BaseEx(name, valPtr), m_Data(data) {
        if (m_Data == nullptr) {
            throw CreationException("DerivedEx");
        }
    }

    ~DerivedEx() {
        std::cout << "~Derived()Ex" << std::endl;
    }

private:
    MyString m_Version{ "1.0" };
    const double* m_Data;
};

// test
int _tmain(int argc, _TCHAR* argv[])
{
    try {
        BaseEx bex1(nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating BaseEx bex1: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating BaseEx bex1: " << "unknown" << std::endl;
    }

    try {
        DerivedEx dex1(std::string(""), nullptr, nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating DerivedEx dex1: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating DerivedEx dex1: " << "unknown" << std::endl;
    }

    try {
        DerivedEx dex2(std::string("DerivedEx"), nullptr, nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating DerivedEx dex2: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating DerivedEx dex2: " << "unknown" << std::endl;
    }

    try {
        int intBuf[2];
        DerivedEx dex3(std::string("DerivedEx"), intBuf, nullptr);
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in creating DerivedEx dex3: "
            << ce.what()
            << std::endl
            << std::endl;
    }
    catch (...) {
        std::cout << "Exception caught in creating DerivedEx dex3: " << "unknown" << std::endl;
    }

    return 0;
}

// output
//********************************************************************************

In the creation "BaseEx bex1" the CreationException thrown in target constructor is caught in delegate constructor. As expected its member variables are destroyed before hitting the catch-section.

Bear in mind that the exception is caught in catch-section of function-try-block used together with constructor/destructor will be automatically re-thrown. And for constructor particularly there cannot be a return statement in function-try-block.

2. Rarely used with destructor
Destructor is another special function in C++. It has global, static and virtual semantics. Its calling hierarchy is the opposite order of the creation constructor. It has its special personality when handling the exception. If an exception caught in destructor, stack-unwinding is triggered. At this time if another exception is thrown during the stack unwinding, normally terminate() will be called and the program is to terminate.

So it is never a good practice to thrown exception in destructor. And function-try-block is not to help this special occasions either. If for some logging/debugging requirement throwing exceptions is a must design requirement, then keep in mind that do not let exception propagate.

//********************************************************************************
class BadInt {
public:
    BadInt(int val) : m_val(val)
    {}

    ~BadInt() {
        throw DestructionException("BadInt");
    }
private:
    int m_val;
};

class BaseFool {
public:
    virtual ~BaseFool() {
        std::cout << "~BaseFool()" << std::endl;
    }
private:
    MyString m_Version{ "1.0" };
};
class Fool1 : public BaseFool {
public:
    ~Fool1() {
        std::cout << "~Fool1()" << std::endl;
    }
public:
    BadInt m_val{ 0 };
    MyNonEmptyString m_ID{ "Fool1" };
};

class Fool2 : public BaseFool{
public:
    ~Fool2() try {
        std::cout << "~Fool2()" << std::endl;
    }
    catch (DestructionException& de) {
        std::cout << "Exception throwin in ~Fool2(): " << de.what() << std::endl;
    }
public:
    BadInt m_val{ 0 };
    MyNonEmptyString m_ID{ "Fool2" };
};

int _tmain(int argc, _TCHAR* argv[])
{
    try {
        Fool1 f;
    }
    catch (DestructionException& de){
        std::cout << "Exception caught: "
            << de.what()
            << std::endl
            << std::endl;
    }

    try {
        Fool2 f;
    }
    catch (DestructionException& de){
        std::cout << "Exception caught: "
            << de.what()
            << std::endl
            << std::endl;
    }
    return 0;
}

// output
//********************************************************************************

In the destruction of "Fool2 f" itself, its member variables, base class, and member variables of base class are all destroyed before hitting the catch-section. As stated in Section 1 the exception caught in function-try-block with destructor will be automatically re-thrown too. Therefore the caller function need to catch this exception.

3. Do not use with normal functions
C++11 standard says that function-try-block can be used for any function. But because normal function does not have the hidden code like constructor and destructor. Therefore anything can be captured by function-try-block can be captured by try-block.

For me both options are valid in terms of their functionality. However I would prefer the try-block for normal function, as it is easier to read and keeps the back compatibility.

4. Do not use with main()
This has been one of most frequently asked questions for function-try-block. In theory as I described in Section 3, the standard does not prevent developers from using function-try-block with main(). However the drive behind this question is that developers are trying to use function-try-block to capture the exceptions thrown from the creation/initialization of global variables or static variables, like global singleton object, under scope or namespace in main() function. Hence some debugging facility can be logged.

Unfortunately the answer is no. One of good explanations of why it is a negative answer, especially on the static variables under scope and namespace, is that the standard does not guarantee that the static variables under scope or namespace initialized in certain order and does not guarantee that they are initialized/created before entering main(), as C++ has lazy initialization idiom.

//********************************************************************************
MyNonEmptyString globalStr("");
namespace MySocpe {
    MyNonEmptyString globalStr("");
    static MyNonEmptyString staticStr("");
}

int _tmain(int argc, _TCHAR* argv[]) try {
    std::cout << "Main()" << std::endl;
    return 0;
}
catch (CreationException& ce){
    std::cout << "Exception caught in global variables: "
              << ce.what()
              << std::endl;
}
//********************************************************************************

This tiny snippet of code will crash before hitting main(). And it will disappoint you if you are expecting something to print out from either MyNonEmptyString or the catch-section of main(), as it is a straightforward crash and nothing to print out.

5. Life time of arguments
The arguments in function-try-block can be accessed both in try-section and catch-section, which is the same as the normal try-block. This poses the difference against the life time of member variables.

6. Life time of member variables
Member variables are only accessible in try-section right before the exception is thrown and they are not accessible in catch-section. This is the right behavior that we want. The standard guarantees that all the well-constructed member variables are destroyed when hitting catch-section. And the base class object and its member variables are destroyed too if the exception is thrown and caught in function-try-block in the derived class.

Again as stated in Section 1 the the object and its member variables will be destroyed as well if the exception is thrown and caught in delegated constructor (the life time of this object starts from a successful returning from the target constructor).

7. Can't catch exceptions thrown by static variables in namespace or scope
Yet again as I briefly mentioned this item in Section 4. Because the standard does not guarantee the order of static variables under scope or namespace. We already know that the memory of global/static variables is allocated in global/static memory section but there is no guarantee that they are initialized/created before entering main(). Either we do not know when exactly it will be firstly initialized/created in our program, because C++ has lazy initialization idiom.

Even though developers can reason out when the first time the object associated/related/used with the static variables is initialized/created (the lazy initialization is fired). And hence can put a function-try-block around it. Still this makes no positive impact or it is nearly not maintainable if later other developers create this object earlier and this function-try-block has to move together with it. It means that every time the reasoning for the first time initialization/creation of the object associated with static variables has to be done before modifying the code. I can't image how this can be achieved.

//********************************************************************************
class Bar {
public:
    Bar() {}

private:
    MyString m_ID{ "Bar" };
    //  Crash at beginning of the programm, no matter
    //  if any insatnce of Bar is created or not.
    static MyNonEmptyString m_NEStr;
};

MyNonEmptyString Bar::m_NEStr{ "" };

int _tmain(int argc, _TCHAR* argv[])
{
    try {
        Bar b;
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in Bar b: " << ce.what() << std::endl;
    }
    return 0;
}
//********************************************************************************

This exception thrown by Bar::m_NEStr can be caught neither by function-try-block, as shown in Section 4, nor by normal try-block as above code snippet.

8 . Can catch exceptions thrown by static variable in function at initialization
As I described in above section, the exception thrown from the initialization/creation of static variables under scope or namespace cannot be caught by function-try-block, because we don't know when exactly the lazy initialization is fired and hence not knowing where to put the function-try-block.

However for static variables in a function  the exception thrown from their initialization/created can be caught by function-try-block, because we know exactly when the lazy initialization is fired - the first time enters the nearest scope of the function.

//********************************************************************************
int Foo() try {
    static MyNonEmptyString localString("");
    //MyNonEmptyString localString("");
    return 2;
}
catch (CreationException& ce) {
    std::cout << "Exception caught in local static variables: "
        << ce.what()
        << std::endl;
}

class Bar {
public:
    Bar()
        try {
        static MyNonEmptyString localStaticStr("");
    }
    catch (CreationException& ce) {
        std::cout << ce.what() << std::endl;
    }

private:
    MyString m_ID{ "Bar" };
};

int _tmain(int argc, _TCHAR* argv[])
{
    Foo();
    try {
        Bar b;
    }
    catch (CreationException& ce) {
        std::cout << "Exception caught in Bar b: " << ce.what() << std::endl;
    }

    return 0;
}

// output:
//********************************************************************************

In this example the exception thrown from the static variable in normal function or constructor can be caught properly.

Summary:
Function-try-block has a valid user case with constructor. It guarantees that all the well-constructed objects at the time  throwing the exceptions will be destroyed before hitting the catch-section. This brings two advantages. One is to guarantee no resource leaking and the second is code cohesion, to take any functionality in catch-section close to the exception thrown.

And it is not a good practice to use function-try-block with any another functions, destructor, main() and normal function.

Bibliography:
[1] C++11 Standard
[2] http://www.stroustrup.com/C++11FAQ.html
[3] http://www.drdobbs.com/cpp/understanding-c-function-try-blocks/240168262