È considerata una cattiva pratica quella di sovradimensionare un array in modo tale che gli indici negativi si comportino bene?

3

Ho praticato l'implementazione di alcuni classici algoritmi di programmazione dinamica e mi chiedevo se la mia implementazione della ricerca di sottosequenza più lunga avesse un odore significativo di codice.

In python, la mia versione del codice è la seguente:

def calculate_LCS_matrix(S, T):
    '''
    Computes the longest common subsequence of the two input strings

    Args:
        S (str): first input string
        T (str): second input string
    '''    

    # Here is the potentially offending line, I add 1 to both dimensions of the 
    # array so that the array is padded with zeroes on the bottom and right.
    # With this, negative i and j indices simply return 0 from the other side of
    # the array, as desired.
    valuestore = np.zeros((len(S)+1, len(T)+1))

    def LCS(s_char, t_char, i, j):
        '''
        Computes LCS of substrings up to index i and j
        '''

        # Without the array padding, I would have to check special cases for
        # i==0 and j==0
        if s_char == t_char:
            return valuestore[i-1, j-1] + 1
        else:
            return np.max([valuestore[i-1, j], valuestore[i, j-1]])
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            value = LCS(s,t,i,j)
            valuestore[i, j] = value

    return valuestore

Non sto cercando input sull'algoritmo stesso, solo sull'opportunità o meno di usare questo spazio a 0-padding per salvare linee di codice e potenziale confusione.

Se puoi fornire esempi specifici di dove questo potrebbe portare a problemi, lo apprezzerei molto!

Per aiutare a illustrare, il risultato dell'esecuzione della funzione calculate_LCS_matrix sulle stringhe

"AAABBBBAABB"

e

"AAABBCCAAB"

è questa matrice:

array([[ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  0.],
       [ 1.,  2.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  3.,  0.],
       [ 1.,  2.,  3.,  4.,  4.,  4.,  4.,  4.,  4.,  4.,  0.],
       [ 1.,  2.,  3.,  4.,  5.,  5.,  5.,  5.,  5.,  5.,  0.],
       [ 1.,  2.,  3.,  4.,  5.,  5.,  5.,  5.,  5.,  6.,  0.],
       [ 1.,  2.,  3.,  4.,  5.,  5.,  5.,  5.,  5.,  6.,  0.],
       [ 1.,  2.,  3.,  4.,  5.,  5.,  5.,  6.,  6.,  6.,  0.],
       [ 1.,  2.,  3.,  4.,  5.,  5.,  5.,  6.,  7.,  7.,  0.],
       [ 1.,  2.,  3.,  4.,  5.,  5.,  5.,  6.,  7.,  8.,  0.],
       [ 1.,  2.,  3.,  4.,  5.,  5.,  5.,  6.,  7.,  8.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

Il riempimento dello zero attorno ai bordi viene utilizzato durante alcune chiamate a LCS .

    
posta Tridius 03.08.2016 - 22:56
fonte

1 risposta

8

In linea di principio non vedo nulla di sbagliato in questo, se puoi permetterti lo spazio di archiviazione e ti semplifica la vita.

Ma non lo faccio personalmente in questo modo, principalmente perché il ragazzo che viene dopo di me (o me, sei mesi dopo) potrebbe pensare di poter effettivamente scrivere dati legittimi in quelle file e colonne imbottite, e ... Kaboom. Nota quanti commenti hai dovuto scrivere nel tuo codice in modo che noi potessimo capirlo abbastanza bene da rispondere alla tua domanda? Dovresti scrivere quegli stessi commenti IRL.

Quindi risolvo la logica corretta per evitare invece il bordo dell'array.

    
risposta data 04.08.2016 - 01:30
fonte

Leggi altre domande sui tag