An in-place algorithm for String Transformation in C++



We are given a string and need to move all characters at even positions to the end of the string while maintaining the original order of both even-positioned and odd-positioned characters. The transformation should be done in-place (without using extra space) and in O(n) time.

Let's look at a few example scenarios to understand the problem clearly.

Scenario 1

Input: T1u2t0o6r2i0a0l4s
Output: Tutorials12062014
Explanation:
Odd-positioned characters are T u t o r i a l s.
Even-positioned characters are 1 2 0 6 2 0 1 4.
We place the even-positioned characters at the end while 
keeping their original order.

Scenario 2

Input: 5August2025
Output: Ags225uut05
Explanation:
Odd-positioned characters are A g s 2 2.
Even-positioned characters are 5 u t 0 5.
We place the even-positioned characters at the end while
keeping their original order.

String Transformation in C++

We use the Cycle Leader Iteration Algorithm to move even-positioned characters to the end of the string. The algorithm works by moving each character directly to its correct position in a cycle, without using extra space.

Algorithm

The following are the steps we took to implement this algorithm in our solution:

  • First, we cut out the largest prefix substring of size 3^k + 1, where k is the highest non-negative integer such that 3^k + 1 is less than or equal to the string length.
  • Next, we apply the Cycle Leader Iteration Algorithm to this substring, starting with positions 1, 3, 9, and so on. This rearranges the substring so that odd-positioned characters move to the left half and even-positioned characters move to the right half, while keeping their order.
  • Then, we process the remaining substring by repeating the first two steps until the whole string is transformed. After processing all substrings, we merge them by reversing the second half of the first block and the first half of the next block.
  • Finally, we reverse these two halves together and repeat the process until all blocks are combined into the final transformed string.

C++ Program to Transform a String

Following is a complete C++ program where we implement the above steps to place all the even-positioned index characters after the odd-positioned index characters in a given string:

// C++ application of above approach
#include <bits/stdc++.h>
using namespace std;

// A utility function to swap characters
void swap ( char* a1, char* b1 ) {
   char t = *a1;
   *a1 = *b1;
   *b1 = t;
}

// A utility function to reverse string str1[low1..high1]
void reverse ( char* str1, int low1, int high1 ) {
   while ( low1 < high1 ) {
      swap(&str1[low1], &str1[high1]);
      ++low1;
      --high1;
   }
}

// Cycle leader algorithm to shift all even
// positioned elements at the end.
void cycleLeader ( char* str1, int shift1, int len1 ) {
   int j;
   char item1;
    for (int i = 1; i < len1; i *= 3 ) {
        j = i;
        item1 = str1[j + shift1];
        do {
            // odd index
            if ( j & 1 )
                j = len1 / 2 + j / 2;
            // even index
            else
                j /= 2;
            // keep the back-up of element at new position
            swap (&str1[j + shift1], &item1);
        } while ( j != i );
    }
}

// The main function to convert a string. This function
// mainly implements cycleLeader() to convert
void moveNumberToSecondHalf( char* str1 ) {
    int k, lenFirst1;
    int lenRemaining1 = strlen( str1 );
    int shift1 = 0;

    while ( lenRemaining1 ) {
        k = 0;
        // Step 1: Find the highest prefix
        // subarray of the form 3^k + 1
        while ( (int)pow( 3, k ) + 1 <= lenRemaining1 )
            k++;
        lenFirst1 = (int)pow( 3, k - 1 ) + 1;
        lenRemaining1 -= lenFirst1;

        // Step 2: Implement cycle leader algorithm
        // for the highest subarray
        cycleLeader ( str1, shift1, lenFirst1 );

        // Step 4.1: Reverse the second half of first subarray
        reverse ( str1, shift1 / 2, shift1 - 1 );

        // Step 4.2: Reverse the first half of second sub-string
        reverse ( str1, shift1, shift1 + lenFirst1 / 2 - 1 );

        // Step 4.3: Reverse the second half of first sub-string
        // and first half of second sub-string together
        reverse ( str1, shift1 / 2, shift1 + lenFirst1 / 2 - 1 );

        // Now increase the length of first subarray
        shift1 += lenFirst1;
    }
}

// Driver program to verify or test the above function
int main() {
    char str1[] = "a1b2c3d4e5f6g7";

    cout << "Input : " << str1 << '\n';
    moveNumberToSecondHalf( str1 );
    cout << "Output: " << str1 << '\n';

    return 0;
}

Following is the output of the above program, showing both the original input string and its output.

Input : a1b2c3d4e5f6g7
Output: abcdefg1234567

Time Complexity: O(n), because each character is moved a constant number of times during the transformation process.

Space Complexity: O(1), because the transformation is performed entirely in place without using any additional space.

Conclusion

In this article, we have learned to transform a string in-place so that all even-positioned characters move to the end while keeping the order of characters the same. We used the Cycle Leader Iteration Algorithm with a few reversals to achieve this in O(n) time and O(1) space complexity.

Updated on: 2025-08-06T16:18:30+05:30

177 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements