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++ 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;
}
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);
}
}
}
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# 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.
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)