Print array of strings in sorted order without copying one string into another
Given an array of strings arr[], the task is to print the strings in lexicographically sorted order. The sorting must be done such that no string is physically copied to another string during the sorting process.
Examples:
Input: arr[] = ["geeks", "for", "geeks", "quiz"]
Output: for geeks geeks quizInput: arr[] = ["ball", "pen", "apple", "kite"]
Output: apple ball kite penInput: arr[] = ["dog", "ant", "zebra", "bee"]
Output: ant bee dog zebra
Approach:
The idea is to avoid copying actual strings during sorting by using an index array that represents the positions of the original strings. Instead of swapping strings, we compare their values via indices and sort these indices based on the string comparisons. In the end, the strings are printed using the sorted indices, preserving the original array.
--> str[] = {"world", "hello"}
--> corresponding index array will be
indexed_arr = {0, 1}
--> Now, how the strings are compared and
accordingly values in indexed_arr are changed.
--> Comparison process:
if (str[index[0]].compare(str[index[1]] > 0
temp = index[0]
index[0] = index[1]
index[1] = temp
// after sorting values of
// indexed_arr = {1, 0}
--> for i=0 to 1
print str[index[i]]
This is how the strings are compared and their corresponding indexes in the indexed_arr are being manipulated/swapped so that after the sorting process is completed, the order of indexes in the indexed_arr
gives us the sorted order of the strings.
Steps to implement the above idea:
- Initialize an index array of same size as the input vector to store original positions of the strings.
- Fill this index array with values from 0 to n-1, representing original positions of each string.
- Use a nested loop to perform selection sort by comparing strings using their index references.
- In each iteration, find the index that points to the lexicographically smallest string in the unsorted portion.
- Swap only the indices in the index array, not the actual strings in the original array.
- After sorting, loop through the sorted index array and print the corresponding strings from the original array.
// C++ program to sort a vector of strings
// without copying actual strings
#include <iostream>
#include <vector>
using namespace std;
// Function to print strings in lexicographical order
void sortStrings(vector<string> &arr) {
int n = arr.size();
vector<int> index(n);
// Initialize array to store original indices
// of strings
for (int i = 0; i < n; i++) {
index[i] = i;
}
// Sort based on string comparison
for (int i = 0; i < n - 1; i++) {
// Assume current index as minimum
int minIdx = i;
// Find index with lexicographically
// smaller string
for (int j = i + 1; j < n; j++) {
if (arr[index[j]] < arr[index[minIdx]]) {
minIdx = j;
}
}
// Swap indices only
if (minIdx != i) {
swap(index[i], index[minIdx]);
}
}
// Print strings using sorted indices
for (int i = 0; i < n; i++) {
cout << arr[index[i]] << " ";
}
}
// Driver code
int main() {
vector<string> arr = {"geeks", "for", "geeks", "quiz"};
sortStrings(arr);
return 0;
}
// Java program to sort an array of strings
// without copying actual strings
class GfG {
// Function to print strings in lexicographical order
static void sortStrings(String[] arr) {
int n = arr.length;
int[] index = new int[n];
// Initialize array to store original indices
// of strings
for (int i = 0; i < n; i++) {
index[i] = i;
}
// Sort based on string comparison
for (int i = 0; i < n - 1; i++) {
// Assume current index as minimum
int minIdx = i;
// Find index with lexicographically
// smaller string
for (int j = i + 1; j < n; j++) {
if (arr[index[j]].compareTo(arr[index[minIdx]]) < 0) {
minIdx = j;
}
}
// Swap indices only
if (minIdx != i) {
int temp = index[i];
index[i] = index[minIdx];
index[minIdx] = temp;
}
}
// Print strings using sorted indices
for (int i = 0; i < n; i++) {
System.out.print(arr[index[i]] + " ");
}
}
// Driver code
public static void main(String[] args) {
String[] arr = {"geeks", "for", "geeks", "quiz"};
sortStrings(arr);
}
}
# Python program to sort an array of strings
# without copying actual strings
def sortStrings(arr):
n = len(arr)
index = [0] * n
# Initialize array to store original indices
# of strings
for i in range(n):
index[i] = i
# Sort based on string comparison
for i in range(n - 1):
# Assume current index as minimum
minIdx = i
# Find index with lexicographically
# smaller string
for j in range(i + 1, n):
if arr[index[j]] < arr[index[minIdx]]:
minIdx = j
# Swap indices only
if minIdx != i:
index[i], index[minIdx] = index[minIdx], index[i]
# Print strings using sorted indices
for i in range(n):
print(arr[index[i]], end=" ")
# Driver code
if __name__ == "__main__":
arr = ["geeks", "for", "geeks", "quiz"]
sortStrings(arr)
// C# program to sort an array of strings
// without copying actual strings
using System;
class GfG {
// Function to print strings in lexicographical order
public static void sortStrings(string[] arr) {
int n = arr.Length;
int[] index = new int[n];
// Initialize array to store original indices
// of strings
for (int i = 0; i < n; i++) {
index[i] = i;
}
// Sort based on string comparison
for (int i = 0; i < n - 1; i++) {
// Assume current index as minimum
int minIdx = i;
// Find index with lexicographically
// smaller string
for (int j = i + 1; j < n; j++) {
if (String.Compare(arr[index[j]], arr[index[minIdx]]) < 0) {
minIdx = j;
}
}
// Swap indices only
if (minIdx != i) {
int temp = index[i];
index[i] = index[minIdx];
index[minIdx] = temp;
}
}
// Print strings using sorted indices
for (int i = 0; i < n; i++) {
Console.Write(arr[index[i]] + " ");
}
}
// Driver code
public static void Main() {
string[] arr = {"geeks", "for", "geeks", "quiz"};
sortStrings(arr);
}
}
// JavaScript program to sort an array of strings
// without copying actual strings
function sortStrings(arr) {
let n = arr.length;
let index = new Array(n);
// Initialize array to store original indices
// of strings
for (let i = 0; i < n; i++) {
index[i] = i;
}
// Sort based on string comparison
for (let i = 0; i < n - 1; i++) {
// Assume current index as minimum
let minIdx = i;
// Find index with lexicographically
// smaller string
for (let j = i + 1; j < n; j++) {
if (arr[index[j]] < arr[index[minIdx]]) {
minIdx = j;
}
}
// Swap indices only
if (minIdx !== i) {
let temp = index[i];
index[i] = index[minIdx];
index[minIdx] = temp;
}
}
// Print strings using sorted indices
for (let i = 0; i < n; i++) {
process.stdout.write(arr[index[i]] + " ");
}
}
// Driver code
let arr = ["geeks", "for", "geeks", "quiz"];
sortStrings(arr);
Output
for geeks geeks quiz
Time Complexity: O(n²), due to nested loops during sorting.
Space Complexity: O(n), extra space for index array.
Application in Real World
This approach is useful in scenarios where minimizing disk writes is important, such as sorting an array of structures. Instead of swapping the entire structures, which can be costly in terms of memory and I/O, we compare their values and maintain a separate index array. Sorting is performed by rearranging these indices, effectively representing the sorted order without altering the original data.