Sort a string according to the order defined by another string
Last Updated :
25 Apr, 2023
Given two strings (of lowercase letters), a pattern, and a string. The task is to sort strings according to the order defined by the pattern. It may be assumed that the pattern has all characters of the string and all characters in the pattern appear only once.
Examples:
Input : pat = "bca", str = "abc"
Output : str = "bca"
Input : pat = "bxyzca", str = "abcabcabc"
Output : str = "bbbcccaaa"
Input : pat = "wcyuogmlrdfphitxjakqvzbnes", str = "jcdokai"
Output : str = "codijak"
Approach 1: The idea is to first count occurrences of all characters in str and store these counts in a count array. Then traverse pattern from left to right, and for each character pat[i], see how many times it appears in count array and copy this character these many times to str.
Below is the implementation of the above idea.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 26;
void sortByPattern(string& str, string pat)
{
int count[MAX_CHAR] = { 0 };
for ( int i = 0; i < str.length(); i++)
count[str[i] - 'a' ]++;
int index = 0;
for ( int i = 0; i < pat.length(); i++)
for ( int j = 0; j < count[pat[i] - 'a' ]; j++)
str[index++] = pat[i];
}
int main()
{
string pat = "bca" ;
string str = "abc" ;
sortByPattern(str, pat);
cout << str;
return 0;
}
|
Java
class GFG {
static int MAX_CHAR = 26 ;
static void sortByPattern( char [] str, char [] pat)
{
int count[] = new int [MAX_CHAR];
for ( int i = 0 ; i < str.length; i++) {
count[str[i] - 'a' ]++;
}
int index = 0 ;
for ( int i = 0 ; i < pat.length; i++) {
for ( int j = 0 ; j < count[pat[i] - 'a' ]; j++) {
str[index++] = pat[i];
}
}
}
public static void main(String args[])
{
char [] pat = "bca" .toCharArray();
char [] str = "abc" .toCharArray();
sortByPattern(str, pat);
System.out.println(String.valueOf(str));
}
}
|
Python3
MAX_CHAR = 26
def sortByPattern( str , pat):
global MAX_CHAR
count = [ 0 ] * MAX_CHAR
for i in range ( 0 , len ( str )):
count[ ord ( str [i]) - 97 ] + = 1
index = 0 ;
str = ""
for i in range ( 0 , len (pat)):
j = 0
while (j < count[ ord (pat[i]) - ord ( 'a' )]):
str + = pat[i]
j = j + 1
index + = 1
return str
pat = "bca"
str = "abc"
print (sortByPattern( str , pat))
|
C#
using System;
class GFG {
static int MAX_CHAR = 26;
static void sortByPattern( char [] str, char [] pat)
{
int [] count = new int [MAX_CHAR];
for ( int i = 0; i < str.Length; i++) {
count[str[i] - 'a' ]++;
}
int index = 0;
for ( int i = 0; i < pat.Length; i++) {
for ( int j = 0; j < count[pat[i] - 'a' ]; j++) {
str[index++] = pat[i];
}
}
}
public static void Main(String[] args)
{
char [] pat = "bca" .ToCharArray();
char [] str = "abc" .ToCharArray();
sortByPattern(str, pat);
Console.WriteLine(String.Join( "" , str));
}
}
|
Javascript
<script>
let MAX_CHAR = 26;
function sortByPattern(str,pat)
{
let count = new Array(MAX_CHAR);
for (let i = 0; i < MAX_CHAR; i++)
{
count[i] = 0;
}
for (let i = 0; i < str.length; i++) {
count[str[i].charCodeAt(0) - 'a' .charCodeAt(0)]++;
}
let index = 0;
for (let i = 0; i < pat.length; i++) {
for (let j = 0; j < count[pat[i].charCodeAt(0) - 'a' .charCodeAt(0)]; j++) {
str[index++] = pat[i];
}
}
}
let pat = "bca" .split( "" );
let str = "abc" .split( "" );
sortByPattern(str, pat);
document.write((str).join( "" ));
</script>
|
Time complexity: O(m+n) where m is the length of the pattern and n is the length of str.
Auxiliary Space: O(1)
Approach 2:
We can pass a comparator to the sort() function and sort the string according to the pattern.
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > position(26, -1);
bool cmp( char & char1, char & char2)
{
return position[char1 - 'a' ] < position[char2 - 'a' ];
}
int main()
{
string pat = "wcyuogmlrdfphitxjakqvzbnes" ;
for ( int i = 0; i < pat.length(); i++) {
if (position[pat[i] - 'a' ] == -1)
position[pat[i] - 'a' ] = i;
}
string str = "jcdokai" ;
sort(str.begin(), str.end(), cmp);
cout << str;
}
|
Java
import java.util.*;
class Main {
static List<Integer> position = new ArrayList<>(Collections.nCopies( 26 , - 1 ));
static int cmp( char char1, char char2) {
if (position.get(char1 - 'a' ) < position.get(char2 - 'a' )) {
return - 1 ;
} else if (position.get(char1 - 'a' ) > position.get(char2 - 'a' )) {
return 1 ;
} else {
return 0 ;
}
}
public static void main(String[] args) {
String pat = "wcyuogmlrdfphitxjakqvzbnes" ;
for ( int i = 0 ; i < pat.length(); i++) {
if (position.get(pat.charAt(i) - 'a' ) == - 1 ) {
position.set(pat.charAt(i) - 'a' , i);
}
}
String str = "jcdokai" ;
char [] charArr = str.toCharArray();
Arrays.sort(charArr, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
return cmp(c1, c2);
}
});
String sortedStr = new String(charArr);
System.out.println(sortedStr);
}
}
|
Python3
from typing import List
from functools import cmp_to_key
position: List [ int ] = [ - 1 ] * 26
def cmp (char1: str , char2: str ) - > int :
if position[ ord (char1) - ord ( 'a' )] < position[ ord (char2) - ord ( 'a' )]:
return - 1
elif position[ ord (char1) - ord ( 'a' )] > position[ ord (char2) - ord ( 'a' )]:
return 1
else :
return 0
if __name__ = = '__main__' :
pat = "wcyuogmlrdfphitxjakqvzbnes"
for i in range ( len (pat)):
if position[ ord (pat[i]) - ord ( 'a' )] = = - 1 :
position[ ord (pat[i]) - ord ( 'a' )] = i
str = "jcdokai"
sorted_str = sorted ( str , key = cmp_to_key( cmp ))
print (''.join(sorted_str))
|
Javascript
<script>
let position = new Array(26).fill(-1);
function cmp(char1, char2)
{
return position[char1.charCodeAt(0) - 'a' .charCodeAt(0)] - position[char2.charCodeAt(0) - 'a' .charCodeAt(0)];
}
let pat = "wcyuogmlrdfphitxjakqvzbnes" ;
for (let i = 0; i <br pat.length; i++) {
if (position[pat.charCodeAt(i) - 'a' .charCodeAt(0)] == -1)
position[pat.charCodeAt(i) - 'a' .charCodeAt(0)] = i;
}
let str = "jcdokai" ;
str = str.split( "" ).sort(cmp).join( "" );
document.write(str, "</br>" );
</script>
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static List< int > position = Enumerable.Repeat(-1, 26).ToList();
static int Cmp( char char1, char char2) {
if (position[char1 - 'a' ] < position[char2 - 'a' ]) {
return -1;
} else if (position[char1 - 'a' ] > position[char2 - 'a' ]) {
return 1;
} else {
return 0;
}
}
public static void Main() {
string pat = "wcyuogmlrdfphitxjakqvzbnes" ;
for ( int i = 0; i < pat.Length; i++) {
if (position[pat[i] - 'a' ] == -1) {
position[pat[i] - 'a' ] = i;
}
}
string str = "jcdokai" ;
char [] charArr = str.ToCharArray();
Array.Sort(charArr, new Comparison< char >(Cmp));
string sortedStr = new string (charArr);
Console.WriteLine(sortedStr);
}
}
|
Time complexity: O(m+nlogn) where m is the length of the pattern and n is the length of str.
Auxiliary Space: O(1)
Exercise: In the above solution, it is assumed that the pattern has all characters of str. Consider a modified version where the pattern may not have all characters and the task is to put all remaining characters (in the string but not in the pattern) at the end. The remaining characters need to be put in alphabetically sorted order.Hint: In the second loop, when increasing the index and putting the character in str, we can also decrease the count at that time. And finally, we traverse the count array to put the remaining characters in alphabetically sorted order.
Share your thoughts in the comments
Please Login to comment...