J'essaie d'inverser l'ordre des mots dans une phrase en place, par exemple:
Ce mots de phrases sont inversés. P> blockQuote>
devient p>
inversé. sont des phrases de mots ce p> BlockQuote>
C'est ce que j'ai jusqu'à présent, ce qui fonctionne presque: J'utilise la fonction Strrev pour inverser la chaîne, puis la fonction INPREV pour envoyer chaque mot à la fonction Strrev individuellement, pour les inverser à l'orientation d'origine, mais dans l'ordre inversé. L'envoi d'un pointeur pour le début et la fin de la fonction Strrev peut sembler un peu stupide, mais elle permet d'utiliser la même fonction dans INPREV (), d'envoyer un pointeur au début et à la fin des mots individuels. P> < Pré> xxx pré>
Voici la sortie: P>
foobar mes amis, foobar p>
Raboof, SDNeirf YM Raboof P>
foobarfriends, mon foobar p> blockQuote>
Le problème est que l'absence d'un espace final à la fin du mot final signifie qu'un espace est manquant entre ce mot et le précédent celui de la chaîne finale, et devient plutôt jeté sur la fin de Le dernier mot, qui était le premier mot de la chaîne d'origine. L'envoi de l'espace de l'autre côté du mot ne fait que déplacer le problème ailleurs. Quelqu'un peut-il voir une solution? P> p>
5 Réponses :
Il vous suffit de déplacer le pointeur code> Démarrer code> dans la fonction code> inPrev code> pour ignorer l'espace entre les mots. Comme cela semble être des devoirs (corrigez-moi si je me trompe), je vais simplement dire que tout ce que vous avez à faire est de déplacer l'emplacement d'un opérateur.
Mais, cela produit un problème, à savoir le et qui prendra soin de plusieurs espaces aussi. De plus, U + 0020 (ASCII 32, un espace) n'est pas le seul caractère d'espace blanc. Il existe des fonctions de bibliothèque standard qui testent des caractères. Ils sont dans inPrev code> effectue une dépassement de mémoire tampon car la recherche n'est pas terminée correctement. Une meilleure façon de le faire est la suivante: p> est ... code>, par ex. ISSPACE code>. p> p>
Merci! Question initiale mise à jour avec mon algorithme fixe. Pas de devoirs BTW, l'a vu dans une interview d'emploi Question Prep et pensé que j'aurais une fissure à l'amusement.
@Matt s'il vous plaît ne corrigez pas le code d'origine dans la question! Cela rend la question inutile pour quiconque le lit à l'avenir. Je vais retourner cette modification.
@Matt: Pour ajouter au commentaire de Razlebe, vous pouvez publier le code mis à jour comme une réponse, plutôt que de modifier la question.
@Matt - Pas de mal fait. :) facilement roulé. Je suis d'accord avec Skizz si vous seriez formidable si vous pouviez poster votre code fixe comme réponse pour aider les futurs lecteurs à comprendre complètement le correctif.
@razlebe: fera, je dois attendre 5 heures, apparemment.
Fonction améliorée affichée, si quelqu'un est intéressé.
a compris une solution; Voici ma fonction révisée qui fonctionne correctement.
void inprev(char * str)
{
_Bool inword = 0;
char * wordend;
char * wordstart;
while(*str)
{
if(!isspace(*str) && (inword == 0))
{
wordstart = str;
inword = 1;
}
else if (isspace(*str) && (inword == 1))
{
wordend = str-1;
inword = 0;
strrev(wordstart, wordend);
}
str++;
}
if (*str == '\0')
strrev(wordstart, str-1);
}
Parfois, les choses deviennent plus faciles si vous n'utilisez pas de pointeurs, mais des compensations. La bibliothèque STRSPN () et STRCSPN () fonctionne plus ou moins forcer à utiliser des compensations, et traiter avec la condition finale de chaîne assez joliment.
#include <stdio.h>
#include <string.h>
size_t revword(char *str);
void revmem(void *ptr, size_t len);
size_t revword(char *str) {
size_t pos,len;
for (pos=len=0; str[pos]; pos += len) {
len = strspn( str+pos, " \t\n\r");
if (len) continue;
len = strcspn( str+pos, " \t\n\r");
if (!len) continue;
revmem( str+pos, len );
}
revmem( str, pos );
return len;
}
void revmem(void *ptr, size_t len)
{
size_t idx;
char *str = (char*) ptr;
if (len-- < 2) return;
for (idx = 0; idx < len; idx++,len--) {
char tmp = str[idx];
str[idx] = str[len];
str[len] = tmp;
}
}
int main (int argc, char **argv)
{
if (!argv[1]) return 0;
revword(argv[1] );
printf("'%s'\n", argv[1] );
return 0;
}
Seriez-vous capable d'ajouter quelques commentaires à cela expliquant ce qui se passe? C'est un peu difficile à suivre, par exemple, ce qui se passe dans la fonction REVWOWWDWWOW.
Eh bien: Dans la boucle, je mesurise la longueur de l'espace blanche consécutive (l'appel STRSPN ()) et sautez-la. Après cela, je mesurais la longueur de WhitSpace sans i> WhitSpace (l'appel STRCSPN ()) et inversez-le. À la fin de la boucle, j'ai la longueur de la corde accumulée et inverser la chaîne entière.
L'algorithme suivant est en place et fonctionne en 2 étapes. Tout d'abord, il inverse toute la chaîne. Ensuite, il renverse chaque mot.
#include <stdio.h>
void reverse(char *str, int len)
{
char *p = str;
char *e = str + len - 1;
while (p != e) {
*p ^= *e ^= *p ^= *e;
p++;
e--;
}
}
void reverse_words(char *str)
{
char *p;
// First, reverse the entire string
reverse(str, strlen(str));
// Then, reverse each word
p = str;
while (*p) {
char *e = p;
while (*e != ' ' && *e != '\0') {
e++;
}
reverse(p, e - p);
printf("%.*s%c", e - p, p, *e);
if (*e == '\0')
break;
else
p = e + 1;
}
}
int main(void) {
char buf[] = "Bob likes Alice";
reverse_words(buf);
return 0;
}
Si len code> est même, la fonction inverse code> provoquera un segfault. Essayez pendant (p
void reverse_str(char* const p, int i, int j) // helper to reverse string p from index i to j
{
char t;
for(; i < j ; i++, j--)
t=p[i], p[i]=p[j], p[j]=t;
}
void reverse_word_order(char* const p) // reverse order of words in string p
{
int i, j, len = strlen(p); // use i, j for start, end indices of each word
reverse_str(p, 0, len-1); // first reverse the whole string p
for(i = j = 0; i < len; i = j) // now reverse chars in each word of string p
{
for(; p[i] && isspace(p[i]);) // advance i to word begin
i++;
for(j = i; p[j] && !isspace(p[j]);) // advance j to past word end
j++;
reverse_str(p, i, j-1); // reverse chars in word between i, j-1
}
}
Que êtes-vous censé faire lorsque vous rencontrez des espaces x? Appartiennent-ils au mot avant ou après?
+1 Bon problème :). Si j'aurai un peu de temps, je vais fournir une solution
Je suppose que vous ne voulez pas trop faire la première lettre une grosse, alors que votre exemple montre ...
@Redx n'a pas pensé à cela, je vais avoir un autre regard sur mon algorithme et essayer de penser à quelque chose
@imacake correct, typo. Merci.