Inverser une chaîne de caractères en Ruby
Comment inverser une chaîne de caractères en Ruby? Je sais sur la chaîne#inverse. Je suis intéressé par la compréhension de la façon de l'écrire dans le plus pur Rubis, de préférence une solution.
- ce sera beaucoup plus lent que la chaîne#inverse btw.
- comment savez-vous que cela soit le cas. Que pensez-vous qui se passe avec l'inverse?
- ruby-doc.org/ruby-1.9/classes/String.src/M000609.html - C'est très peu probable que Ruby sera en mesure de rivaliser avec C la vitesse de la catégorie.
- string#inverse internes utilisez C pour calculer l'inverse.
- Par "en place de la solution" voulez-vous dire l'équivalent de
string#reverse!
? Une fonction qui modifie la chaîne directement plutôt que d'un duplicata? - Je me souviens de Jorg Mittag dire que Rubinius peut faire certaines choses dans le plus pur Rubis plus vite que YARV n'en C.
- Au passage,
"{{{1,2,3}},{4,5,6}}".reverse
="}}6,5,4{,}}3,2,1{{{"
. Depuis, il renverse les crochets, c'est en faire plus qu'un 'miroir'/'ordre' flip. C'est en manipulant les chiffres que les personnages représentent.
Vous devez vous connecter pour publier un commentaire.
Il y a déjà une place inverser méthode, appelée "reverse!":
Si vous voulez le faire manuellement, essayez ceci (mais il ne sera probablement pas être multi-octets en sécurité, par exemple UTF-8), et il sera plus lent:
Ce swaps de tous les octets à partir du début avec tous les octets à partir de la fin jusqu'à ce que les deux indices se réunissent au centre:
Juste pour la discussion, avec autant de suppléants, il est bon de voir si il ya de grandes différences dans la vitesse de l'efficience. J'ai nettoyé un peu le code que le code en montrant la sortie a été maintes fois d'inverser les sorties.
Et les résultats:
C'est intéressant pour moi que le "C" version ("reverse_string()") est le plus rapide des pur-version de Ruby. #2 ("reverse!") est plus rapide, mais c'est profiter de la
[].reverse
, qui est en C.L'ajout d'un supplément de cas de test (7):
Si la chaîne est plus longue (
lorum *= 10, n/=10
), nous pouvons voir que la différence s'élargit parce que certaines fonctions sont en O(n^2), tandis que d'autres (le mien 🙂 O(n):lorum *= 10, n /= 10
et les résultats vont vous montrer que toute solution à l'aide de[]
n'est pas de l'ordre (i.e. O(n^2)) au lieu de O(n) pour les solutions aveceach_char
. Aussi, à l'aide de+=
comme #6 vous donne également #6. J'ai édité ma réponse avec une autre solution n'utilisant pasreverse
.2.2.0
, mais n'a pas obtenu la divergence de la vitesse vous avez montré ici. Plus précisément, il ne semble pas être l'inverse avec#unshift
était en cours d'exécution O(n^2). Toutes les pensées?Le Rubis équivalent de la builtin
reverse
pourrait ressembler à:Note: cela suppose Ruby 1.9, ou d'autre
require "backports"
et définir$KCODE
pour l'UTF-8.Pour une solution n'impliquant pas
reverse
, que l'on pourrait faire:Note de: aucune solution à l'aide de
[]
pour accéder à lettres individuelles seront de l'ordreO(n^2)
; pour accéder à la 1000e lettre, Ruby doit passer par le premier 999, un par un pour vérifier les caractères multioctets. Il est donc important d'utiliser un itérateur commeeach_char
pour une solution àO(n)
.Une autre chose à éviter est de construire des valeurs intermédiaires de l'augmentation de la longueur; à l'aide de
+=
au lieu de<<
dansalt_reverse
permettrait aussi de rendre la solutionO(n^2)
au lieu deO(n)
.La construction d'un tableau avec
unshift
permettra également de faire la solutionO(n^2)
, car elle implique de recopier tous les éléments d'un index de plus chaque fois on fait ununshift
.Voici un moyen de le faire avec injection et unshift:
unshift
rend votre solution en O(n^2). Voir mes solutions pour O(n).Utilisation
La solution décrite ci-dessous. Il n'est pas nécessaire d'aller au-delà de la moitié de la taille de la matrice:
Aussi, en utilisant des Proc ...
Proc.de nouveau, ce serait pratique ici, car vous pourriez alors nest votre inversion de l'algorithme (et toujours garder les choses sur une seule ligne). Ce serait pratique si, par exemple, vous avez besoin pour inverser chaque mot dans une phrase inversée:
Difficile à lire, one-liner,
a.length
peut être retiréPensez regarder comment Rubinius implémente la méthode - ils mettre en œuvre une grande partie de la bibliothèque de base en Ruby lui-même, et je ne serais pas surpris si
String#reverse
etString#reverse!
est mis en œuvre en Ruby.C'est la solution qui a le plus de sens pour moi qu'un rubis débutant
Voici une solution de rechange à l'aide de la xor au niveau du bit opérations:
En Ruby:
Je crois que ce travail aussi
Si vous avez de la phrase "La plus grande victoire est celle" et vous voulez avoir un "c'est la victoire Le plus grand", vous devez utiliser cette méthode
Ici est une alternative simple, il brise la chaîne en un tableau en compte la longueur et la soustrait un(à cause de rubis d'indexation de la règle pour tableau à partir de 0), crée une variable vide, puis exécute une itération sur les touches du tableau, tout en ajoutant la valeur de la longueur du tableau moins les index de tableau de la variable vide créé et quand il atteint le zéro(désolé pour mon français) de la valeur qu'il s'arrête. Espérons que cette aide.