Open In App

Count of pairs of strings which differ in exactly one position

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of strings of equal lengths. The task is to calculate the total number of pairs of strings which differ in exactly one position. Examples:

Input: arr[] = {“abc”, “abd”, “bbd”}
Output: 2 (abc, abd) and (abd, bbd) are the only valid pairs. 

Input: arr[] = {“def”, “deg”, “dmf”, “xef”, “dxg”} 
Output: 4

Method 1: For every possible pair, check if both the strings differ in exactly a single index position with a single traversal of the strings. Method 2: Two string can be compared in the following way in order to check whether they differ in a single index position:

Let str1 = “abc” and str2 = “adc” For str1, add “#bc”, “a#c” and “ab#” to a set. Now for str2, generate the string in the similar manner and if any of the generated string is already present in the set then both the strings differ in exactly 1 index position. For example, “a#c” is one of the generated strings. Note that “#” is used because it will not be a part of any of the original strings.

Below is the implementation of the above approach: 

C++




// CPP implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the count of same pairs
int pairCount(map<string, int> &d)
{
    int sum = 0;
    for (auto i : d)
        sum += (i.second * (i.second - 1)) / 2;
 
    return sum;
}
 
// Function to return total number of strings
// which satisfy required condition
int difference(vector<string> &array, int m)
{
    // Dictionary changed will store strings
    // with wild cards
    // Dictionary same will store strings
    // that are equal
    map<string, int> changed, same;
 
    // Iterating for all strings in the given array
    for (auto s : array)
    {
        // If we found the string then increment by 1
        // Else it will get default value 0
        same[s]++;
 
        // Iterating on a single string
        for (int i = 0; i < m; i++)
        {
            // Adding special symbol to the string
            string t = s.substr(0, i) + "//" + s.substr(i + 1);
 
            // Incrementing the string if found
            // Else it will get default value 0
            changed[t]++;
        }
    }
 
    // Return counted pairs - equal pairs
    return pairCount(changed) - pairCount(same) * m;
}
 
// Driver Code
int main()
{
    int n = 3, m = 3;
    vector<string> array = {"abc", "abd", "bbd"};
    cout << difference(array, m) << endl;
 
    return 0;
}
 
// This code is contributed by
// sanjeev2552


Java




import java.util.HashMap;
import java.util.Map;
 
public class Main {
 
    // Function to return the count of same pairs
    public static int pairCount(Map<String, Integer> d)
    {
        int count = 0;
        for (int i : d.values()) {
            count += (i * (i - 1)) / 2;
        }
        return count;
    }
 
    // Function to return total number of strings
    // which satisfy required condition
    public static int difference(String[] array, int m)
    {
        // Dictionary changed will store strings
        // with wild cards
        // Dictionary same will store strings
        // that are equal
        Map<String, Integer> changed = new HashMap<>();
        Map<String, Integer> same = new HashMap<>();
 
        // Iterating for all strings in the given array
        for (String s : array) {
            // If we found the string then increment by 1
            // Else it will get default value 0
            same.put(s, same.getOrDefault(s, 0) + 1);
 
            // Iterating on a single string
            for (int i = 0; i < m; i++) {
                // Adding special symbol to the string
                String t = s.substring(0, i) + "#"
                           + s.substring(i + 1);
 
                // Incrementing the string if found
                // Else it will get default value 0
                changed.put(t,
                            changed.getOrDefault(t, 0) + 1);
            }
        }
 
        // Return counted pairs - equal pairs
        return pairCount(changed) - pairCount(same) * m;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int n = 3, m = 3;
        String[] array = { "abc", "abd", "bbd" };
        System.out.println(difference(array, m));
    }
}


Python3




# Python3 implementation of the approach
 
