Open In App

Number of pairs of words not in correct order

Last Updated : 12 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of words sentence[] and another array of words dictionary[] denoting the correct order of words, the task is to find the number of pairs of words that are not in the correct order.

Examples:

Input: sentence[]= {“red”, “apple”, “is”, “the”}, dictionary[]= {“the”, “apple”, “is”, “red”}
Output: 5
Explanation: In the comparison of the positions of each word in the two sentences, there are 5 pairs that are not in correct order. These are: (“red”, “apple”), (“red”, “is”), (“red”, “the”), (“apple”, “the”), and (“is”, “the”).

Input: sentence[] = {“sun”, “the”, “shining”, “is”, “bright”, “today”}, dictionary[]= {“the”, “sun”, “is”, “shining”, “bright”, “today”}
Output: 2
Explanation: In the comparison of the positions of each word in the sentences, there are 2 pairs that are not in correct order. These are: (“sun”, “the”) and (“shining”, “is”).

We recommend you to refer Fenwick Tree or Binary Indexed Tree (BIT) before further reading this post.

Background on BIT:

BIT basically supports two operations for an array arr[] of size n:

  1. Sum or query of elements till arr[i] in O(log n) time.
  2. Update an array element in O(log n) time.

BIT is implemented using an array and works in form of trees. Note that there are two ways of looking at BIT as a tree.

  1. The sum or query operation where parent of index x is “x – (x & -x)”.
  2. The update operation where parent of index x is “x + (x & -x)”.

Approach: To solve the problem, follow the below idea:

Store the ‘dictionary‘ order in the map and convert the ‘sentence‘ order to integers using the map and store it in an array. Traverse through the array from right and for every index find the number of smaller elements on the right side of the array. This can be done using BIT. Sum up the counts for all indexes in the array and print the sum which is the number of pairs which are not in order.

Step-by-step algorithm:

  • Create a map, BIT and an array.
  • Store the dictionary order in the map.
  • Convert the sentence order to integers using the map and store it in an array.
  • Traverse through the array from right to left.
  • For every index get count of elements smaller than arr[i] and add it to variable ‘ans’.
  • To get the count of smaller elements, query() of BIT is used.
  • After that we add the current element to the BIT[] by using update() of BIT that updates the count of the current element from 0 to 1, and therefore updates ancestors of the current element in BIT.
  • Return the sum as ans.

Below is the implementation of the algorithm:

C++14




// C++ program to count disorder level using Binary Indexed
// Tree
#include <bits/stdc++.h>
using namespace std;
 
// Function to update the Binary Indexed Tree (BIT)
void update(int bit[], int x, int val, int n)
{
    // Traverse all ancestors and add 'val'
    while (x <= n) {
        bit[x] += val;
        x += x & -x; // Get next
    }
}
 
// Function to get sum from BIT
int query(int bit[], int x)
{
    int sum = 0;
    // Traverse all ancestors and add their values
    while (x > 0) {
        sum += bit[x];
        x -= x & -x; // Parent in BIT
    }
    return sum;
}
 
// Function to calculate the disorder level of a sentence
long long getDisorderLevel(string sentence[],
                           string normal[], int n)
{
    // Size of the BIT
    int MAX = n + 1;
    // Map to store the normal order
    map<string, int> m;
    // BIT and array to store the sentence order
    int bit[MAX] = { 0 }, a[MAX];
 
    // Store the normal order in the map
    for (int i = 0; i < n; i++) {
        m[normal[i]] = i + 1;
    }
 
    // Convert the sentence order to integers using the map
    for (int i = 0; i < n; i++) {
        a[i] = m[sentence[i]];
    }
 
    long long disorderLevel = 0;
 
    // Traverse all elements from right
    for (int i = n - 1; i >= 0; i--) {
        // Get count of elements smaller than arr[i]
        disorderLevel += query(bit, a[i] - 1);
 
        // Update the BIT
        update(bit, a[i], 1, n);
    }
    return disorderLevel;
}
 
