Y a-t-il un moyen de remplacer un caractère à la position n dans une chaîne de la Lua.
C'est ce que j'ai monté jusqu'à présent: P>
function replace_char(pos, str, r) return str:sub(pos, pos - 1) .. r .. str:sub(pos + 1, str:len()) end str = replace_char(2, "aaaaaa", "X") print(str)
3 Réponses :
Vous devez utiliser Peut-être p> est plus efficace que l'opérateur POS code> à l'intérieur de votre fonction au lieu de littéral
1 code> et
3 code>, mais en dehors de cela, il semble bon. Comme les chaînes Lua sont immuables, vous ne pouvez pas vraiment faire beaucoup mieux que cela.
.. / code> , mais j'en doute - s'il s'avère être un goulot d'étranglement, mesurez-le (puis décidez d'implémenter cette fonction de remplacement en C). P> P>
Oui, l'opérateur .. / code> est le moyen le plus lent de concaténer des chaînes car une nouvelle chaîne est créée pour chaque
.. code>. Les méthodes plus rapides incluent
string.format code> et
table.concat code>. Cela ne devrait causer aucun effet notable, sauf si vous travaillez avec de très grandes chaînes ou de nombreuses opérations de concaténation. Par exemple, j'ai eu un script utilisant plus de 500 Mo de mémoire pour traiter un fichier de moins de 1 Mo en utilisant environ 5
.. code> par ligne d'entrée lors du tri et de la reconstruction de l'entrée comme sortie. Changer pour stocker des chaînes dans une table et
table.concat code> à la fin le rendit si vite que je n'ai même pas pris la peine de mesurer.
@Arrowmaster: Savez-vous que dans a .. b .. c code> Il y en a deux (au lieu d'une seule) nouvelles chaînes créées ou présumez-vous simplement cela? En principe, cela pourrait être optimisé par le compilateur / interprète pour créer une seule nouvelle chaîne, comme s'il est fait en Java pour l'opérateur
+ code>. Votre exemple est un autre cas, car vous devez vraiment créer de nouvelles chaînes avec chaque relevé.
@ Paŭlo Ebermann Ouais Je viens de copier le code, j'ai oublié de supprimer les littéraux. @Arrowmaster @ Paŭlo Ebermann Je vais comparer le .. Opérateur à la méthode du format. Merci pour la perspicacité.
@ Paŭlo: La version de référence de Lua n'a pas grand-chose si des optimisations de compilateur. Je ne suis pas sûr d'autres implémentations telles que Luajit.
Vous avez besoin de parens autour de "% s% s% s" code> ici.
À propos des optimisations: Autant que je me souvienne, Standard Lua essaie de transformer toutes les concatenations .. code> dans une seule expression à une seule instruction VM (jusqu'à un point). Donc
a .. b .. c code> ne crée pas de chaîne intermédiaire. (Mais
a .. (b .. c) code> devrait en créer un.)
Et généralement table.concat code> (et la création de table qu'elle a besoin) ne valent que la peine dans les boucles. Si vous avez une seule expression, allez pour
.. code>. (Et de toute façon, vous ne devriez pas essayer d'optimiser prématurément; écrivez-le de manière la plus concise d'abord, profilez et optimisez plus tard)
Lua a un opcode spécial "Concat" qui ne crée pas de chaînes intermédiaires. L'utilisation de parenthèses provoque la création de chaînes intermédiaires.
Fait ou pas? Le "soit" me jette.
@Rosscharette: Je suppose que c'est "ça ne" pas ". Mais vous devriez inclure un @sylvanaar code> dans votre message afin qu'il obtient une notification à ce sujet.
Les cordes de Lua sont immuables. Cela signifie que toute solution qui remplace le texte dans une chaîne doit finir par construire une nouvelle chaîne avec le contenu souhaité. Pour le cas spécifique de remplacement d'un seul caractère avec une autre teneur, vous devrez diviser la chaîne d'origine en une partie de préfixe et une pièce postfix, et de les concaténer autour du nouveau contenu.
Cette variation de votre code: P>
function replace_char3(pos, str, r) return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)} end
Merci pour l'explication en profondeur
C'est vieux. Mais je viens de faire résoudre un insecte mineur dans un code que j'ai écrit. Éteint que la méthode remplacer_char2 code> n'insérez pas NULL (
\ 0 code>) caractères.
@DelusionAlogic bon point. String.Format CODE> est basé solidement sur la fonction
SPRINTF (CODE> STRINTF () CODE> STRINTF () et est susceptible d'avoir des problèmes avec des octets nul intégrés.
avec Luajit, vous pouvez utiliser la bibliothèque FFI pour lancer la chaîne dans une liste de graphiques non signés: