J'ai une question à propos de C++ 11. Je sais que la fonction ci-dessous inverse une chaîne, mais je ne sais pas ce qu'est la syntaxe {}? Quel type de structure est-ce? Je code habituellement en Java. Je ne peux pas comprendre que c'est quoi? J'ai aussi une autre question, quelle est l'efficacité de cette méthode pour inverser une chaîne de caractères? Parce que je pense inverser nous devrions changer l'emplacement des caractères si nous voulons avoir une chaîne qui est continue sur la mémoire.Syntaxe de support bouclé et itérateur en C++
Répondre
Ce qui est utilisé est appelé Uniform Initialization.
Cela semble un peu étrange, je l'admets. La fonction sait qu'elle doit renvoyer un string
, mais elle a été alimentée par une paire d'itérateurs. Les accolades permettent au compilateur de tenter de construire un string
basé sur le contenu des accolades, et bien sûr, constructor number six listed here tentera de construire une chaîne à partir d'un itérateur de début et de fin.
Alors
return {str.rbegin(), str.rend()};
est dans la syntaxe plus familière
return string(str.rbegin(), str.rend());
Le bit suivant de la magie est rbegin
et rend
fournir itérateurs inverse, de sorte que l'entrée string
sera lue en arrière dans la sortie string
.
string
string
, ainsi l'itérateur sera traversé en heure O (N). Il n'y a pas beaucoup de magie dans la construction de la nouvelle chaîne, en copiant l'ancienne chaîne et peut-être un redimensionnement de la mémoire tampon, la nouvelle chaîne sera construite en O (N) temps PLUS tout le temps requis pour dimensionner le tampon sauvegarder le nouveau string
.
Il en résulte soit
- O (N) complexité car le tampon est préencollé avant de copier la copie de N éléments d'une
string
à l'autre, ou - Amortized O (N) complexité car le tampon est redimensionné à la demande, ce qui entraîne une allocation supplémentaire et la copie de l'ancien tampon à nouveau ainsi que la copie d'un
string
à l'autre.
La deuxième option est possible parce que le constructeur string
ne nécessite pas l'itérateur d'entrée à accès aléatoire, ce qui rend le calcul du taille du tampon nécessaire pour préencollage potentiellement plus cher que le redimensionnement. Mais il pourrait avoir un cas particulier de test pour l'accès aléatoire et la présentification.
Ce code peut être écrit aussi:
string reverseString(string str){
return string(str.rbegin(), str.rend());
}
Il utilise constructeur de gamme qui crée une nouvelle chaîne de deux itérateurs (début et fin).
Merci à l'initialisation uniforme, vous pouvez l'écrire comme:
string reverseString(string str){
return string{str.rbegin(), str.rend()};
}
Et puisque le compilateur sait déjà que le type de retour est string
, vous ne devez pas spécifier explicitement, ce qui conduit à cette « étrange "syntaxe:
string reverseString(string str){
return {str.rbegin(), str.rend()};
}
La syntaxe est appelée "initialisation uniforme" et ici elle appelle simplement (implicitement) le constructeur. La complexité est ici linéaire dans la taille de la chaîne. – Arcinde
Ceci est [initialisation de la liste de copie] (http://en.cppreference.com/w/cpp/language/list_initialization). Voir la syntaxe # 8 * 'return {arg1, arg2, ...};' * –
Vous appelez le constructeur 'std :: string' avec la notation de parenthèse – RPGillespie