// Driver code
int main()
{
    // Test case 1
    string sentence1[] = { "red", "apple", "is", "the" };
    string normal1[] = { "the", "apple", "is", "red" };
    int n1 = sizeof(sentence1) / sizeof(sentence1[0]);
    cout << getDisorderLevel(sentence1, normal1, n1)
         << endl;
 
    // Test case 2
    string sentence2[] = { "sun", "the",    "shining",
                           "is",  "bright", "today" };
    string normal2[] = { "the",     "sun",    "is",
                         "shining", "bright", "today" };
    int n2 = sizeof(sentence2) / sizeof(sentence2[0]);
    cout << getDisorderLevel(sentence2, normal2, n2)
         << endl;
 
    return 0;
}


Java




// Java program to count disorder level using Binary Indexed
// Tree
import java.util.*;
import java.util.HashMap;
import java.util.Map;
 
public class Main {
 
    // Function to update the Binary Indexed Tree (BIT)
    static void update(int[] bit, int x, int val, int n)
    {
        // Traverse all ancestors and add 'val'
        while (x <= n) {
            bit[x] += val;
            x += x & -x;
        }
    }
 
    // Function to get sum from BIT
    static int query(int[] bit, int x)
    {
        int sum = 0;
        // Traverse all ancestors and add their values
        while (x > 0) {
            sum += bit[x];
            x -= x & -x;
        }
        return sum;
    }
 
    // Function to calculate the disorder level of a
    // sentence
    static long getDisorderLevel(String[] sentence,
                                 String[] normal, int n)
    {
        // Size of the BIT
        int MAX = n + 1;
        // Map to store the normal order
        Map<String, Integer> m = new HashMap<>();
        // BIT and array to store the sentence order
        int[] bit = new int[MAX];
        int[] a = new int[MAX];
 
        // Store the normal order in the map
        for (int i = 0; i < n; i++) {
            m.put(normal[i], i + 1);
        }
 
        // Convert the sentence order to integers using the
        // map
        for (int i = 0; i < n; i++) {
            a[i] = m.get(sentence[i]);
        }
 
        long disorderLevel = 0;
 
        // Traverse all elements from right.
        for (int i = n - 1; i >= 0; i--) {
            // Get count of elements smaller than arr[i]
            disorderLevel += query(bit, a[i] - 1);
 
            // Update the BIT
            update(bit, a[i], 1, n);
        }
        return disorderLevel;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        // Test case 1
        String[] sentence1
            = { "red", "apple", "is", "the" };
        String[] normal1 = { "the", "apple", "is", "red" };
        int n1 = sentence1.length;
        System.out.println(
            getDisorderLevel(sentence1, normal1, n1));
 
        // Test case 2
        String[] sentence2 = { "sun", "the",    "shining",
                               "is",  "bright", "today" };
        String[] normal2 = { "the",     "sun",    "is",
                             "shining", "bright", "today" };
        int n2 = sentence2.length;
        System.out.println(
            getDisorderLevel(sentence2, normal2, n2));
    }
}


Python3




# Java program to count disorder level using Binary Indexed Tree
def update(bit, x, val, n):
    # Traverse all ancestors and add 'val'
    while x <= n:
        bit[x] += val
        x += x & -# Get next
 
 
def query(bit, x):
    sum_val = 0
    # Traverse all ancestors and add their values
    while x > 0:
        sum_val += bit[x]
        x -= x & -# Parent in BIT
    return sum_val
 
 
def get_disorder_level(sentence, normal, n):
    # Size of the BIT
    MAX = n + 1
    # Map to store the normal order
    m = {}
    # BIT and array to store the sentence order
    bit = [0] * MAX
    a = [0] * MAX
 
    # Store the normal order in the map
    for i in range(n):
        m[normal[i]] = i + 1
 
    # Convert the sentence order to integers using the map
    for i in range(n):
        a[i] = m[sentence[i]]
 
    disorder_level = 0
 
    # Traverse all elements from right.
    for i in range(n - 1, -1, -1):
        # Get count of elements smaller than arr[i]
        disorder_level += query(bit, a[i] - 1)
 
        # Update the BIT
        update(bit, a[i], 1, n)
 
    return disorder_level
 
 
# Driver code
# Test case 1
sentence1 = ["red", "apple", "is", "the"]
normal1 = ["the", "apple", "is", "red"]
n1 = len(sentence1)
print(get_disorder_level(sentence1, normal1, n1))
 
# Test case 2
sentence2 = ["sun", "the", "shining", "is", "bright", "today"]
normal2 = ["the", "sun", "is", "shining", "bright", "today"]
n2 = len(sentence2)
print(get_disorder_level(sentence2, normal2, n2))