# Function to return the count of same pairs
def pair_count(d):
    return sum((i*(i-1))//2 for i in d.values())
 
 
# Function to return total number of strings
# which satisfy required condition
def Difference(array, m):
     
    # Dictionary changed will store strings
    # with wild cards
    # Dictionary same will store strings
    # that are equal
    changed, same = {}, {}
     
    # Iterating for all strings in the given array
    for s in array:
         
        # If we found the string then increment by 1
        # Else it will get default value 0
        same[s]= same.get(s, 0)+1
         
        # Iterating on a single string
        for i in range(m):
            # Adding special symbol to the string
            t = s[:i]+'#'+s[i + 1:]
             
            # Incrementing the string if found
            # Else it will get default value 0
            changed[t]= changed.get(t, 0)+1
 
    # Return counted pairs - equal pairs
    return pair_count(changed) - pair_count(same)*m
 
# Driver code
if __name__=="__main__":
    n, m = 3, 3
    array =["abc", "abd", "bbd"]
    print(Difference(array, m))


C#




// C# implementation of the approach
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    static int PairCount(Dictionary<string, int> d)
    {
        int sum = 0;
        foreach (var i in d.Values)
        {
            sum += (i * (i - 1)) / 2;
        }
 
        return sum;
    }
 
    static int Difference(List<string> array, int m)
    {
        // Dictionary changed will store strings
        // with wild cards
        // Dictionary same will store strings
        // that are equal
        var changed = new Dictionary<string, int>();
        var same = new Dictionary<string, int>();
 
        // Iterating for all strings in the given array
        foreach (var s in array)
        {
            // If we found the string then increment by 1
            // Else it will get default value 0
            if (!same.ContainsKey(s))
            {
                same[s] = 1;
            }
            else
            {
                same[s]++;
            }
 
            // Iterating on a single string
            for (int i = 0; i < m; i++)
            {
                // Adding special symbol to the string
                var t = s.Substring(0, i) + "#" + s.Substring(i + 1);
 
                // Incrementing the string if found
                // Else it will get default value 0
                if (!changed.ContainsKey(t))
                {
                    changed[t] = 1;
                }
                else
                {
                    changed[t]++;
                }
            }
        }
 
        // Return counted pairs - equal pairs
        return PairCount(changed) - PairCount(same) * m;
    }
 
    static void Main(string[] args)
    {
        int n = 3, m = 3;
        List<string> array = new List<string> { "abc", "abd", "bbd" };
        Console.WriteLine(Difference(array, m));
    }
}
 
// contributed by adityasharmadev01


Javascript




<script>
 
// JavaScript implementation of the approach
 
// Function to return the count of same pairs
function pairCount(d)
{
    let sum = 0;
    for (let [i,j] of d)
        sum += Math.floor((j * (j - 1)) / 2);
 
    return sum;
}
 
// Function to return total number of strings
// which satisfy required condition
function difference(array,m)
{
    // Dictionary changed will store strings
    // with wild cards
    // Dictionary same will store strings
    // that are equal
    let changed = new Map(), same = new Map();
 
    // Iterating for all strings in the given array
    for (let s of array)
    {
        // If we found the string then increment by 1
        // Else it will get default value 0
        if(same.has(s)){
            same.set(s,same.get(s)+1);
        }
        else same.set(s,1);
 
        // Iterating on a single string
        for (let i = 0; i < m; i++)
        {
            // Adding special symbol to the string
            let t = s.substring(0, i) + "//" + s.substring(i + 1,);
 
            // Incrementing the string if found
            // Else it will get default value 0
            if(changed.has(t)){
                changed.set(t,changed.get(t)+1);
            }
            else changed.set(t,1);
        }
    }
 
    // Return counted pairs - equal pairs
    return pairCount(changed) - pairCount(same) * m;
}
 
// Driver Code
 
let n = 3, m = 3;
let array = ["abc", "abd", "bbd"];
document.write(difference(array, m),"</br>");
 
// This code is contributed by shinjanpatra
 
</script>


Output

2






Time Complexity : O(n*m*m)
Auxiliary Space : O(n+m)

METHOD 2:Using Hash Table

APPROACH:

We can use a hash table to store each string along with a count of how many times it appears in the array. Then, we can iterate through each string in the array and compare it to every other string. If the two strings differ in exactly one position and they both appear in the hash table, we can increment the count.

ALGORITHM:

1.Initialize a count variable to 0
2.Initialize a hash table
3.Iterate through each string in the array
4.Add the string to the hash table along with a count of how many times it appears in the array
5.Iterate through each string in the array
6.Compare the strings character by character and count the number of positions where they differ
7.If the number of differing positions is exactly 1 and both strings appear in the hash table, increment the count variable
8.Return the count variable

C++




#include <iostream>
#include <vector>
#include <unordered_map>
 
int countPairsHashTable(const std::vector<std::string>& arr) {
    int count = 0;
    std::unordered_map<std::string, int> stringCounts;
 
    // Count the occurrences of each string
    for (const std::string& s : arr) {
        stringCounts[s]++;
    }
 
    // Compare pairs of strings for differing by exactly one character
    for (size_t i = 0; i < arr.size(); ++i) {
        for (size_t j = i + 1; j < arr.size(); ++j) {
            int diffCount = 0;
            for (size_t k = 0; k < arr[i].length(); ++k) {
                if (arr[i][k] != arr[j][k]) {
                    ++diffCount;
                    if (diffCount > 1) {
                        break;
                    }
                }
            }
            if (diffCount == 1 && stringCounts[arr[i]] > 0 && stringCounts[arr[j]] > 0) {
                ++count;
            }
        }
    }
 
    return count;
}
 
