C'è una matrice indicizzata da 0-n
(cioè size = n) contenente elementi da 0-m
dove m < n
(supponiamo m è 100 o 1000 volte minore di n ie m è molto minore di n) , quindi molti degli elementi o sottoarray devono essere ripetuti e dobbiamo trovare il numero di tale sub array ripetuto di dimensione 1 o maggiore di 1. Ad esempio, considerare un array
1 2 4 1 2 4 1 5 6 3 5
, qui
1
viene ripetuto 2 volte
2
si ripete 1 volta
4
si ripete 1 volta
5
viene ripetuto 1 volta
1 2
viene ripetuto 1 volta
2 4
si ripete 1 volta
4 1
viene ripetuta 1 volta
1 2 4
viene ripetuto 1 volta
2 4 1
viene ripetuto 1 volta
1 2 4 1
si ripete 1 volta
Quindi la risposta finale è la somma di questi, ad esempio 11
Qualcuno può suggerire una struttura dati o un algoritmo efficiente per risolvere questo problema. Stavo pensando all'hashing e all'individuazione del valore dell'indice dove si verifica ma non lo ha formalizzato.
Assumere n,m < 10^5
Trova il numero di subarray ripetuto in una matrice
risposta
Creare un hash con numeri interi come chiavi ed elenchi estendibili (elenchi concatenati, ad esempio) di numeri interi come valori.
Leggere l'elenco di input. Tratta ogni elemento di input scansionato come una chiave; aggiungere l'indice del seguente elemento all'elenco di valori associato.
Ora, il numero ripetuto di 1 elemento è n - | keys |
Quindi, passa le chiavi. Per ogni chiave, considera gli elementi indicizzati dell'elenco originale come una nuova lista di input. Crea un nuovo hash e continua come al punto 1.Si noti che quando memorizziamo gli indici continuiamo a utilizzare quelli dell'elenco originale.
Esempio: 1 2 4 1 2 4 1 5 6 3 5 (supponiamo di avere un indice zero). Qui, n = 11.
- 1 -> [1, 4, 7]
- 2 -> [2, 5]
- 3 -> [10]
- 4 -> [3, 6]
- 5 -> [8, nil]
- 6 -> [9]
Il numero di ripetute 1-PFU è di 11 - 6 = 5.
Ora, passiamo attraverso le chiavi. Iniziamo con 1. La lista degli indici è [1, 4, 7] che corrisponde agli elementi [2, 2, 5].
- 2 -> [2, 5]
- 5 -> [8]
Questa raccoglie 3 - 2 = 1 duplicato elenco 2 elementi.
ecc ...
Durata: lineare in ingresso + uscita
Questo è un approccio innovativo. Per gli elementi non-1, se gli indici non sono uno accanto all'altro, allora non fanno parte di un modello! Molto bella! – lsk
.......... bello! –
Ho usato un approccio basato sugli alberi di suffisso, da Skienna's book on the design of algorithms. Gli alberi suffissi sono un tipo speciale di trie tree, in cui si inserisce ogni suffisso della stringa data nell'albero trie. Gli alberi Trie sono un modo per memorizzare più parole in un singolo albero: la radice è la stringa nulla e ogni lato aggiunge un carattere. Di seguito ho utilizzato un'implementazione molto semplice come prova del concetto.
#include <iostream>
#include <string>
using std::string;
using std::cout;
class Node
{
Node* m_descendants[10];
int m_count;
public:
Node()
{
for(int i=0; i<10; ++i) { m_descendants[i] = nullptr; }
m_count = 0;
}
void Add(const char* str) {
// Increment number of times we've reached this node
m_count++;
const int firstDigit = str[0] - '0';
if (!(0 <= firstDigit && firstDigit <= 9)) return; // recursion base case
// Access descendant node correponding to current digit
Node*& descendant = m_descendants[firstDigit];
if (descendant == 0) { // create descendant if necessary
descendant = new Node;
}
// Recurse on rest of string
descendant->Add(str +1);
}
void Print(const string& str, int countAdj=0) const // debug function
{
for(int nextDigit=0; nextDigit<10; ++nextDigit) {
const Node* node = m_descendants[nextDigit];
if (node) {
const int adjustedCount = node->Count() - countAdj;
if (adjustedCount > 0) {
char c = '0' + nextDigit;
string strWithC = str;
strWithC += c;
cout << strWithC << ": " << adjustedCount << "\n";
node->Print(strWithC, countAdj);
}
}
}
}
int SumRepeated() const
{
int sumRepeated = 0;
for(int nextDigit=0; nextDigit<10; ++nextDigit) {
const Node* node = m_descendants[nextDigit];
if (node) {
const int repeatCount = node->Count() -1;
if (repeatCount > 0) {
sumRepeated += repeatCount;
sumRepeated += node->SumRepeated();
}
}
}
return sumRepeated;
}
int Count() const { return m_count; }
};
int main(int argc, const char* argv[])
{
// Construct
Node* const root = new Node;
for(const char* str = "12412415635"; *str; ++str) {
root->Add(str);
}
// Print
root->Print(string(), 1);
cout << "Sum repeated is " << root->SumRepeated() << "\n";
return 0; // (nodes are leaked)
}
uscita
1: 2
12: 1
124: 1
1241: 1
2: 1
24: 1
241: 1
4: 1
41: 1
5: 1
Sum repeated is 11
Nota v'è un ulteriore sottostringa ripetuto qui, vale a dire 1241.
Come ho già detto, questa è la prova di concetto, così, per esempio, che ci si vuole utilizzare un dizionario invece di una matrice per memorizzare i discendenti, con più grande m
. Inoltre, questa implementazione non è ottimale nemmeno in termini di algoritmo complessivo: è O (n^2) nel tempo e nello spazio. Puoi ottimizzare cracciando i percorsi senza branching per ottenere lo spazio O (n) e utilizzare algoritmi di costruzione intelligenti per ottenere il tempo O (n). Inoltre, come indicato in una delle altre risposte, non è necessario elaborare stringhe secondarie di lunghezza pari a metà della lunghezza dell'originale.
ecco qualcosa in JavaScript: (uscita è più o meno immediato e JavaScript è una delle più lente, credo):
<script>
function f (s, m) {
var i = 0, n = s.length, c = 0, H = {}, Hi = {}
while (i < n-1) {
for (var j=i+1; j<=Math.min (i + 1 + m,n - 1); j++) {
if (s[i] == s[j]) {
var i_= i, j_= j, tmp = ''
while (s[i_] == s[j_] && i_ < j) {
tmp += String (s[i_])
i_++
j_++
}
var k = tmp.length - 1
while (k >= 0) {
if (!H[tmp]) {
H[tmp] = 1
Hi[tmp] = i
c++
}
else if (i == Hi[tmp]) {
H[tmp]++
c++
}
tmp = tmp.substr(0,k--)
}
}
}
i++
}
var t1 = ''
for (var i in H) t1 += i + ", "
return [t1,c]
}
var a1 = [1,2,4,1,2,4,1,5,6,3,5],
a2 = []
for (var i=0;i<100000;i++) a2.push(Math.floor(Math.random()*10))
console.log(a1 +"\n"+ f(a1,10))
console.log(f(a2,10))
</script>
uscita:
1,2,4,1,2,4,1,5,6,3,5
1, 2, 4, 5, 12, 24, 41, 124, 241, ,10
["0...6358, 3582, 038, 4304, 2068, 095,
9252, 37866, 3786, 7866, 7893, 8701, 0669, ", 771]
- 1. Trova e sostituisci le righe di un array con numero ripetuto da una riga prestabilita
- 2. trova il numero di stringhe in una matrice di stringhe in C
- 3. regex: trova il numero di una cifra
- 4. Subarray JavaScript senza copiare?
- 5. Trova il numero di file in una directory
- 6. Trova il numero più vicino in una lista di numeri
- 7. Trova stringa più comune in una matrice
- 8. Come posso trovare il numero di elementi in una matrice?
- 9. È possibile contare il numero di dimensioni in una matrice?
- 10. Trovare il numero di coppia non ordinata in una matrice
- 11. Come ottenere il numero di colonne in una matrice?
- 12. Trova il valore minimo non zero in una matrice
- 13. Trova il valore massimo in una matrice per ricorsione
- 14. Ottenere il numero di volte in cui un elemento viene ripetuto in C#
- 15. Algoritmo per contare il numero di elementi collegati per ciascun elemento in una matrice
- 16. Come trovare il numero più alto in una matrice?
- 17. trova un valore minimo in una matrice di float
- 18. PHP fgetcsv() - trova il numero di colonne
- 19. Objective-C: conta il numero di volte in cui un oggetto si verifica in una matrice?
- 20. PHP Ordina array SubArray Valore
- 21. Trova il valore più grande più piccolo di x in una matrice ordinata
- 22. Valutazione dell'array al subarray specifico
- 23. Subarray from NSMutableArray
- 24. Trova "numero" disponibile in un array 2d
- 25. Trovare il subarray più grande con uguale numero di 0 e 01
- 26. Numero di conteggi PHP in una matrice booleana
- 27. come spostare elementi identici in serie numpy in subarray
- 28. Mongolo: trova attraverso la matrice di ID
- 29. numero conte di volte una variabile viene ripetuto continuamente in R
- 30. Inserimento di un valore ripetuto in una colonna
posso darvi un "modello": 'Piano [12412415635/(10^(10 - n))] mod 10'. Funziona, ma sarebbe uno schema accettabile per te? Probabilmente no. Devi specificare cosa *** esattamente *** consideri un "modello". A meno che tu non possa dare una specifica, non puoi implementarla. – phant0m
@ phant0m Ho modificato la domanda. Spero sia chiaro ora. Quello che intendevo è contare il sub array ripetuto –
Probabilmente si può usare un suffisso per questo, ma non sono sicuro di quale sarebbe esattamente l'algoritmo. – harold