Move() pour Insérer/Supprimer un poste(s) à partir d'un tableau dynamique de la chaîne
En Utilisant Le Système.Move() pour insérer/supprimer un poste(s) à partir d'un tableau de chaîne de caractères n'est pas aussi simple que d'insérer ou de supprimer à partir d'autres ensembles de types de données simples. Le problème, c'est ... de la chaîne de référence est comptée dans Delphi. À l'aide de la méthode Move() sur la référence dépouillement des données types de besoins à approfondir les connaissances sur le comportement du compilateur interne.
Quelqu'un peut ici expliquer les étapes nécessaires pour moi de réaliser que, ou mieux à l'aide de l'extrait de code codes, ou me diriger vers une bonne référence sur internet?
Oh, s'il vous Plaît ne me dites pas d'utiliser le "lazy-mais de façon lente", qui est, pour la boucle, je le sais.
OriginalL'auteur Phantom | 2010-09-16
Vous devez vous connecter pour publier un commentaire.
Je l'ai montré comment faire pour supprimer des éléments d'un tableau dynamique avant:
Dans cet article, j'ai commencer avec le code suivant:
Vous ne peut pas aller mal avec ce code. Utiliser n'importe quelle valeur pour
X
vous le souhaitez, dans votre cas, le remplacer parstring
. Si vous souhaitez obtenir de l'amateur et de l'utilisationMove
, puis il y a la façon de le faire, aussi.Depuis
X
eststring
, leFinalize
appel est équivalent à l'affectation de la chaîne vide pour que l'élément de tableau. J'utiliseFinalize
dans ce code, bien que, parce qu'il va travailler pour tous tableau-les types d'élément, même des types qui incluent des enregistrements, des interfaces, des chaînes et des autres tableaux.Pour l'insertion, vous passez les choses de la direction opposée:
Utilisation
Finalize
lorsque vous êtes sur le point de faire quelque chose qui est en dehors des limites de la langue, comme l'utilisation de la non-type-safeMove
procédure pour remplacer une variable d'un compilateur-géré type. UtilisationInitialize
lorsque vous êtes re-entrer dans la définition de la partie de la langue. (Le langage définit ce qui arrive quand une matrice augmente ou réduit avecSetLength
, mais il ne définit pas comment faire pour copier ou supprimer des chaînes sans l'aide d'une chaîne-instruction d'affectation.)juste une suggestion, ou peut-être une demande, nous serons heureux si vous s'il vous plaît mettre à jour votre article ci-dessus pour inclure également l'insertion. J'aime votre conception de site web.
J'ai modifié Rob code à fournir un moyen de le faire à l'aide de la plus récente TArray<T> de la construction. Que pensez-vous, Rob? Tous les problèmes que j'ai manqué?
Devrait être: TailElements := ALength - Index - 1; dans DeleteX()
OriginalL'auteur Rob Kennedy
Pour insérer une chaîne de caractères, il suffit d'ajouter une chaîne de caractères (la manière paresseuse) à la fin du tableau (qui est un tableau de pointeurs), et ensuite utiliser
Move
pour modifier l'ordre des éléments de ce tableau (de pointeurs).OriginalL'auteur Andreas Rejbrand
Si je voulais insérer une chaîne dans une liste de chaînes de caractères, je ne l'utiliserais TStringList.Insérer. (Il le fait rapidement à l'aide du Système.Déplacer.)
Aucune raison particulière pour laquelle vous êtes à l'aide d'un tableau au lieu d'un TStringList?
Eh bien, aussi longtemps que vous mesurez les frais généraux réels de la
TStringList
approche. Beaucoup de gens sont très tolérants à des retards de quelques millisecondes.Assez juste, mais il y a d'autres implications sur les performances à prendre en compte. Par exemple, si vous avez à remplir votre tableau avec un grand nombre de chaînes, utilisez-vous la
SetLength(MyArray, length(MyArray) + 1)
à chaque fois? C'est un énorme nombre de reallocs et copies, et il peut vraiment performance de glisser vers le bas. À la tête de ce problème, il faut allouer plus d'espace que vous utilisez, de sorte que vous besoin de quelque chose pour garder une trace de la capacité et du nombre actuel. Pour gérer cela, il vous faut l'encapsuler dans un objet... et puis vous êtes bien sur la route à réinventer la TStringList. 😛Oui, Mason est absolument droit. L'exemple dans son commentaire, est l'un des plus fréquents et plus graves Delphi problèmes de performances. Mais, @Fantôme, puisque vous parlez de
Move
, je suppose que vous êtes déjà au courant de ce problème.Non, je vais allouer de la mémoire, tout dit, pour 16384 éléments, et d'allouer plus de 16384 si il est apparemment nécessaire.
OriginalL'auteur Mason Wheeler
Appel UniqueString() sur celui-ci, avant de jouer avec elle.
http://docwiki.embarcadero.com/VCL/en/System.UniqueString
Alors vous avez une chaîne à une seule référence.
Chance de graisse que c'est ce que la suppression et l'insertion en faire trop, et je doute que vous serez plus rapide.
"Fat chance" signifie que quelque chose est peu probable. Par exemple: "pensez-vous que notre patron nous donnera un bonus cette année?" "Bonne chance!" L'appel de UniqueString est exactement que la Suppression et l'Insertion fera lors de la modification du caractère contenu d'une chaîne de caractères. Il n'y a pas besoin de l'appeler lors de la modification du contenu des éléments d'un tableau dynamique.
Oups, les expressions sont toujours des douleurs dans les langues étrangères 🙂 de toute façon, j'ai raté le "tableau de bits. Puis vient de finaliser les bits supprimés et l'initialisation de la non supprimé bits (ou de les remplir avec du zéro) ferait
OriginalL'auteur Marco van de Voort
Juste envie d'ajouter ce pour tout les gens qui viennent ici dans l'avenir.
La modification de Rob code, je suis venu avec cette façon de faire qui utilise la plus récente
TArray<T>
type de constructions.Une chose semblable peut être fait pour l'insérer.
(Ne recherche pas ce pour obtenir marqué comme réponse, juste à la recherche de fournir un exemple qui a été trop long pour tenir dans les commentaires sur Rob excellente réponse.)
(Fixé à l'adresse de Rob commentaires ci-dessous.)
TArray
aurait été bien, mais vous avez décidé d'ajouter une autre caractéristique, et ce faisant, vous avez cassé l'ensemble de la chose. Je ne pense pas qu'il y a aucun entrée qui fait de cette fonction de travail.Avez-vous quelque chose de plus spécifique à-dire que cela? J'ai effectivement corrigé une erreur qui, je crois, est-il (j'ai eu mon 0/1 transposée sur le
if Index = 0 then
conditionnelle). Je suis en train de l'utiliser tout de suite et c'est apparemment fonctionne bien. Si il y a une erreur, ce n'est certainement pas très évident au debug/runtime. La critique Constructive de bienvenue.Pouvez-vous expliquer comment cela répond à la question de "l'Aide de la méthode Move() pour insérer/supprimer des éléments d'un tableau dynamique de la chaîne"? Je vois une boucle itérative qui n'a rien à faire avec l'aide de
Move
que ce soit, n'adresse pas undynamic array of string
(ungeneric TArray<string>
n'est pas undynamic array of string
), et la question de la demande spécifiquement ne pas utiliser une boucle, parce que l'affiche sait déjà comment faire. OIE, cela n'a absolument aucune pertinence à la question posée ici; affichage aléatoire des non-réponses aux questions n'est pas vraiment comment ça fonctionne.La transposition n'a pas aidé. Tout moment
Index
est différente de zéro, vous finissez par écrire àA[-1]
. Le premier endroit que vous écrivez doit toujours êtreA[Index]
. Regarde mon code. Pourquoi l'indice de départ de la jamais conditionnelle en premier lieu? Vous pourriez vous rapprocher de votre but ensemble des fonctionnalités de revenir à mon code et en remplaçant chaque occurrence de1
avecCount
.Merci, c'est plus constructif. En fait, c'était surtout le fait de regarder mon code, après une nuit de sommeil et va "attendre, pourquoi ai-je écrit cela?" Je n'ai aucune idée à ce point, mais la réponse est assez évidente. J'ai passé par plusieurs tours de papier et un stylo à les soluces, donc je suis confiant que c'est juste à ce point.
OriginalL'auteur jep
Vous n'énoncez pas si c'est important pour vous de garder les éléments d'un tableau dans le même ordre ou pas.
Si l'ordre n'est pas pertinent, vous pouvez donc quelque chose de vraiment rapide comme ceci:
{ Je n'ai pas testé le code pour voir qu'il compile, mais vous avez l'idée de toute façon... }
OriginalL'auteur Rigel
Si vous utilisez le Système.Déplacer à mettre les éléments dans un tableau de chaîne de caractères, vous devez être conscient que les chaînes que là où avant le Déménagement (et désormais remplacée), avaient un nombre de références de -1 pour les chaines, ou > 0 pour les variables chaînes de caractères. Les chaines ne doit pas être modifiée, mais les chaînes de variables doivent être traités en conséquence: Vous devez manuellement réduire leur référence-comte (avant qu'ils ne soient écrasés!). Pour ce faire, vous devez essayer quelque chose comme cela:
Mais si la référence-comte atteint zéro, vous devez également finaliser la mémoire associée à l' - quelque chose de Delphes lui-même n'beaucoup mieux si vous le permettez, c'est le compilateur de la magie pour les chaînes. Ah, et aussi : si les chaînes que vous voulez copier viennent de la même matrice que votre écriture, le besoin de l'administration devient très lourd, très rapidement!
Donc, si c'est d'une certaine façon possible afin d'éviter tous ce manuel d'entretien ménager, je vous conseille de laisser Delphi gérer lui-même.
TStringList a été conçu pour la manipulation d'un grand nombre de chaînes. Si vous avez Delphi vous avez des Classes.pas; parcourir le code de TStringList et TStrings et de voir le nombre de bits de code que vous pouvez trouver qui sont là précisément pour des raisons de performances. C'est l'un des plus classes utilisées dans l'ensemble de RTL, et il a été largement testé depuis maintenant 15 ans. Vous auriez à travailler assez dur pour arriver à une solution qui est nettement plus rapide que la TStringList à la manipulation des chaînes. Si vous voulez savoir si c'est lent, essayez de l'utiliser et voir si elle se sent lent ou pas.
Je vais l'essayer.
-1 pour suggérer la modification manuelle de l'intérieur, définis par l'implémentation des structures de données. Vous pouvez avoir attribué
SomeString := ''
et laisser le compilateur prendre soin du zéro de référence-le comte de la situation, ainsi que le fil de sécurité.Je viens de répondre Fantôme de la question de savoir comment diminuer le nombre de références manuellement. Je crois que c'est une question valable, de répondre, même quand il n'est pas conseillé de le faire! (N'ai-je pas mentionner que lors de ma dernière déclaration?) Bien sûr, réglage
Somestring := ''
fonctionne aussi, mais qui s'appuie sur le compilateur de la magie, donc, ma réponse a une certaine crédibilité, vous ne pensez pas?OriginalL'auteur PatrickvL