Número de pares con Concatenación Pandigital

Se dice que un par de strings cuando se concatenan es una ‘Concatenación pandigital’ si su concatenación consta de todos los dígitos de (0 a 9) en cualquier orden al menos una vez. La tarea es, dadas N strings, calcular el número de pares que dan como resultado una ‘Concatenación pandigital’. 

Ejemplos: 

Input  : num[] = {"123567", "098234", "14765", "19804"}
Output : 3
The pairs, 1st and 2nd giving 
(123567098234),1st and 4rd giving(12356719804) and 
2nd and 3rd giving (09823414765),
on concatenation result in Pandigital Concatenations. 

Input : num[] =  {"56789", "098345", "1234"}
Output : 0
None of the pairs on concatenation result in Pandigital 
Concatenations.

Método 1 (Fuerza bruta): una posible solución de fuerza bruta es formar todas las concatenaciones posibles formando todos los pares en O(n 2 y usando una array de frecuencia para los dígitos (0 – 9), verificamos si cada dígito existe al menos una vez en cada concatenación formada para cada par. 

C++

// C++ program to find all
// Pandigital concatenations
// of two strings.
#include <bits/stdc++.h>
using namespace std;
 
// Checks if a given
// string is Pandigital
bool isPanDigital(string s)
{
    bool digits[10] = {false};
    for (int i = 0; i < s.length(); i++)
        digits[s[i] - '0'] = true;
 
    // digit i is not present
    // thus not pandigital
    for (int i = 0; i <= 9; i++)
        if (digits[i] == false)
            return false;
 
    return true;
}
 
// Returns number of pairs
// of strings resulting in
// Pandigital Concatenations
int countPandigitalPairs(vector<string> &v)
{
    // iterate over all
    // pair of strings
    int pairs = 0;
    for (int i = 0; i < v.size(); i++)
        for (int j = i + 1; j < v.size(); j++)
            if (isPanDigital(v[i] + v[j]))
                pairs++;
    return pairs;
}
 
// Driver code
int main()
{
    vector<string> v = {"123567", "098234",
                        "14765", "19804"};
    cout << countPandigitalPairs(v) << endl;
    return 0;
}

Java

// Java program to find all
// Pandigital concatenations
// of two strings.
import java.io.*;
import java.util.*;
 
class GFG
{
    static ArrayList<String> v =
                  new ArrayList<String>();
                   
    // Checks if a given
    // string is Pandigital
    static int isPanDigital(String s)
    {
        int digits[] = new int[10];
         
        for (int i = 0; i < s.length(); i++)
            digits[s.charAt(i) -
                        (int)'0'] = 1;
     
        // digit i is not present
        // thus not pandigital
        for (int i = 0; i <= 9; i++)
            if (digits[i] == 0)
                return 0;
     
        return 1;
    }
     
    // Returns number of pairs
    // of strings resulting in
    // Pandigital Concatenations
    static int countPandigitalPairs()
    {
        // iterate over all
        // pair of strings
        int pairs = 0;
        for (int i = 0; i < v.size(); i++)
            for (int j = i + 1;
                     j < v.size(); j++)
                if (isPanDigital(v.get(i) +
                                 v.get(j)) == 1)
                    pairs++;
        return pairs;
    }
     
    // Driver code
    public static void main(String args[])
    {
        v.add("123567");
        v.add("098234");
        v.add("14765");
        v.add("19804");
        System.out.print(countPandigitalPairs());
    }
}
 
// This code is contributed
// by Manish Shaw(manishshaw1)

Python3

# Python3 program to find all
# Pandigital concatenations
# of two strings.
 
# Checks if a given
# is Pandigital
def isPanDigital(s) :
 
    digits = [False] * 10;
 
    for i in range(0, len(s)) :
        digits[int(s[i]) -
               int('0')] = True
 
    # digit i is not present
    # thus not pandigital
    for i in range(0, 10) :
        if (digits[i] == False) :
            return False
 
    return True
 
# Returns number of pairs
# of strings resulting in
# Pandigital Concatenations
def countPandigitalPairs(v) :
 
    # iterate over all
    # pair of strings
    pairs = 0
    for i in range(0, len(v)) :
 
        for j in range (i + 1,
                        len(v)) :
         
            if (isPanDigital(v[i] +
                             v[j])) :
                pairs = pairs + 1
    return pairs
 
# Driver code
v = ["123567", "098234",
        "14765", "19804"]
 
print (countPandigitalPairs(v))
 
# This code is contributed by
# Manish Shaw(manishshaw1)

C#

// C# program to find all Pandigital
// concatenations of two strings.
using System;
using System.Collections.Generic;
 
class GFG
{
    // Checks if a given
    // string is Pandigital
    static int isPanDigital(string s)
    {
        int []digits = new int[10];
        Array.Clear(digits, 0, 10);
        for (int i = 0; i < s.Length; i++)
            digits[s[i] - (int)'0'] = 1;
     
        // digit i is not present
        // thus not pandigital
        for (int i = 0; i <= 9; i++)
            if (digits[i] == 0)
                return 0;
     
        return 1;
    }
     
    // Returns number of pairs
    // of strings resulting in
    // Pandigital Concatenations
    static int countPandigitalPairs(ref List<string> v)
    {
        // iterate over all
        // pair of strings
        int pairs = 0;
        for (int i = 0; i < v.Count; i++)
            for (int j = i + 1; j < v.Count; j++)
                if (isPanDigital(v[i] + v[j]) == 1)
                    pairs++;
        return pairs;
    }
     
    // Driver code
    static void Main()
    {
        List<string> v = new List<string>{"123567", "098234",
                                          "14765", "19804"};
        Console.WriteLine(countPandigitalPairs(ref v));
    }
}
 
// This code is contributed
// by Manish Shaw(manishshaw1)

PHP

<?php
// PHP program to find all
// Pandigital concatenations
// of two strings.
 
// Checks if a given
// $is Pandigital
function isPanDigital($s)
{
    $digits = array();
    $digits = array_fill(0, 10, false);
 
    for ($i = 0; $i < strlen($s); $i++)
        $digits[ord($s[$i]) -
                ord('0')] = true;
 
    // digit i is not present
    // thus not pandigital
    for ($i = 0; $i <= 9; $i++)
        if ($digits[$i] == false)
            return false;
 
    return true;
}
 
// Returns number of pairs
// of strings resulting in
// Pandigital Concatenations
function countPandigitalPairs(&$v)
{
    // iterate over all
    // pair of strings
    $pairs = 0;
    for ($i = 0;
         $i < count($v); $i++)
    {
        for ($j = $i + 1;
             $j < count($v); $j++)
        {
            if (isPanDigital($v[$i].$v[$j]))
            {
                $pairs++;
            }
        }
    }
    return $pairs;
}
 
// Driver code
$v = array("123567", "098234",
           "14765", "19804");
 
echo (countPandigitalPairs($v));
 
// This code is contributed by
// Manish Shaw(manishshaw1)
?>

Javascript

<script>
 
// Javascript program to find all
// Pandigital concatenations
// of two strings.
 
// Checks if a given
// is Pandigital
function isPanDigital(s)
{
    let digits = new Array(10).fill(false);
 
    for(let i = 0; i < s.length; i++)
        digits[s[i].charCodeAt(0) -
                '0'.charCodeAt(0)] = true;
 
    // digit i is not present
    // thus not pandigital
    for(let i = 0; i <= 9; i++)
        if (digits[i] == false)
            return false;
 
    return true;
}
 
// Returns number of pairs
// of strings resulting in
// Pandigital Concatenations
function countPandigitalPairs(v)
{
     
    // Iterate over all
    // pair of strings
    let pairs = 0;
    for(let i = 0; i < v.length; i++)
    {
        for(let j = i + 1;
                j < v.length; j++)
        {
            if (isPanDigital(v[i] + v[j]))
            {
                pairs++;
            }
        }
    }
    return pairs;
}
 
// Driver code
let v = [ "123567", "098234",
          "14765", "19804" ];
 
document.write(countPandigitalPairs(v));
 
// This code is contributed by gfgking
 
</script>

Producción: 

3

Método 2 (Eficiente): 
Ahora buscamos algo mejor que la fuerza bruta discutida anteriormente. Un análisis cuidadoso sugiere que, para que esté presente cada dígito del 0 al 9, tenemos una máscara como 1111111111 (es decir, todos los números del 0 al 9 existen en la array de números).

Digits -  0  1  2  3  4  5  6  7  8  9
          |  |  |  |  |  |  |  |  |  |
Mask   -  1  1  1  1  1  1  1  1  1  1 

Here 1 denotes that the corresponding digits
exists at-least once thus for all such Pandigital 
Concatenations, this relationship should hold.
So we can represent 11...11 as a valid mask for
pandigital concatenations.

Así que ahora el enfoque es representar cada string como una máscara de 10 bits donde el i -ésimo bit se establece si el i -ésimo dígito existe en la string. 

E.g., "11405" can be represented as
Digits -           0  1  2  3  4  5  6  7  8  9
                   |  |  |  |  |  |  |  |  |  |
Mask for 11405 -   1  1  0  0  1  1  0  0  0  0

Aunque el enfoque puede parecer completo, todavía no es eficiente, ya que todavía tenemos que iterar sobre todos los pares y verificar si el OR de estas dos strings da como resultado la máscara de una concatenación pandigital válida. 

Si analizamos las posibles máscaras de todas las strings posibles, podemos entender que cada string individual estaría compuesta solo por dígitos 0 a 9, por lo que cada número puede contener como máximo todos los dígitos 0 a 9 al menos una vez, por lo que la máscara de tal número sería sea ​​1111111111 (1023 en decimal). Así, en el sistema decimal todas las máscaras salen en (0 – 1023). 

Ahora solo tenemos que mantener una array de frecuencias para almacenar la cantidad de veces que existe una máscara en la array de strings.

Sean dos máscaras i y j con frecuencias freq i y freq j respectivamente,
Si (i O j) = Concatenación pandigital 
de máscara Entonces, 
Número de pares = freq i * freq j  

C++

// C++ program to count PanDigital pairs
#include <bits/stdc++.h>
using namespace std;
 
const int pandigitalMask = ((1 << 10) - 1);
 
void computeMaskFrequencies(vector<string> v, map<int,
                                        int>& freq)
{
    for (int i = 0; i < v.size(); i++) {
        int mask = 0;
 
        // Stores digits present in string v[i]
        // atleast once. We use a set as we only
        // need digits which exist only once
        // (irrespective of reputation)
        unordered_set<int> digits;
        for (int j = 0; j < v[i].size(); j++)
            digits.insert(v[i][j] - '0');
 
        // Calculate the mask by considering all digits
        // existing atleast once
        for (auto it = digits.begin(); it != digits.end(); it++) {
            int digit = (*it);
            mask += (1 << digit);
        }
 
        // Increment the frequency of this mask
        freq[mask]++;
    }
}
 
// Returns number of pairs of strings resulting
// in Pandigital Concatenations
int pandigitalConcatenations(map<int, int> freq)
{
    int ans = 0;
 
    // All possible strings lie between 1 and 1023
    // so we iterate over every possible mask
    for (int i = 1; i <= 1023; i++) {
        for (int j = 1; j <= 1023; j++) {
 
            // if the concatenation results in mask of
            // Pandigital Concatenation, calculate all
            // pairs formed with Masks i and j
            if ((i | j) == pandigitalMask) {
                if (i == j)
                    ans += (freq[i] * (freq[i] - 1));            
                else
                    ans += (freq[i] * freq[j]);            
            }
        }
    }
 
    // since every pair is considers twice,
    // we get rid of half of these
    return ans/2;
}
 
int countPandigitalPairs(vector<string> v)
{
    // Find frequencies of all masks in
    // given vector of strings
    map<int, int> freq;
    computeMaskFrequencies(v, freq);
     
    // Return all possible concatenations.
    return pandigitalConcatenations(freq);
}
 
// Driver code
int main()
{
    vector<string> v = {"123567", "098234", "14765", "19804"};
    cout << countPandigitalPairs(v) << endl;
    return 0;
}

Java

// Java program to count PanDigital pairs
import java.util.*;
 
class GFG{
 
static int pandigitalMask = ((1 << 10) - 1);
 
static void computeMaskFrequencies(Vector<String> v,
                         HashMap<Integer, Integer> freq)
{
    for(int i = 0; i < v.size(); i++)
    {
        int mask = 0;
 
        // Stores digits present in String v[i]
        // atleast once. We use a set as we only
        // need digits which exist only once
        // (irrespective of reputation)
        HashSet<Integer> digits = new HashSet<>();
        for(int j = 0; j < v.get(i).length(); j++)
            digits.add(v.get(i).charAt(j) - '0');
 
        // Calculate the mask by considering
        // all digits existing atleast once
        for(int it :digits)
        {
            int digit = (it);
            mask += (1 << digit);
        }
 
        // Increment the frequency of
        // this mask
        if (freq.containsKey(mask))
        {
            freq.put(mask, freq.get(mask) + 1);
        }
        else
        {
            freq.put(mask, 1);
        }
    }
}
 
// Returns number of pairs of Strings
// resulting in Pandigital Concatenations
static int pandigitalConcatenations(
    HashMap<Integer, Integer> freq)
{
    int ans = 0;
 
    // All possible Strings lie between
    // 1 and 1023 so we iterate over every
    // possible mask
    for(int i = 1; i <= 1023; i++)
    {
        for(int j = 1; j <= 1023; j++)
        {
             
            // If the concatenation results in mask of
            // Pandigital Concatenation, calculate all
            // pairs formed with Masks i and j
            if ((i | j) == pandigitalMask &&
                      freq.containsKey(j) &&
                      freq.containsKey(i))
            {
                if (i == j)
                    ans += (freq.get(i) *
                           (freq.get(i) - 1));            
                else
                    ans += (freq.get(i) *
                            freq.get(j));            
            }
        }
    }
     
    // Since every pair is considers twice,
    // we get rid of half of these
    return ans / 2;
}
 
static int countPandigitalPairs(Vector<String> v)
{
     
    // Find frequencies of all masks in
    // given vector of Strings
    HashMap<Integer,Integer> freq = new HashMap<>();
    computeMaskFrequencies(v, freq);
     
    // Return all possible concatenations.
    return pandigitalConcatenations(freq);
}
 
// Driver code
public static void main(String[] args)
{
    Vector<String> v  = new Vector<>();
    v.add("123567");
    v.add("098234");
    v.add("14765");
    v.add("19804");
     
    System.out.print(countPandigitalPairs(v) + "\n");
}
}
 
// This code is contributed by Amit Katiyar

Python3

# Python program to count PanDigital pairs
pandigitalMask = ((1 << 10) - 1)
freq = dict()
 
def computeMaskFrequencies(v):
    global freq
    for i in range(len(v)):
 
        mask = 0
 
        # Stores digits present in string v[i]
        # atleast once. We use a set as we only
        # need digits which exist only once
        # (irrespective of reputation)
        digits = set()
 
        for j in range(len(v[i])):
            digits.add(int(v[i][j]))
 
        # Calculate the mask by considering
        # all digits existing atleast once
        for it in digits:
 
            digit = it
            mask += (1 << digit)
 
        # Increment the frequency of this mask
        if mask in freq:
            freq[mask] += 1
 
        else:
            freq[mask] = 1
 
 
# Returns number of pairs of strings resulting
# in Pandigital Concatenations
def pandigitalConcatenations():
    global freq
 
    ans = 0
 
    # All possible strings lie between 1 and 1023
    # so we iterate over every possible mask
    for i in range(1, 1024):
        for j in range(1, 1024):
 
            # if the concatenation results in mask of
            # Pandigital Concatenation, calculate all
            # pairs formed with Masks i and j
            if ((i | j) == pandigitalMask and
                    i in freq and j in freq):
 
                if (i == j):
                    ans += (freq[i] * (freq[i] - 1))
                else:
                    ans += (freq[i] * freq[j])
 
    # Since every pair is considers twice,
    # we get rid of half of these
    return ans // 2
 
 
def countPandigitalPairs(v):
 
    # Find frequencies of all masks in
    # given vector of strings
    computeMaskFrequencies(v)
 
    # Return all possible concatenations.
    return pandigitalConcatenations()
 
# Driver code
v = ["123567", "098234", "14765", "19804"]
print(countPandigitalPairs(v))
 
# This code is contributed by phasing17

C#

// C# program to count
// PanDigital pairs
using System;
using System.Collections.Generic;
class GFG{
 
static int pandigitalMask =
           ((1 << 10) - 1);
 
static void computeMaskFrequencies(List<String> v,
                                   Dictionary<int,
                                   int> freq)
{
  for(int i = 0; i < v.Count; i++)
  {
    int mask = 0;
 
    // Stores digits present in String v[i]
    // atleast once. We use a set as we only
    // need digits which exist only once
    // (irrespective of reputation)
    HashSet<int> digits = new HashSet<int>();
     
    for(int j = 0; j < v[i].Length; j++)
      digits.Add(v[i][j] - '0');
 
    // Calculate the mask by considering
    // all digits existing atleast once
    foreach(int it in digits)
    {
      int digit = (it);
      mask += (1 << digit);
    }
 
    // Increment the frequency of
    // this mask
    if (freq.ContainsKey(mask))
    {
      freq[mask]++;
    }
    else
    {
      freq.Add(mask, 1);
    }
  }
}
 
// Returns number of pairs of
// Strings resulting in Pandigital
// Concatenations
static int pandigitalConcatenations(Dictionary<int,
                                    int> freq)
{
  int ans = 0;
 
  // All possible Strings lie between
  // 1 and 1023 so we iterate over every
  // possible mask
  for(int i = 1; i <= 1023; i++)
  {
    for(int j = 1; j <= 1023; j++)
    {
      // If the concatenation results in
      // mask of Pandigital Concatenation,
      // calculate all pairs formed with
      // Masks i and j
      if ((i | j) == pandigitalMask &&
          freq.ContainsKey(j) &&
          freq.ContainsKey(i))
      {
        if (i == j)
          ans += (freq[i] *
                  (freq[i] - 1));            
        else
          ans += (freq[i] *
                  freq[j]);            
      }
    }
  }
 
  // Since every pair is considers
  // twice, we get rid of half of
  // these
  return ans / 2;
}
 
static int countPandigitalPairs(List<String> v)
{   
  // Find frequencies of all masks in
  // given vector of Strings
  Dictionary<int,
             int> freq = new Dictionary<int,
                                        int>();
  computeMaskFrequencies(v, freq);
 
  // Return all possible concatenations.
  return pandigitalConcatenations(freq);
}
 
// Driver code
public static void Main(String[] args)
{
  List<String> v  = new List<String>();
  v.Add("123567");
  v.Add("098234");
  v.Add("14765");
  v.Add("19804");
  Console.Write(countPandigitalPairs(v) + "\n");
}
}
 
// This code is contributed by 29AjayKumar

Javascript

<script>
 
// Javascript program to count PanDigital pairs
const pandigitalMask = ((1 << 10) - 1);
 
function computeMaskFrequencies(v, freq)
{
    for(let i = 0; i < v.length; i++)
    {
        let mask = 0;
 
        // Stores digits present in string v[i]
        // atleast once. We use a set as we only
        // need digits which exist only once
        // (irrespective of reputation)
        let digits = new Set();
        for(let j = 0; j < v[i].length; j++)
            digits.add((v[i][j]).charCodeAt(0) -
                             '0'.charCodeAt(0));
 
        // Calculate the mask by considering
        // all digits existing atleast once
        for(let it of digits)
        {
            let digit = it;
            mask += (1 << digit);
        }
 
        // Increment the frequency of this mask
        if (freq.has(mask))
        {
            freq.set(mask, freq.get(mask) + 1)
        }
        else
        {
            freq.set(mask, 1)
        }
    }
}
 
// Returns number of pairs of strings resulting
// in Pandigital Concatenations
function pandigitalConcatenations(freq)
{
    let ans = 0;
 
    // All possible strings lie between 1 and 1023
    // so we iterate over every possible mask
    for(let i = 1; i <= 1023; i++)
    {
        for(let j = 1; j <= 1023; j++)
        {
             
            // if the concatenation results in mask of
            // Pandigital Concatenation, calculate all
            // pairs formed with Masks i and j
            if ((i | j) == pandigitalMask &&
                freq.has(i) && freq.has(j))
            {
                if (i == j)
                    ans += (freq.get(i) *
                           (freq.get(i) - 1));
                else
                    ans += (freq.get(i) *
                            freq.get(j));
            }
        }
    }
 
    // Since every pair is considers twice,
    // we get rid of half of these
    return Math.floor(ans / 2);
}
 
function countPandigitalPairs(v)
{
     
    // Find frequencies of all masks in
    // given vector of strings
    let freq = new Map();
    computeMaskFrequencies(v, freq);
 
    // Return all possible concatenations.
    return pandigitalConcatenations(freq);
}
 
// Driver code
let v = [ "123567", "098234", "14765", "19804" ];
document.write(countPandigitalPairs(v) + "<br>");
 
// This code is contributed by gfgking
 
</script>

Producción:  

3

Complejidad : O(N * |s| + 1023 * 1023) donde |s| da la longitud de las strings en la array
 

Publicación traducida automáticamente

Artículo escrito por sirjan13 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *