Data una stringa di un milione di numeri, restituisce tutti i numeri a 3 cifre ripetuti


137

Ho avuto un'intervista con una società di hedge fund a New York qualche mese fa e, sfortunatamente, non ho ricevuto l'offerta di tirocinio come ingegnere informatico / software. (Hanno anche chiesto che la soluzione fosse in Python.)

Ho praticamente incasinato il primo problema dell'intervista ...

Domanda: data una stringa di un milione di numeri (ad esempio Pi), scrivere una funzione / programma che restituisca tutti i numeri a 3 cifre ripetuti e il numero di ripetizioni maggiore di 1

Ad esempio: se la stringa fosse: 123412345123456allora la funzione / programma restituirebbe:

123 - 3 times
234 - 3 times
345 - 2 times

Non mi hanno dato la soluzione dopo aver fallito l'intervista, ma mi hanno detto che la complessità temporale della soluzione era costante di 1000 poiché tutti i possibili risultati sono tra:

000 -> 999

Ora che ci sto pensando, non penso che sia possibile elaborare un algoritmo a tempo costante. È?


68
Se pensano che la soluzione sia una costante di 1000, allora questo mi fa pensare che avrebbero costruito tutti i numeri a tre cifre e quindi regex li ha cercati. È molto comune per le persone pensare che le operazioni che in realtà non hanno scritto / visto siano "gratuite". Sono abbastanza sicuro che questo sarebbe lineare rispetto alla lunghezza della stringa.
mypetlion il

54
Incredibilmente, se la dimensione dell'input è una costante, ogni algoritmo è un tempo costante ;-)
Paŭlo Ebermann

34
una costante di 1000 cosa ? (aggiunte? elefanti?)
ilkkachu

31
Bene, se la lunghezza della stringa è costante (1M) e la lunghezza della sottostringa / numero è costante (3), tecnicamente ogni soluzione è tempo costante ...
Kevin

8
They did not give me the solution after I failed the interview, but they did tell me that the time complexity for the solution was constant of 1000 since all the possible outcomes are between: 000 --> 999 Questo era probabilmente il test vero e proprio. Per vedere se potresti dimostrare loro perché ciò non è possibile e mostrare loro la complessità temporale minima corretta.
James,

Risposte:


168

Sei sceso alla leggera, probabilmente non vuoi lavorare per un hedge fund in cui i quants non comprendono gli algoritmi di base :-)

Non v'è alcun modo per elaborare una struttura di dati arbitrariamente dimensioni in O(1)se, come in questo caso, è necessario visitare ogni elemento almeno una volta. Il meglio che puoi sperare è O(n)in questo caso, dov'è nla lunghezza della stringa.

Sebbene, a parte, un O(n)algoritmo nominale sarà essere O(1)per una dimensione fissa ingresso così, tecnicamente, essi possono essere stati corretti qui. Tuttavia, di solito non è così che le persone usano l'analisi della complessità.

Mi sembra che potresti averli colpiti in molti modi.

Innanzitutto, informandoli che lo è non è possibile farlo, a O(1)meno che non si usi il ragionamento "sospetto" di cui sopra.

In secondo luogo, mostrando le tue abilità d'élite fornendo codice Pythonic come:

inpStr = '123412345123456'

# O(1) array creation.
freq = [0] * 1000

# O(n) string processing.
for val in [int(inpStr[pos:pos+3]) for pos in range(len(inpStr) - 2)]:
    freq[val] += 1

# O(1) output of relevant array values.
print ([(num, freq[num]) for num in range(1000) if freq[num] > 1])

Questo produce:

[(123, 3), (234, 3), (345, 2)]

anche se, ovviamente, potresti modificare il formato di output in base a ciò che desideri.

E, infine, dicendo loro che non c'è quasi nessun problema con unO(n) soluzione, poiché il codice sopra fornisce risultati per una stringa da un milione di cifre in meno di mezzo secondo. Sembra ridimensionare in modo abbastanza lineare, poiché una stringa di 10.000.000 di caratteri impiega 3,5 secondi e una di 100.000.000 di caratteri impiega 36 secondi.

E, se ne hanno bisogno meglio, ci sono modi per parallelizzare questo tipo di cose che possono accelerare notevolmente.

Ovviamente non all'interno di un singolo interprete Python, a causa di GIL, ma potresti dividere la stringa in qualcosa del genere ( vvè necessaria la sovrapposizione indicata da per consentire una corretta elaborazione delle aree di confine):

    vv
123412  vv
    123451
        5123456

Puoi coltivarli per separare i lavoratori e combinare i risultati in seguito.

La suddivisione dell'input e la combinazione dell'output rischiano di inondare qualsiasi salvataggio con stringhe di piccole dimensioni (e forse anche stringhe da un milione di cifre) ma, per set di dati molto più grandi, potrebbe fare la differenza. Il mio solito mantra di "misura, non indovinare" si applica qui, ovviamente.


Questo mantra si applica anche ad altre possibilità, come bypassare del tutto Python e usare un linguaggio diverso che potrebbe essere più veloce.

Ad esempio, il seguente codice C, in esecuzione sullo stesso hardware del precedente codice Python, gestisce un centinaio di milioni di cifre in 0,6 secondi, all'incirca la stessa quantità di tempo del codice Python elaborato un milione. In altre parole, molto più veloce:

#include <stdio.h>
#include <string.h>

int main(void) {
    static char inpStr[100000000+1];
    static int freq[1000];

    // Set up test data.

    memset(inpStr, '1', sizeof(inpStr));
    inpStr[sizeof(inpStr)-1] = '\0';

    // Need at least three digits to do anything useful.

    if (strlen(inpStr) <= 2) return 0;

    // Get initial feed from first two digits, process others.

    int val = (inpStr[0] - '0') * 10 + inpStr[1] - '0';
    char *inpPtr = &(inpStr[2]);
    while (*inpPtr != '\0') {
        // Remove hundreds, add next digit as units, adjust table.

        val = (val % 100) * 10 + *inpPtr++ - '0';
        freq[val]++;
    }

    // Output (relevant part of) table.

    for (int i = 0; i < 1000; ++i)
        if (freq[i] > 1)
            printf("%3d -> %d\n", i, freq[i]);

    return 0;
}

19
Questa "dimensione di input fissa" sembra davvero una brutta battuta che l'intervistatore o l'intervistato non hanno capito. Ogni algoritmo diventa O(1)si nè fisso o delimitato.
Eric Duminil,

5
Se hanno bisogno di meglio, forse non dovrebbero usare Python, almeno per l'algoritmo specifico.
Sebastian Redl,

3
@ezzzCash Perché potrebbe esserci una sovrapposizione nei punti in cui la stringa viene "spezzata" quando si tenta un approccio parallelo. Poiché stai cercando gruppi a 3 cifre, -2 consente al controllo su entrambi i gruppi paralleli di non perdere una corrispondenza potenzialmente valida.
code_dredd

5
@ezzzCash Non mancano le conoscenze di programmazione parallela. Considera una stringa di lunghezza N. Se lo dividi in due parti in posizione N/2, devi comunque tenere conto del fatto che potresti perdere una corrispondenza valida di 3 cifre al "bordo", alla fine string1e all'inizio di string2. Pertanto, è necessario controllare le corrispondenze tra string1[N/2-2]e string2[2](utilizzando un indice a base zero), ecc. Questa è l'idea.
code_dredd

1
Con sequenze di cifre più lunghe, ci sarebbe qualcosa da guadagnare dall'ottimizzazione della conversione in numero intero con una finestra scorrevole che consente di rilasciare la cifra più alta e aggiungere una nuova cifra. (L'overhead di Python probabilmente ucciderebbe questo, quindi si applicherebbe solo a C o ad altre implementazioni di basso livello). val -= 100 * (d[i]-'0');per rilasciare la cifra iniziale. val = 10*val + d[i+2]-'0'per accumulare una nuova cifra meno significativa (normale analisi stringa> intero). val % 100è probabilmente non orribile, ma solo se 100è una costante di tempo di compilazione, quindi non utilizza un vero divario HW.
Peter Cordes,

78

Il tempo costante non è possibile. Tutte le 1 milione di cifre devono essere esaminate almeno una volta, quindi questa è una complessità temporale di O (n), in cui n = 1 milione in questo caso.

Per una soluzione O (n) semplice, creare un array di dimensioni 1000 che rappresenti il ​​numero di occorrenze di ogni possibile numero di 3 cifre. Avanza di 1 cifra alla volta, primo indice == 0, ultimo indice == 999997 e matrice di incremento [numero di 3 cifre] per creare un istogramma (conteggio delle occorrenze per ogni possibile numero di 3 cifre). Quindi emettere il contenuto dell'array con conteggi> 1.


26
@ezzzCash: sì, un dizionario funzionerebbe, ma non è necessario. Tutte le possibili "chiavi" sono note in anticipo, limitatamente all'intervallo da 0 a 999. La differenza nell'overhead sarebbe il tempo necessario per eseguire un accesso basato sulle chiavi utilizzando 3 stringhe di caratteri come chiavi, rispetto al tempo necessario per convertire un 3 digitare la stringa in un indice e quindi utilizzare l'indice per accedere all'array.
rcgldr,

4
Se vuoi trucchi numerici, puoi anche decidere di passare a BCD e memorizzare le tre cifre in 12 bit. E decodifica le cifre ASCII mascherando i 4 bit bassi. Ma quel x-'0'pattern non è valido in Python, è un C-ism (dove i caratteri sono numeri interi).
Yann Vernier,

5
@LorenPechtel: le ricerche nel dizionario in Python sono molto veloci. Concesso, l'accesso all'array è ancora più veloce, quindi se avessimo a che fare con numeri interi dall'inizio, avresti ragione. Tuttavia, in questo caso, abbiamo stringhe di 3 lunghezze, che per prima cosa dobbiamo convertire in numeri interi se vogliamo usarle con le matrici. Si scopre che contrariamente a quanto ci si potrebbe aspettare, la ricerca del dizionario è in realtà più veloce della conversione intera + accesso all'array. In questo caso la soluzione array è infatti più lenta del 50%.
Aleksi Torhamo,

2
Immagino si possa sostenere che se il numero di input ha sempre esattamente 1 milione di cifre, allora l'algoritmo è O (1), con un fattore costante di 1 milione.
tobias_k,

2
@AleksiTorhamo - Se l'obiettivo è confrontare le velocità relative delle implementazioni per un algoritmo, preferirei un linguaggio tradizionale come C o C ++, dal momento che Python è significativamente più lento e sembra avere costi generali unici di Python rispetto ad altre lingue.
rcgldr,

14

Un milione è piccolo per la risposta che fornisco di seguito. Prevedendo solo che devi essere in grado di eseguire la soluzione nell'intervista, senza una pausa, quindi Quanto segue funziona in meno di due secondi e fornisce il risultato richiesto:

from collections import Counter

def triple_counter(s):
    c = Counter(s[n-3: n] for n in range(3, len(s)))
    for tri, n in c.most_common():
        if n > 1:
            print('%s - %i times.' % (tri, n))
        else:
            break

if __name__ == '__main__':
    import random

    s = ''.join(random.choice('0123456789') for _ in range(1_000_000))
    triple_counter(s)

Spero che l'intervistatore sia alla ricerca dell'uso delle raccolte di librerie standard. Classe di confronto.

Versione di esecuzione parallela

Ho scritto un post sul blog con ulteriori spiegazioni.


Funziona bene e sembra essere la soluzione più veloce, non intorpidita.
Eric Duminil,

3
@EricDuminil, non credo che dovresti preoccuparti di avere gli orari dei fastet qui, quando la maggior parte delle soluzioni fornite non ti ritarderà molto. Molto meglio per dimostrare che hai una buona conoscenza della libreria standard di Python e puoi scrivere codice gestibile in una situazione di intervista, penso. (A meno che l'intervistatore non abbia sottolineato la criticità temporale in base alla quale dovresti chiedere i tempi effettivi prima di valutare ciò che verrà dopo).
Paddy3118,

1
Siamo d'accordo al 100%. Anche se non sono sicuro che una risposta sia pertinente se l'intervistatore pensa davvero che sia possibile farlo O(1).
Eric Duminil,

1
Se l'intervistatore ha sottolineato che è stato un momento critico, quindi, dopo aver profilato per confermare che questo è il limite, potrebbe essere il momento di scrivere un modulo C per affrontare questo collo di bottiglia. Ho uno script che ha visto un miglioramento di 84x rispetto al codice Python dopo essere passati all'utilizzo del modulo ac.
TemporalWolf

Ciao @TemporalWolf, ho letto quello che hai detto, poi ho pensato che un'altra soluzione, più veloce e scalabile potrebbe essere quella di cambiarlo in un algoritmo parallelo in modo che possa essere eseguito su molti processi in una farm / cloud di calcolo. Devi dividere la stringa in n sezioni; sovrapponendo gli ultimi 3 caratteri di ogni sezione con la sezione successiva. Ogni sezione può quindi essere scansionata per le triple in modo indipendente, le triple vengono sommate e le tre triple di carattere alla fine di tutte, ma l'ultima sezione viene sottratta come se fosse stata contata due volte. Ho il codice e probabilmente lo trasformerò in un post sul blog ...
Paddy3118,

13

La semplice soluzione O (n) sarebbe quella di contare ogni numero di 3 cifre:

for nr in range(1000):
    cnt = text.count('%03d' % nr)
    if cnt > 1:
        print '%03d is found %d times' % (nr, cnt)

Ciò cercherebbe tra tutte le 1 milione di cifre 1000 volte.

Attraversare le cifre una sola volta:

counts = [0] * 1000
for idx in range(len(text)-2):
    counts[int(text[idx:idx+3])] += 1

for nr, cnt in enumerate(counts):
    if cnt > 1:
        print '%03d is found %d times' % (nr, cnt)

Il tempismo mostra che l'iterazione solo una volta sull'indice è due volte più veloce dell'uso count.


37
C'è uno sconto del venerdì nero su text.count()?
Eric Duminil,

3
@EricDuminil Hai un buon punto ma, dato che text.countè fatto in un linguaggio compilato ad alta velocità (ad es. C) rispetto al lento ciclo interpretato a livello di pitone, sì, c'è uno sconto.
Giovanni 1024

È molto inefficiente contare ogni numero separatamente ma è un tempo costante, quindi ancora O (n).
Loren Pechtel,

11
L'opzione che hai proposto che utilizza countnon è corretta, poiché non conterà i motivi sovrapposti. Si noti che '111'.count('11') == 1quando ci aspettiamo che sia 2.
Cireo,

2
Inoltre, la tua " O(n)soluzione semplice " è in realtà O(10**d * n)con dil numero di cifre cercate e nla lunghezza totale della stringa. Il secondo è il O(n)tempo e lo O(10**d + n)spazio.
Eric Duminil,

10

Ecco un'implementazione NumPy dell'algoritmo O (n) "consensus": cammina attraverso tutte le terzine e raccogli mentre procedi. Il binning viene effettuato quando si incontra "385", aggiungendo uno al bin [3, 8, 5] che è un'operazione O (1). I contenitori sono disposti in un 10x10x10cubo. Dato che il binning è completamente vettorizzato, non vi è alcun loop nel codice.

def setup_data(n):
    import random
    digits = "0123456789"
    return dict(text = ''.join(random.choice(digits) for i in range(n)))

def f_np(text):
    # Get the data into NumPy
    import numpy as np
    a = np.frombuffer(bytes(text, 'utf8'), dtype=np.uint8) - ord('0')
    # Rolling triplets
    a3 = np.lib.stride_tricks.as_strided(a, (3, a.size-2), 2*a.strides)

    bins = np.zeros((10, 10, 10), dtype=int)
    # Next line performs O(n) binning
    np.add.at(bins, tuple(a3), 1)
    # Filtering is left as an exercise
    return bins.ravel()

def f_py(text):
    counts = [0] * 1000
    for idx in range(len(text)-2):
        counts[int(text[idx:idx+3])] += 1
    return counts

import numpy as np
import types
from timeit import timeit
for n in (10, 1000, 1000000):
    data = setup_data(n)
    ref = f_np(**data)
    print(f'n = {n}')
    for name, func in list(globals().items()):
        if not name.startswith('f_') or not isinstance(func, types.FunctionType):
            continue
        try:
            assert np.all(ref == func(**data))
            print("{:16s}{:16.8f} ms".format(name[2:], timeit(
                'f(**data)', globals={'f':func, 'data':data}, number=10)*100))
        except:
            print("{:16s} apparently crashed".format(name[2:]))

Non sorprende che NumPy sia un po 'più veloce della pura soluzione Python di @ Daniel su grandi set di dati. Uscita campione:

# n = 10
# np                    0.03481400 ms
# py                    0.00669330 ms
# n = 1000
# np                    0.11215360 ms
# py                    0.34836530 ms
# n = 1000000
# np                   82.46765980 ms
# py                  360.51235450 ms

Probabilmente significativamente più veloce per appiattire la stringa di cifre invece di disporre di bin nidificati, a meno che NumPy non finisca per implementarla come matrice 3D con un'indicizzazione efficiente. Contro quale versione di @ Daniel hai passato del tempo; quello che esegue una ricerca di stringhe per ogni numero intero o quello con un istogramma?
Peter Cordes,

2
@PeterCordes Ne dubito. ndarrays, il tipo di intorpidimento di base, riguardano l'archiviazione, la manipolazione e l'indicizzazione efficienti di matrici multidimensionali di numeri. A volte puoi radere qualche% appiattendoti, ma in questo caso fare 100 x [0] + 10 x [1] + x [2] a mano non ti farà guadagnare molto. Ho usato quello che @Daniel ha detto che era più veloce, puoi controllare tu stesso il codice di riferimento.
Paul Panzer,

Non conosco davvero NumPy (o Python in generale; principalmente faccio C e tuning delle prestazioni dell'assembly per x86), ma penso che tu abbia un singolo array 3D, giusto? Stavo pensando al tuo testo inglese (che apparentemente non avevo nemmeno letto attentamente) che avevi veri e propri oggetti Python nidificati e li indicizzavi separatamente. Ma non è così, quindi nvm il mio primo commento.
Peter Cordes,

Penso che la versione pura di Python che hai usato sia praticamente la stessa implementazione dell'istogramma utilizzata dalle risposte votate ancora più alte, ma se diversi modi di scriverla in Python influiscono molto sulla velocità.
Peter Cordes,

3

Vorrei risolvere il problema come segue:

def find_numbers(str_num):
    final_dict = {}
    buffer = {}
    for idx in range(len(str_num) - 3):
        num = int(str_num[idx:idx + 3])
        if num not in buffer:
            buffer[num] = 0
        buffer[num] += 1
        if buffer[num] > 1:
            final_dict[num] = buffer[num]
    return final_dict

Applicato alla stringa di esempio, questo produce:

>>> find_numbers("123412345123456")
{345: 2, 234: 3, 123: 3}

Questa soluzione gira in O (n) perché n è la lunghezza della stringa fornita ed è, immagino, la migliore che puoi ottenere.


Potresti semplicemente usare a Counter. Non è necessario un final_dicte non è necessario aggiornarlo ad ogni iterazione.
Eric Duminil,

2

Secondo la mia comprensione, non puoi avere la soluzione in un tempo costante. Ci vorrà almeno un passaggio sul numero di milioni di cifre (supponendo che sia una stringa). È possibile avere un'iterazione progressiva a 3 cifre sulle cifre del numero della lunghezza di un milione e aumentare il valore della chiave hash di 1 se esiste già o creare una nuova chiave hash (inizializzata dal valore 1) se non esiste già in il dizionario.

Il codice sarà simile al seguente:

def calc_repeating_digits(number):

    hash = {}

    for i in range(len(str(number))-2):

        current_three_digits = number[i:i+3]
        if current_three_digits in hash.keys():
            hash[current_three_digits] += 1

        else:
            hash[current_three_digits] = 1

    return hash

Puoi filtrare fino alle chiavi che hanno un valore di elemento maggiore di 1.


2

Come indicato in un'altra risposta, non è possibile eseguire questo algoritmo in tempo costante, poiché è necessario esaminare almeno n cifre. Il tempo lineare è il più veloce che puoi ottenere.

Tuttavia, l'algoritmo può essere eseguito nello spazio O (1) . Devi solo memorizzare i conteggi di ciascun numero di 3 cifre, quindi hai bisogno di un array di 1000 voci. È quindi possibile eseguire lo streaming del numero.

La mia ipotesi è che o l'intervistatore ha sbagliato a parlare quando ti hanno dato la soluzione, o hai sentito "tempo costante" quando hanno detto "spazio costante".


Come altri hanno sottolineato, l'approccio dell'istogramma è O(10**d)uno spazio aggiuntivo, dove si dtrova il numero di cifre decimali che stai cercando.
Peter Cordes,

1
L'approccio del dizionario sarebbe O (min (10 ^ d, n)) per n cifre. Ad esempio se hai n = 10 ^ 9 cifre e vuoi trovare le rare sequenze di 15 cifre che si verificano più di una volta.
gnasher729,

1

Ecco la mia risposta:

from timeit import timeit
from collections import Counter
import types
import random

def setup_data(n):
    digits = "0123456789"
    return dict(text = ''.join(random.choice(digits) for i in range(n)))


def f_counter(text):
    c = Counter()
    for i in range(len(text)-2):
        ss = text[i:i+3]
        c.update([ss])
    return (i for i in c.items() if i[1] > 1)

def f_dict(text):
    d = {}
    for i in range(len(text)-2):
        ss = text[i:i+3]
        if ss not in d:
            d[ss] = 0
        d[ss] += 1
    return ((i, d[i]) for i in d if d[i] > 1)

def f_array(text):
    a = [[[0 for _ in range(10)] for _ in range(10)] for _ in range(10)]
    for n in range(len(text)-2):
        i, j, k = (int(ss) for ss in text[n:n+3])
        a[i][j][k] += 1
    for i, b in enumerate(a):
        for j, c in enumerate(b):
            for k, d in enumerate(c):
                if d > 1: yield (f'{i}{j}{k}', d)


for n in (1E1, 1E3, 1E6):
    n = int(n)
    data = setup_data(n)
    print(f'n = {n}')
    results = {}
    for name, func in list(globals().items()):
        if not name.startswith('f_') or not isinstance(func, types.FunctionType):
            continue
        print("{:16s}{:16.8f} ms".format(name[2:], timeit(
            'results[name] = f(**data)', globals={'f':func, 'data':data, 'results':results, 'name':name}, number=10)*100))
    for r in results:
        print('{:10}: {}'.format(r, sorted(list(results[r]))[:5]))

Il metodo di ricerca dell'array è molto veloce (anche più veloce del metodo numpy di @ paul-panzer!). Naturalmente, imbroglia poiché non è tecnicamente finito dopo il completamento, perché restituisce un generatore. Inoltre, non è necessario controllare ogni iterazione se il valore esiste già, il che probabilmente aiuterà molto.

n = 10
counter               0.10595780 ms
dict                  0.01070654 ms
array                 0.00135370 ms
f_counter : []
f_dict    : []
f_array   : []
n = 1000
counter               2.89462101 ms
dict                  0.40434612 ms
array                 0.00073838 ms
f_counter : [('008', 2), ('009', 3), ('010', 2), ('016', 2), ('017', 2)]
f_dict    : [('008', 2), ('009', 3), ('010', 2), ('016', 2), ('017', 2)]
f_array   : [('008', 2), ('009', 3), ('010', 2), ('016', 2), ('017', 2)]
n = 1000000
counter            2849.00500992 ms
dict                438.44007806 ms
array                 0.00135370 ms
f_counter : [('000', 1058), ('001', 943), ('002', 1030), ('003', 982), ('004', 1042)]
f_dict    : [('000', 1058), ('001', 943), ('002', 1030), ('003', 982), ('004', 1042)]
f_array   : [('000', 1058), ('001', 943), ('002', 1030), ('003', 982), ('004', 1042)]

1
Quindi cosa stai confrontando esattamente? Non dovresti restituire elenchi invece di generatori inutilizzati?
Eric Duminil,

Countersnon sono usati in questo modo. Utilizzati correttamente, diventano l'opzione più veloce con il tuo esempio. Se si utilizza timeitun elenco installato di un generatore, il metodo diventa più lento di Countero dict. Vedi qui .
Eric Duminil,

Infine, f_arraypotresti essere più veloce se prima convertissi ogni carattere in un int: ints = [int(c) for c in text]e poi lo usi i, j, k = ints[n:n+3].
Eric Duminil,


1

Ecco la mia soluzione:

from collections import defaultdict
string = "103264685134845354863"
d = defaultdict(int)
for elt in range(len(string)-2):
    d[string[elt:elt+3]] += 1
d = {key: d[key] for key in d.keys() if d[key] > 1}

Con un po 'di creatività in for loop (e un elenco di ricerca aggiuntivo con True / False / None per esempio) dovresti essere in grado di sbarazzarti dell'ultima riga, poiché vuoi solo creare chiavi in ​​dict che abbiamo visitato una volta fino a quel punto . Spero che sia d'aiuto :)


Vedi la risposta di pho7 . E commenti. Prova a capire perché non ottiene molti voti.
Barbabianca il

0

-Scrivere dalla prospettiva di C. -Puoi avere un int 3-d array risultati [10] [10] [10]; -Vai dalla posizione 0 alla posizione n-4, dove n è la dimensione dell'array di stringhe. -In ogni posizione, controlla l'attuale, il prossimo e il prossimo è il prossimo. -Incrementa il cntr come resutls [current] [next] [next's next] ++; -Stampare i valori di

results[1][2][3]
results[2][3][4]
results[3][4][5]
results[4][5][6]
results[5][6][7]
results[6][7][8]
results[7][8][9]

-È O (n) tempo, non ci sono confronti coinvolti. -È possibile eseguire alcune cose parallele qui partizionando l'array e calcolando le corrispondenze attorno alle partizioni.


-1
inputStr = '123456123138276237284287434628736482376487234682734682736487263482736487236482634'

count = {}
for i in range(len(inputStr) - 2):
    subNum = int(inputStr[i:i+3])
    if subNum not in count:
        count[subNum] = 1
    else:
        count[subNum] += 1

print count

Grazie per la tua risposta, ma è troppo simile a un algoritmo come è stato dato da @abhishek arora 5-6 giorni fa. Inoltre, la domanda originale non era quella di chiedere l'algoritmo ma piuttosto una domanda diversa (a cui era già stata data risposta più volte)
its.david
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.