C#




using System;
using System.Collections.Generic;
 
class GFG
{
    // Function to update the Binary Indexed Tree (BIT)
    static void Update(int[] bit, int x, int val, int n)
    {
        // Traverse all ancestors and add 'val'
        while (x <= n)
        {
            bit[x] += val;
            x += x & -x; // Get next
        }
    }
 
    // Function to get sum from BIT
    static int Query(int[] bit, int x)
    {
        int sum = 0;
        // Traverse all ancestors and add their values
        while (x > 0)
        {
            sum += bit[x];
            x -= x & -x; // Parent in BIT
        }
        return sum;
    }
 
    // Function to calculate the disorder level of a sentence
    static long GetDisorderLevel(string[] sentence, string[] normal, int n)
    {
        // Size of the BIT
        int MAX = n + 1;
        // Map to store the normal order
        Dictionary<string, int> m = new Dictionary<string, int>();
        // BIT and array to store the sentence order
        int[] bit = new int[MAX];
        int[] a = new int[MAX];
 
        // Store the normal order in the map
        for (int i = 0; i < n; i++)
        {
            m[normal[i]] = i + 1;
        }
 
        // Convert the sentence order to integers using the map
        for (int i = 0; i < n; i++)
        {
            a[i] = m[sentence[i]];
        }
 
        long disorderLevel = 0;
 
        // Traverse all elements from right
        for (int i = n - 1; i >= 0; i--)
        {
            // Get count of elements smaller than arr[i]
            disorderLevel += Query(bit, a[i] - 1);
 
            // Update the BIT
            Update(bit, a[i], 1, n);
        }
        return disorderLevel;
    }
 
    // Driver code
    static void Main()
    {
        // Test case 1
        string[] sentence1 = { "red", "apple", "is", "the" };
        string[] normal1 = { "the", "apple", "is", "red" };
        int n1 = sentence1.Length;
        Console.WriteLine(GetDisorderLevel(sentence1, normal1, n1));
 
        // Test case 2
        string[] sentence2 = { "sun", "the", "shining", "is", "bright", "today" };
        string[] normal2 = { "the", "sun", "is", "shining", "bright", "today" };
        int n2 = sentence2.Length;
        Console.WriteLine(GetDisorderLevel(sentence2, normal2, n2));
    }
}
 
// This code is contributed by shivamgupta0987654321


Javascript




// Function to update the Binary Indexed Tree (BIT)
function update(bit, x, val, n) {
    // Traverse all ancestors and add 'val'
    while (x <= n) {
        bit[x] += val;
        x += x & -x; // Get next
    }
}
 
// Function to get sum from BIT
function query(bit, x) {
    let sum = 0;
    // Traverse all ancestors and add their values
    while (x > 0) {
        sum += bit[x];
        x -= x & -x; // Parent in BIT
    }
    return sum;
}
 
// Function to calculate the disorder level of a sentence
function getDisorderLevel(sentence, normal, n) {
    // Size of the BIT
    const MAX = n + 1;
    // Map to store the normal order
    const m = new Map();
    // BIT and array to store the sentence order
    const bit = new Array(MAX).fill(0);
    const a = [];
 
    // Store the normal order in the map
    for (let i = 0; i < n; i++) {
        m.set(normal[i], i + 1);
    }
 
    // Convert the sentence order to integers using the map
    for (let i = 0; i < n; i++) {
        a[i] = m.get(sentence[i]);
    }
 
    let disorderLevel = 0;
 
    // Traverse all elements from right
    for (let i = n - 1; i >= 0; i--) {
        // Get count of elements smaller than arr[i]
        disorderLevel += query(bit, a[i] - 1);
 
        // Update the BIT
        update(bit, a[i], 1, n);
    }
    return disorderLevel;
}
 
// Driver code
// Test case 1
const sentence1 = ["red", "apple", "is", "the"];
const normal1 = ["the", "apple", "is", "red"];
console.log(getDisorderLevel(sentence1, normal1, sentence1.length));
 
// Test case 2
const sentence2 = ["sun", "the", "shining", "is", "bright", "today"];
const normal2 = ["the", "sun", "is", "shining", "bright", "today"];
console.log(getDisorderLevel(sentence2, normal2, sentence2.length));


Output

5
2




Time complexity: O(N * log(N)), where N is the number of words in the input.
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads