Open In App

Sort an Array of Version Numbers

Improve
Improve
Like Article
Like
Save
Share
Report

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)



Last Updated : 26 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads