12
votes

Comment ajouter de nombreuses chaînes en C ++

Comme je sais que c ++ permet seulement d'ajouter 2 chaînes ensemble, c'est-à-dire S = S1 + S2

Mais comment puis-je ajouter de nombreuses chaînes ensemble? Comme: xxx


6 commentaires

Pourquoi pensez-vous que cela ne fonctionne pas?


utilisez-vous la classe de cordes?


Oui, je remarque que cela ne fonctionne que lorsque j'utilise une classe de cordes. mais je veux faire quelque chose comme ça dans c ++ #define st "blah3" S = S1 + "blah1" + "blah2" + st


@tsubasa: Eh bien, vous ne pouvez pas. Si vous connaissez deux littéraux au moment de la compilation, il vous suffit de les laisser adjacents les uns aux autres pour leur permettre de concaténer dans le préprocesseur. I.e., "asd" "123" devient "asd123" . Mais l'ajout de chaînes d'exécution nécessite que vous utilisiez la classe de cordes.


N'oubliez pas non plus "bla1" + "blah2" est faux. Il ajoutera les valeurs du pointeur ensemble plutôt que de contatraliser les cordes.


@Billy: Eh bien, cela n'ajoutera pas les valeurs du pointeur en soi. Ça va essayer mais ne pas compiler.


6 Réponses :


8
votes

Tout d'abord, vous pouvez faire la chose + Sn bien. Bien qu'il faudra prendre exponential s> quadradic (voir commentaires) temps en supposant que vous utilisez std :: basique_string code> cordes sur C ++ 03.

Vous pouvez Utilisez le std :: basic_string :: ANNEXE code> en concert avec std :: basique_string :: réserve code> pour concaténer votre chaîne dans O (n) heure. p>

EDIT: Par exemple P>

string a;
//either
a.append(s1).append(s2).append(s3);
//or
a.append("I'm a string!").append("I am another string!");


10 commentaires

Cela ne va pas prendre du temps exponentiel, seulement quadratique. Ajoutez sera plus rapide, mais en général Quadratique de toute façon, car il doit réaffecter une forme de formulaire à temps. Dans la plupart des cas, les deux méthodes ne seront pas assez lentes pour être perceptibles, cependant.


Non, c'est en fait exponentiel, la réponse de R Samuel Klatchko le démontre. Vous ajoutez S1 et S2 ensemble, puis ajoutez le résultat à S3, puis ajoutez le résultat à S4 ... etc. Chaque ajoute ajoute la longueur complète de toutes les chaînes précédentes dans la séquence. Par conséquent, étant donné K chaînes de longueur n, vous aurez Sum_ {i = 1} ^ {k} (somme_ {j = 1} ^ {i-1} (n) + n) qui est exponentielle. std :: basique_string :: ajout est linéaire si utilisé avec std :: basique_string :: réserve comme indiqué dans ma réponse, car std :: basique_string :: réserve ne garantit pas de réaffectation.


Remarque: son quadratique en ce qui concerne K dans mon exemple ci-dessus, mais exponentiel par rapport à N. Nous sommes donc les deux corrects ici si vous regardez le problème d'une autre manière.


@Billyonéal: Pourquoi cela serait-il exponentiel? La somme que vous mentionnez est égale à (0 * N + N) + (1 * N + N) + (2 * N + N) + ... + ((k-1) * N + N) < / code> qui est égal à (1 + 2 + ... + (k-1)) * n + k * n = (k * (k-1) / 2) * n + K * n = (k ^ 2 + k) / 2) * n = o (k ^ 2 * n) . Donc, il est quadratique dans le nombre de pièces k . Dans le nombre de caractères dans chaque partie, n , il est linéaire.


À propos de APPEND () : Je semble avoir manqué que vous avez mentionné réserve () . Utilisé avec réserve () Il est en effet linéaire.


D'ACCORD. Vous gagnez. Bill ouvre la bouche, la facture insère pied. Le projet de loi doit aller trouver où il a lu l'heure exponentielle et ne croit jamais les conseils de ladite source.


@sth même sans réserver assez d'espace, Ajout prend du temps amorti linéaire qui est bien plus rapide que quadratique


@Billyonéal, vous pouvez prétendre que c'est exponentiel lorsque l'exposant en question se produit 2 (ce qui n'est toujours pas génial: p)


@Steven non, exponentiel est 2 ^ n, pas n ^ 2


@Billyonéal Oui ... Je plaisante simplement. L'expression implique un exposant. L'exposant (plutôt que la base) est 2.



13
votes

Si vous essayez d'ajouter des objets à chaîne de la classe STD :: STRING, cela devrait fonctionner.

string s = string("s1") + string("s2") + string("s3") ...


6 commentaires

+1 - Il suffit de garder à l'esprit lorsque vous utilisez opérateur + (std :: basic_string , std :: basique_string ) Vous encourrez une heure exponentielle en C ++ 03. Utilisation du std :: basic_string :: ANNEX La fonction membre ne prend que du temps linéaire en comparaison.


Je pense que string s = chaîne ("S1") + chaîne ("S2") + chaîne ("S3") ... est quelque chose que je cherche. Je me demande pourquoi ça marche?


Parce que vous êtes lorsque vous utilisez une chaîne (x), vous invoquez un constructeur pour la classe de chaîne standard sur x. Vous créez un objet à chaîne temporaire qui peut alors participer avec son opérateur +. (Cette sorte d'oeuvres comme une forme de coulé)


@tsubasa: C'est assez suffisant si vous vous assurez simplement que le premier élément est une chaîne , donc string ("S2" + "S2" + "S3" fonctionnera également . La raison est que les constantes de chaîne normales telles que "s1" sont de type const char * , et vous ne pouvez pas simplement ajouter de tels pointeurs ensemble. String Objets d'autre part Savoir comment ajouter un Const Char * Pour former une nouvelle chaîne . (Aussi: rien n'utilisera une heure exponentielle ici, alors ne vous inquiétez pas trop à ce sujet)


@Billyonéal: Êtes-vous sûr que c'est une heure exponentielle? Regarder o (n ^ 2) pour moi.


@Steve: Oui, mon mauvais, voir les commentaires sur ma réponse. Cela ne me laissera pas modifier ce commentaire ici. Pas que le temps quadratique est une bonne chose ici non plus.



5
votes
s = s1;
s += s2;
s += s3;
...
s += sn;

1 commentaires

Votre exemple n'est pas tout à fait le même TMP1 doit être COPY CROX COPY. Ce serait la même chose si TMP1 était "chaîne const &". Bien que je dois admettre que le RVO éliminerait probablement la copie.



3
votes

std :: ostringingstream est construit pour cela, voir Exemple Ici . C'est facile: xxx


5 commentaires

Je voudrais souligner que l'utilisation de Stringstream pour les chaînes ajoutées est plus lente que de simplement ajouter une chaîne. Stringstream est idéal pour la conversion de choses aux cordes, mais si tout ce que vous faites est de construire des cordes de chaînes, c'est une façon moins efficace de le faire. Ajouter () et + = sont la voie à suivre.


En fait, j'ai écrit un programme de test récemment et j'ai constaté qu'il fallait environ 2 1/2 fois pour mettre des cordes avec Stringstream que d'ajouter directement à une chaîne - et c'est sans obtenir la ficelle de la chaîne quand vous avez terminé. Ce chiffre particulier n'est probablement pas généralement précis avec des circonstances variables et tout cela, mais il était évident que la construction de ruisseaux avec Stringream est nettement plus lente que de simplement ajouter une chaîne.


Eh bien, j'ai fait des tests et j'ai constaté que bien que légèrement plus lent, c'était seulement 20% plus lent. Prendre une chaîne et ajouter 10 chaîne de 10 caractères sur elle. Réinitialiser et répéter cela un million de fois. La différence est de 2 secondes (sur ma machine). À peine, même la peine d'être remarquée car aucun stand de processeur frappera cette différence immédiatement. La victoire pour moi est la plus basse sur le système de gestion de la mémoire. Moins d'appels pour allouer de l'espace car le flux de chaîne a un tampon relativement grand.


Ceci est probablement dû à une mise en œuvre particulière de la gestion des tampons de chaîne interne (croissance exponentielle?) Et la gestion des tampons de flux de chaînes. Ni sont garantis pour se comporter d'une manière ou d'une autre.


@Nikolai vrai. Si vous vous souciez vraiment et que vous voulez être sûr dont vous êtes plus rapide pour ce que vous faites, vous devez le profiler pour le programme particulier que vous travaillez avec la mise en œuvre particulière que vous utilisez. Cependant, les indications générales sont que StringStream est susceptible d'être plus lente. Je dirais donc d'utiliser l'annexe de chaîne () ou + = à moins que vous n'ayez besoin de stringstream pour ses capacités particulières ou que vous vous souciez vraiment de la performance et avez profilé votre code et avez-vous constaté. Ce StringStream est meilleur dans votre cas particulier.



1
votes

Utilisez un modèle pour ajouter des chaînes, Char * et Char's pour former une chaîne

SHLEN: - P>

int main()
    {
    const char * s[] = {"vw", "xyz"};
    std::vector<std::string> v{"l", "mn", "opqr"};
    std::string a("a");
    std::string b("bc");
    std::string c("def");
    std::cout << string_add(a, b+c, "ghij", make_it_pair(v), 'k', make_it_pair(s));
    }


1 commentaires

Vous devriez créer une proposition de normalisation :)



0
votes

Si vous voulez pouvoir faire cela

  • efficacement , i.e sans encourir de temps quadratique li>
  • sans écraser la variable d'origine li>
  • sans créer de variables temporaires li> ul>

    alors cela fera le travail P> xxx pré>

    et si vous aimez les choses bien formatées p>

    auto s = std::string(s1).append(s2)
                            .append(s3)
                            .append(sn)
    


0 commentaires