int main() {
    std::vector<std::string> arr = {"abc", "abd", "bbd"};
    std::cout << countPairsHashTable(arr) << std::endl;
 
    return 0;
}


Java




import java.util.HashMap;
import java.util.Map;
 
public class Main {
    public static int countPairsHashTable(String[] arr) {
        int count = 0;
        Map<String, Integer> stringCounts = new HashMap<>();
 
        // Count the occurrences of each string
        for (String s : arr) {
            stringCounts.put(s, stringCounts.getOrDefault(s, 0) + 1);
        }
 
        // Compare pairs of strings for differing by exactly one character
        for (int i = 0; i < arr.length; ++i) {
            for (int j = i + 1; j < arr.length; ++j) {
                int diffCount = 0;
                for (int k = 0; k < arr[i].length(); ++k) {
                    if (arr[i].charAt(k) != arr[j].charAt(k)) {
                        ++diffCount;
                        if (diffCount > 1) {
                            break;
                        }
                    }
                }
                if (diffCount == 1 && stringCounts.get(arr[i]) > 0 && stringCounts.get(arr[j]) > 0) {
                    ++count;
                }
            }
        }
 
        return count;
    }
// Driver Code
    public static void main(String[] args) {
        String[] arr = {"abc", "abd", "bbd"};
        System.out.println(countPairsHashTable(arr));
    }
}


Python3




from collections import defaultdict
 
def count_pairs_hash_table(arr):
    count = 0
    string_counts = defaultdict(int)
    for s in arr:
        string_counts[s] += 1
    for i in range(len(arr)):
        for j in range(i+1, len(arr)):
            diff_count = 0
            for k in range(len(arr[i])):
                if arr[i][k] != arr[j][k]:
                    diff_count += 1
                    if diff_count > 1:
                        break
            if diff_count == 1 and string_counts[arr[i]] > 0 and string_counts[arr[j]] > 0:
                count += 1
    return count
arr = ["abc", "abd", "bbd"]
print(count_pairs_hash_table(arr))


C#




using System;
using System.Collections.Generic;
 
class Program {
    static int CountPairsHashTable(List<string> arr)
    {
        int count = 0;
        Dictionary<string, int> stringCounts
            = new Dictionary<string, int>();
 
        // Count the occurrences of each string
        foreach(string s in arr)
        {
            if (stringCounts.ContainsKey(s)) {
                stringCounts[s]++;
            }
            else {
                stringCounts[s] = 1;
            }
        }
 
        // Compare pairs of strings for differing by exactly
        // one character
        for (int i = 0; i < arr.Count; i++) {
            for (int j = i + 1; j < arr.Count; j++) {
                int diffCount = 0;
                for (int k = 0; k < arr[i].Length; k++) {
                    if (arr[i][k] != arr[j][k]) {
                        diffCount++;
                        if (diffCount > 1) {
                            break;
                        }
                    }
                }
                if (diffCount == 1
                    && stringCounts.ContainsKey(arr[i])
                    && stringCounts.ContainsKey(arr[j])) {
                    count++;
                }
            }
        }
 
        return count;
    }
 
    static void Main()
    {
        List<string> arr
            = new List<string>{ "abc", "abd", "bbd" };
        Console.WriteLine(CountPairsHashTable(arr));
 
        Console.ReadKey();
    }
}


Javascript




function countPairsHashTable(arr) {
    let count = 0;
    let stringCounts = new Map();
 
    // Count the frequency of each string in the array
    for (let s of arr) {
        stringCounts.set(s, (stringCounts.get(s) || 0) + 1);
    }
 
    // Iterate through the array to find pairs with only one differing character
    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            let diffCount = 0;
 
            // Compare characters of the two strings
            for (let k = 0; k < arr[i].length; k++) {
                if (arr[i][k] !== arr[j][k]) {
                    diffCount++;
                    if (diffCount > 1) {
                        break;
                    }
                }
            }
 
            // If there is exactly one differing character and both
            // strings are in the map, increment the count
            if (diffCount === 1 && stringCounts.get(arr[i]) > 0 &&
                stringCounts.get(arr[j]) > 0) {
                count++;
            }
        }
    }
 
    return count;
}
 
const arr = ["abc", "abd", "bbd"];
console.log(countPairsHashTable(arr)); // Output: 2


Output

2






Time complexity: O((n^2)*m), where n is the length of the input array and m is the size of the string.

Space complexity: O(n).



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