Count of pairs of strings which differ in exactly one position
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++
#include <bits/stdc++.h>
using namespace std;
int pairCount(map<string, int > &d)
{
int sum = 0;
for ( auto i : d)
sum += (i.second * (i.second - 1)) / 2;
return sum;
}
int difference(vector<string> &array, int m)
{
map<string, int > changed, same;
for ( auto s : array)
{
same[s]++;
for ( int i = 0; i < m; i++)
{
string t = s.substr(0, i) + "//" + s.substr(i + 1);
changed[t]++;
}
}
return pairCount(changed) - pairCount(same) * m;
}
int main()
{
int n = 3, m = 3;
vector<string> array = { "abc" , "abd" , "bbd" };
cout << difference(array, m) << endl;
return 0;
}
|
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
public static int pairCount(Map<String, Integer> d)
{
int count = 0 ;
for ( int i : d.values()) {
count += (i * (i - 1 )) / 2 ;
}
return count;
}
public static int difference(String[] array, int m)
{
Map<String, Integer> changed = new HashMap<>();
Map<String, Integer> same = new HashMap<>();
for (String s : array) {
same.put(s, same.getOrDefault(s, 0 ) + 1 );
for ( int i = 0 ; i < m; i++) {
String t = s.substring( 0 , i) + "#"
+ s.substring(i + 1 );
changed.put(t,
changed.getOrDefault(t, 0 ) + 1 );
}
}
return pairCount(changed) - pairCount(same) * m;
}
public static void main(String[] args)
{
int n = 3 , m = 3 ;
String[] array = { "abc" , "abd" , "bbd" };
System.out.println(difference(array, m));
}
}
|
Python3
def pair_count(d):
return sum ((i * (i - 1 )) / / 2 for i in d.values())
def Difference(array, m):
changed, same = {}, {}
for s in array:
same[s] = same.get(s, 0 ) + 1
for i in range (m):
t = s[:i] + '#' + s[i + 1 :]
changed[t] = changed.get(t, 0 ) + 1
return pair_count(changed) - pair_count(same) * m
if __name__ = = "__main__" :
n, m = 3 , 3
array = [ "abc" , "abd" , "bbd" ]
print (Difference(array, m))
|
C#
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)
{
var changed = new Dictionary< string , int >();
var same = new Dictionary< string , int >();
foreach ( var s in array)
{
if (!same.ContainsKey(s))
{
same[s] = 1;
}
else
{
same[s]++;
}
for ( int i = 0; i < m; i++)
{
var t = s.Substring(0, i) + "#" + s.Substring(i + 1);
if (!changed.ContainsKey(t))
{
changed[t] = 1;
}
else
{
changed[t]++;
}
}
}
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));
}
}
|
Javascript
<script>
function pairCount(d)
{
let sum = 0;
for (let [i,j] of d)
sum += Math.floor((j * (j - 1)) / 2);
return sum;
}
function difference(array,m)
{
let changed = new Map(), same = new Map();
for (let s of array)
{
if (same.has(s)){
same.set(s,same.get(s)+1);
}
else same.set(s,1);
for (let i = 0; i < m; i++)
{
let t = s.substring(0, i) + "//" + s.substring(i + 1,);
if (changed.has(t)){
changed.set(t,changed.get(t)+1);
}
else changed.set(t,1);
}
}
return pairCount(changed) - pairCount(same) * m;
}
let n = 3, m = 3;
let array = [ "abc" , "abd" , "bbd" ];
document.write(difference(array, m), "</br>" );
</script>
|
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;
for ( const std::string& s : arr) {
stringCounts[s]++;
}
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<>();
for (String s : arr) {
stringCounts.put(s, stringCounts.getOrDefault(s, 0 ) + 1 );
}
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;
}
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 >();
foreach ( string s in arr)
{
if (stringCounts.ContainsKey(s)) {
stringCounts[s]++;
}
else {
stringCounts[s] = 1;
}
}
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();
for (let s of arr) {
stringCounts.set(s, (stringCounts.get(s) || 0) + 1);
}
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
let diffCount = 0;
for (let k = 0; k < arr[i].length; k++) {
if (arr[i][k] !== arr[j][k]) {
diffCount++;
if (diffCount > 1) {
break ;
}
}
}
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));
|
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
Share your thoughts in the comments
Please Login to comment...