Given an array of strings arr[], consisting of N strings each representing dot separated numbers in the form of software versions.
Input: arr[] = {“1.1.2”, “0.9.1”, “1.1.0”} Output: “0.9.1” “1.1.0” “1.1.2” Input: arr[] = {“1.2”, “0.8.1”, “1.0”} Output: “0.8.1” “1.0” “1.2”
Approach: Follow the steps below to solve the problem:
- Create a function to compare two strings.
- Store strings into a vector.
- In order to compare two dot separated strings S1 and S2, iterate up to the length min(S1, S2) + 1 and compare each numerical parts of the string and sort accordingly.
- Repeat the above steps for each pair of string and sort the array accordingly.
Below is the implementation of above idea:
C++
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Compares two strings int check( const string& a, const string& b)
{ int al = a.length();
int bl = b.length();
int i = 0, j = 0;
while (i < al && j < bl) {
if (a[i] == b[j]) {
++i;
++j;
}
else if (a[i] > b[j]) {
return 1;
}
else
return -1;
}
if (i == al && j == bl)
return 0;
if (i == al)
return -1;
return 1;
} // Function to split strings based on dots vector<string> getTokens( const string& a)
{ vector<string> v;
string s;
// Stringstream is used here for
// tokenising the string based
// on "." delimiter which might
// contain unequal number of "."[dots]
stringstream ss(a);
while (getline(ss, s, '.' )) {
v.push_back(s);
}
return v;
} // Comparator to sort the array of strings bool comp( const string& a, const string& b)
{ // Stores the numerical substrings
vector<string> va, vb;
va = getTokens(a);
vb = getTokens(b);
// Iterate up to length of minimum
// of the two strings
for ( int i = 0; i < min(va.size(), vb.size());
i++) {
// Compare each numerical substring
// of the two strings
int countCheck = check(va[i], vb[i]);
if (countCheck == -1)
return true ;
else if (countCheck == 1)
return false ;
}
if (va.size() < vb.size())
return true ;
return false ;
} // Driver Code int main()
{ vector<string> s;
s.push_back( "1.1.0" );
s.push_back( "1.2.1" );
s.push_back( "0.9.1" );
s.push_back( "1.3.4" );
s.push_back( "1.1.2" );
s.push_back( "1.1.2.2.3" );
s.push_back( "9.3" );
// Sort the strings using comparator
sort(s.begin(), s.end(), comp);
// Display the sorted order
for ( int i = 0; i < s.size(); i++) {
cout << s[i] << endl;
}
cout << endl;
return 0;
} |
Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class VersionComparator implements Comparator<String> {
@Override
public int compare(String a, String b) {
String[] va = a.split( "\\." );
String[] vb = b.split( "\\." );
int minLength = Math.min(va.length, vb.length);
for ( int i = 0 ; i < minLength; i++) {
int comparison = va[i].compareTo(vb[i]);
if (comparison != 0 ) {
return comparison;
}
}
return Integer.compare(va.length, vb.length);
}
} public class Main {
public static void main(String[] args) {
List<String> versions = new ArrayList<>();
versions.add( "1.1.0" );
versions.add( "1.2.1" );
versions.add( "0.9.1" );
versions.add( "1.3.4" );
versions.add( "1.1.2" );
versions.add( "1.1.2.2.3" );
versions.add( "9.3" );
Collections.sort(versions, new VersionComparator());
for (String version : versions) {
System.out.println(version);
}
}
} |
Python3
from functools import cmp_to_key
def check(a, b):
i, j = 0 , 0
while i < len (a) and j < len (b):
if a[i] = = b[j]:
i + = 1
j + = 1
elif a[i] > b[j]:
return 1
else :
return - 1
if i = = len (a) and j = = len (b):
return 0
if i = = len (a):
return - 1
return 1
def get_tokens(a):
return a.split( '.' )
def comp(a, b):
va, vb = get_tokens(a), get_tokens(b)
for i in range ( min ( len (va), len (vb))):
count_check = check(va[i], vb[i])
if count_check = = - 1 :
return - 1
elif count_check = = 1 :
return 1
return len (va) - len (vb)
s = [ "1.1.0" , "1.2.1" , "0.9.1" , "1.3.4" , "1.1.2" , "1.1.2.2.3" , "9.3" ]
s.sort(key = cmp_to_key(comp))
for version in s:
print (version)
|
C#
// C# Program to implement // the above approach using System;
using System.Collections.Generic;
public class comp : IComparer< string >
{ // Compares two strings
static int check( string a, string b)
{
int al = a.Length;
int bl = b.Length;
int i = 0, j = 0;
while (i < al && j < bl) {
if (a[i] == b[j]) {
++i;
++j;
}
else if (a[i] > b[j]) {
return 1;
}
else
return -1;
}
if (i == al && j == bl)
return 0;
if (i == al)
return -1;
return 1;
}
// Function to split strings based on dots
static List < string > getTokens( string a)
{
List< string > v = new List< string >(a.Split( '.' ));
return v;
}
// Comparator to sort the array of strings
public int Compare( string a, string b)
{
// Stores the numerical substrings
List< string > va, vb;
va = getTokens(a);
vb = getTokens(b);
// Iterate up to length of minimum
// of the two strings
for ( int i = 0; i < Math.Min(va.Count, vb.Count);
i++) {
// Compare each numerical substring
// of the two strings
int countCheck = check(va[i], vb[i]);
if (countCheck == -1)
return -1;
else if (countCheck == 1)
return 1;
}
if (va.Count < vb.Count)
return -1;
return 1;
}
} class GFG
{ // Driver Code
public static void Main( string [] args)
{
List< string > s = new List< string >();
s.Add( "1.1.0" );
s.Add( "1.2.1" );
s.Add( "0.9.1" );
s.Add( "1.3.4" );
s.Add( "1.1.2" );
s.Add( "1.1.2.2.3" );
s.Add( "9.3" );
// Sort the strings using comparator
s.Sort( new comp());
// Display the sorted order
for ( int i = 0; i < s.Count; i++) {
Console.WriteLine(s[i]);
}
}
} // This code is contributed by phasing17. |
Javascript
function check(a, b) {
let i = 0, j = 0;
while (i < a.length && j < b.length) {
if (a[i] === b[j]) {
i++;
j++;
} else if (a[i] > b[j]) {
return 1;
} else {
return -1;
}
}
if (i === a.length && j === b.length) {
return 0;
}
if (i === a.length) {
return -1;
}
return 1;
} function getTokens(a) {
return a.split( '.' );
} function comp(a, b) {
const va = getTokens(a);
const vb = getTokens(b);
for (let i = 0; i < Math.min(va.length, vb.length); i++) {
const countCheck = check(va[i], vb[i]);
if (countCheck === -1) {
return -1;
} else if (countCheck === 1) {
return 1;
}
}
return va.length - vb.length;
} const s = [ "1.1.0" , "1.2.1" , "0.9.1" , "1.3.4" , "1.1.2" , "1.1.2.2.3" , "9.3" ];
s.sort(comp); for (const version of s) {
console.log(version);
} |
Output
0.9.1 1.1.0 1.1.2 1.1.2.2.3 1.2.1 1.3.4 9.3
Time complexity: O(n*log(n)*len) where n is the number of strings in the array and len is the length of longest string in the array
Auxiliary space: O(len)