Algorithm for certain letter combination

Asked

Viewed 87 times

1

I have the following problem, I want to know the combinations of certain letter in the string, example:

AAbA

Viraria

AAbA, AAb, Ab, bA, b

I arrived at the following code, but does not contemplate the answer, it creates combinations that should not be in the answer

def add_all_possibilities(item, nonTerminalWithEpisolon, production):
        numberNonTerminal = item.count(nonTerminalWithEpisolon)
        for i in range(numberNonTerminal + 1):
            new_production = item.replace(nonTerminalWithEpisolon, "", i)
            self._productions[production].add(new_production)
            self._productions[production].add(new_production[::-1])

Where item is the string "Aaba", nonTerminalWithEpisolon is "A" which should be the combination of that letter and Production does not matter for that part of the problem

  • Vinicius could explain the goal and how you arrived at the desired combinations?

  • It is an algorithm for Formal Languages, removal of Episolon, the idea is this: the A can be considered as an empty symbol or not, so you have to create all possible combinations of this.

1 answer

2


The function combinations, of the standard module itertools, gives you all possible combinations for a given sequence and window size:

import itertools
...
In [6]: list(itertools.combinations('AAbA', 4))
Out[6]: [('A', 'A', 'b', 'A')]

In [7]: list(itertools.combinations('AAbA', 3))
Out[7]: [('A', 'A', 'b'), ('A', 'A', 'A'), ('A', 'b', 'A'), ('A', 'b', 'A')]

In [8]: list(itertools.combinations('AAbA', 2))
Out[8]: [('A', 'A'), ('A', 'b'), ('A', 'A'), ('A', 'b'), ('A', 'A'), ('b', 'A')]

We can iterate over a string in different window sizes, remembering each unique combination:

import itertools

def pegar_combinacoes(s):
    combinacoes_unicas = set()
    # Pra diferentes tamanhos de janela...
    for i in range(1, len(s) + 1):
        # Pra cada combinação da string com esse tamanho de janela...
        for combinacao in itertools.combinations(s, i):
            # Não incluir combinações que são só 'A'
            if not all(ch == 'A' for ch in combinacao):
                # Adicionar a combinação às únicas vistas como string
                combinacoes_unicas.add(''.join(combinacao))
    return combinacoes_unicas

print(pegar_combinacoes('AAbA'))  # {'AbA', 'AAb', 'bA', 'AAbA', 'b', 'Ab'}

This method also works more generically:

print(pegar_combinacoes('AAbAc'))
# {'AbAc', 'Ac', 'Ab', 'bAc', 'AAb', 'AAbA', 'AAbc', 'b', 'bc', 'AAAc', 'bA', 'AbA', 'AAc', 'c', 'Abc', 'AAbAc'}
  • It works even, I had come to use the itertools Combinations, but it was generating more combinations too, thanks!

  • @Viniciusmacelai you weren’t using the permutations? It is more "liberal" and also generates reordering; it would generate, for example, AbAA or bAAA which are not valid in that case.

  • 2

    I saw this one too, but it was the same Combinations, I think the difference is that the Combinations parameter I passed starting from 0 and I didn’t have the point of removing the combinations that are the same letter.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.