Encoder chaque élément d'un ensemble avec un nombre premier.
Ex:
a -> 2
b -> 3
c -> 5
etc.
Maintenant, vous avez besoin de deux autres listes pour maintenir.
La première liste est pour les nombres premiers, la seconde est pour leurs exposants.
L'idée est; Lorsque vous tombez sur un élément, enregistrez son nombre premier et combien de fois de suite il apparaît.
Pour [a, b, b, c]
, vous obtenez ceci:
[2, 3, 3, 5]
qui peut être enregistré comme:
[2, 3^2, 5]
ou, plus précisément:
[2^1, 3^2, 5^1]
et vous maintenir deux listes:
[2,3,5] // primes in succession - list [p]
[1,2,1] // exponents - list [e]
Maintenant, vous parcourez ces deux listes de bout en bout, en vérifiant si le premier élément [p]^[e] est le même que le dernier élément; si c'est le cas, puis deuxième avec avant-dernier et ainsi de suite ... Si tous sont les mêmes, votre liste peut être réduite.
Dans cet exemple, vous vérifiez si 2^1*5^1 == 3^2*3^2
; et puisque ce n'est pas le cas, cela ne peut pas être réduit.
Essayons [a, b, b, a, b, b]
:
Ceci est codé comme
[2^1, 3^2, 2^1, 3^2]
ou,
[2, 3, 2, 3] // primes
[1, 2, 1, 2] // exponents
Maintenant, nous vérifions si 2^1 * 3^2 == 3^2 * 2^1
(premier premier, premier exposant multiplié par la dernière prime, dernière exposant, puis comparé avec le deuxième par rapport à l'avant-dernier)
Puisque cela est vrai, il est réductible.
Essayons [b, b, b, b, b]
:
Cela peut être codé comme
[3^5]
ou,
[3] // primes
[5] // exponents
Ceci est un cas particulier: si vous avez 1 listes d'éléments, votre la liste originale est réductible.
Essayons [b, b, b, b, a]
:
Cela peut être encodée comme
[3^4, 2^1]
ou,
[3, 2] // primes
[4, 1] // exponents
Nous vérifions si 3^4 == 2^1
, et comme il n'est pas, votre liste n'est pas réductible.
Essayons [a, b, a, b, a, b]
:
Cela peut être codé comme
[2^1, 3^1, 2^1, 3^1, 2^1, 3^1]
ou,
[2, 3, 2, 3, 2, 3]
[1, 1, 1, 1, 1, 1]
Essayer la procédure ci-dessus fonctionne, car 2^1 * 3^1 == 3^1 * 2^1 == 2^1 * 3^1
Ainsi, l'algorithme serait être quelque chose comme ça:
Encode tous les nombres en nombres premiers.
Itération dans votre liste, faire deux listes et les remplir comme décrit
Maintenant que vous avez vos deux listes, p
et e
, tous les deux ayant une longueur n
faire:
var start = p[0]^e[0] * p[n-1]^e[n-1]
var reducible = true;
for (int i = 0; i < n/2, ++i) :
if ((p[i]^e[i] * p[n-i]^e[n-i]) != start) :
reducible = false;
break;
Note: Je n'ai pas vraiment codé cet algorithme et je l'ai essayé pour différentes entrées. C'est juste une idée. Aussi, si une liste est réductible, de sa longueur et longueur de n
, il ne devrait pas être trop difficile de voir comment réduire la liste d'origine à sa forme de base.
Deuxième remarque: si quelqu'un voit une erreur ci-dessus, veuillez me corriger. Il est possible que rien de tout cela ne fonctionne vraiment car il est tard et ma concentration n'est pas optimale.
Quelle est votre règle pour l'unreduceness de '[a, b, b, c]' et '[b, b, b, b, a]'? Et quelle est l'intuition? Je demande parce que cela ressemble à des cas particuliers d'un algorithme plus général. '[b, b]' réduira (récursivement) à '[b]', tout comme le fera [b, b, b, b] -> [b] 'par votre 3ème règle. –
Ce que vous cherchez est un algorithme de compression de données. Découvrez Huffman et le codage arithmétique. –
[a, b, b, c] -> [a, b, b, c] [b, b, b, b, a] -> [b, b, b, b, a] [ b, b] -> [b] Tous ces cas conservent la liste de lecture originale puisqu'elle est en boucle pour toujours. – kiteloop