6
votes

Mots inversants dans une phrase

Je passe actuellement à K.n. La programmation C du roi: une approche moderne . J'ai déjà passé le texte du 8ème chapitre (tableaux), et je suis impatient de passer au chapitre 9, mais je n'ai pas encore résolu les "projets de programmation" à la fin de chaque chapitre. Malheureusement, le 14ème ... me bugs .

Écrivez un programme qui inverse les mots dans une phrase. xxx

indice : Utilisez une boucle pour lire les caractères un à un et rangez-les dans un tableau un dimensionnel char . Avoir l'arrêt de la boucle à une période, point d'interrogation ou point d'exclamation (le "caractère de terminaison"), qui est enregistré dans une variable distinct char . Ensuite, utilisez une seconde boucle pour rechercher en arrière via le tableau pour le début du dernier mot. Imprimez le dernier mot, puis recherchez en arrière pour le prochain mot. Répéter jusqu'à ce que le début de la matrice soit atteint. Enfin, imprimez le caractère de terminaison.

J'ai envisagé de définir un mot comme une séquence de caractères entre des espaces vides. Donc, quand un espace est atteint, allez en arrière, imprimant chaque caractère, jusqu'à ce qu'un autre espace soit trouvé. Mon première version du programme n'a imprimé que le premier mot. La version actuelle de celui-ci imprime uniquement les autres mots. J'ai été coincé à ce sujet pendant deux jours. Toute aide est donc vraiment appréciée. Voici mon code, ainsi qu'un échantillon de sortie. J'espère que j'ai correctement documenté mon code. Merci d'avance!

code xxx

sortie:

http://drp.ly/1nyt5j


4 commentaires

Il y a une solution beaucoup plus facile, imho. D'abord inverser chaque mot en place, puis inversez la chaîne entière.


@Carl Norum Mon problème semble être lié à la délimitation des mots. Comment ferais-je plus facilement chaque mot? Merci!


J'écris un exemple rapide maintenant. Holtez un instant!


Connexes: Compte tenu d'un éventail de caractères qui forment une phrase de mots, donnez un algorithme efficace pour inverser l'ordre des mots (pas des caractères) dans Il


10 Réponses :


5
votes

Appuyez sur chaque mot sur une pile et lisez la pile de l'index 0 à N-1


2 commentaires

C'est difficile à faire en C s'il s'agit de sa première gâche avec des chaînes de C. Nous ne sommes pas en C ++ ou Perl Terre ici, Toto. :-)


J'ai édité mon post retirant la balise "Cordes". Je pense que de nombreux malentendus ont rencontré. En dehors de cela, ne pas être un "devoir" vraiment, il n'est pas non plus lié aux chaînes. Jusqu'à présent, je suis supposé de connaître uniquement des boucles, des conditionnels, des E / S de la console, des types de données de base et des tableaux de base. Pas de chaînes ni de fonctions. Je pense donc que je dois trouver une solution ad-hoc. Les piles sont ... deux chapitres loin.



3
votes

Une autre méthodologie à penser:

man strcspn


4 commentaires

Ce n'est pas ... Je ne suis pas nouveau à la programmation, j'ai effectué des travaux approfondis dans PHP (et les technologies Web associées). Mais il y a deux semaines, je voulais choisir C, cette fois-ci pour le bien (oui, j'ai des tentatives passées, mais l'école prenait beaucoup trop de temps, alors je devais abandonner). J'ai donc acheté ce livre et j'essaie de le suivre à fond. Il y a eu beaucoup d'endroits où j'aurais pu utiliser des choses comme ... des fonctions, mais je ne voulais pas, parce que, comme je l'ai dit, c'est le sujet du prochain chapitre, et je n'essaie pas de précipiter les choses. Je vais essayer de tirer le meilleur parti de vos suggestions. Merci!


Pas de problème, content d'aider! Ceci est un peu d'un premier premier projet de jeu avec des cordes en c. Chacun des sous-problèmes que j'ai mentionnés (qui devrait aller dans une fonction distincte chacun) serait un bon endroit pour commencer. Écrivez un programme pour trouver un '.' ou un '' ' dans une chaîne et déterminez l'index. Écrivez un programme pour inverser tous les caractères d'une chaîne, tout au long de la fin (pas le '\ 0' cependant!). et écrivez un programme qui trouve et imprime les mots individuels d'une phrase. Si vous pouvez faire ces trois choses séparément, vous pouvez les ajouter ensemble pour résoudre ce problème plus important. :-)


Je pensais à écrire la première fonction que vous suggérez, car il serait possible de rechercher la fin de la chaîne d'entrée en utilisant une fonction avec un nombre variable d'arguments. Mais je ne suis pas censé savoir comment écrire une fonction, comme je l'ai dit, je vais devoir proposer une solution ad-hoc. Quant à la deuxième fonction, avez-vous besoin de deux tableaux, ou je manque quelque chose? Enfin, mon idée de définir des mots comme séquences de caractères délimitées par des espaces un bon?


Vous n'avez pas besoin d'un nombre variable d'arguments. Consultez strcspn . Le premier argore est la chaîne à rechercher, la seconde est une chaîne contenant plusieurs caractères, qui déclenchera la recherche. strtok et plusieurs autres fonctionnent aussi bien. Éloignez-vous des fonctions variables-arg en C, sauf si vous avez vraiment besoin. Pour la deuxième fonction, vous pouvez le faire en place. Pensez à la jonglerie. Vous pouvez échanger deux balles si vous conservez un dans les airs. Il suffit de faire place à cette balle, faites-le, puis passez à l'échange suivant. Et oui, l'espace séparé est le plus facile, sinon 100% correct - commencer là.



2
votes

Voici un exemple qui fait ce que j'ai mentionné. Tout d'abord, inverser chaque mot en place, puis inverser toute la chaîne. Voici une fonction inverse () code> qui inverse une chaîne en place avec un caractère délimitant donné. Vous pouvez étendre pour utiliser plusieurs délimiteurs si vous le souhaitez.

$ ./example "the quick red fox jumps over the lazy brown dog"
dog brown lazy the over jumps fox red quick the


6 commentaires

-1 Pour donner une solution pleine soufflée à une personne qui a besoin d'un coup de pouce dans la bonne direction. Comment XLR3204S peut-il apprendre à penser lorsque vous donnez une solution à l'emploi à la pâte ?!


@sbi, il dit qu'il n'est pas nouveau à la programmation - seulement nouveau à C. Le but est de l'aider avec un exemple bien écrit dans la langue qu'il tente d'apprendre. Les algorithmes ne sont pas le problème ici, apprendre une syntaxe de langue spécifique. Quand Je suis Apprendre quelque chose, je veux généralement voir un bon exemple - beaucoup plus que je ne veux que de vagues notes sur la syntaxe correcte.


Qui passe quelque chose? Je suis libre de sauter ce problème et des chapitres suivants si je veux. J'essaie de tirer le meilleur parti de sa réponse / programme, en regardant les parties dont j'ai besoin. Je pense que la balise Twork attire les gens qui pensent que je fais cela pour une classe ou quelque chose comme ça.


Les balises ont été éditées et celle-ci a été ajoutée par eruciforme. Je pensais que c'était une procédure de base, je vois d'autres auto-fautittes ont la balise devises . Puis-je l'enlever sans être sanctionné pour cela?


Ma faute, cela ressemblait vraiment à un problème de devoirs. mes excuses.


@Carl: Il y a un exercice @ XLR3204S veut faire, mais se bloque et demande de l'aide. Vous postez une solution passée. Je suis désolé si cela vous offense, mais après avoir enseigné la programmation depuis des années, c'est un modèle que je n'aime pas passionné et que je vole. (S'il y avait devoirs tag, je ne l'ai pas vu, BTW.)



0
votes

Je n'ai pas essayé. l'espoir serait utile pour vous.

char temp[100];
int j=0, k=100, l=0;
for(i=size-1; i>=0; i--){
  if(sentence[i] == ' ' || i == 0){
    if(k-i >= 2){// at least one character

      if(i==0) j = 0;
      else j = i+1;

      for( l=0; j < k; j++, l++){
         temp[l] = sentence[j];
      }
      temp[l] = '\0';
      printf("%s ",temp);
    }
    k = i;
  }
}
printf("\b%c",tc);


3 commentaires

Peut-être parce qu'il combine des parties de votre code avec des parties de mon code, mais je n'ai pas répondu à votre réponse, quelqu'un d'autre l'a fait. Je vais essayer de upvoting pour y contrevoler ...


Merci. J'ai suivi votre modèle afin que vous puissiez l'obtenir facilement. Je l'ai déjà dit, je l'ai tapé ici, pas testé - mais la logique devrait bien fonctionner.


Sadat: J'ai fait voté votre réponse pour la même raison pour laquelle j'ai voté, Carl. Je suis désolé si vous n'avez pas compris cela, je pensais que c'était évident.



1
votes
int main()
{

    char sent[50],last,s;
    int i,j,length,k,temp,b;
    clrscr();
    i=0;
    printf("Enter a sentence: ");
    sent[i]=getchar();
    while(sent[i]!='\n'&&sent[i]!='.'&&sent[i]!='?'&&sent[i]!='!')
    {
        sent[++i]=getchar();
    }
    last=sent[i];//storing last char
    b=i; //length of string
    printf("Reverse of sentence: ");
    for(;;)
    {
        k=b-1;// begin from last position
        temp=k;
        while(sent[k]!=' ' && k!=-1)
        k--;
        s=k;//storing space here
        b=s;
        for(j=b+1;j<=temp;j++)
        putchar(sent[j]);
        if(s!=-1)
        putchar(sent[s]);
        if(b==-1)
        break;
    }
    putchar(last);
    getch();
    return 0;
}

0 commentaires

0
votes

Voici ma réponse

/ * Écrivez un programme qui inverse les mots dans une phrase: p>

Entrez une phrase: vous pouvez cage une hirondelle Ne pouvez-vous pas? P>

Réversibilité de la phrase: vous ne pouvez pas avaler une cage. Pouvez-vous vous? P>

indice: utilisez une boucle pour lire les caractères un à un et rangez-les dans un tableau de caractères unidimensionnel. P> avoir l'arrêt de la boucle à une période, point d'interrogation ou point d'exclamation - (le "caractère de terminaison"), qui est enregistré comme une variable de caractères séparée. P>

puis utilisez une seconde boucle pour rechercher en arrière via le tableau pour le début du dernier mot. P>

Imprimez le dernier mot, puis recherchez en arrière pour le dernier mot. Répéter jusqu'à ce que le début de la matrice soit enfin atteint. P>

Enfin, imprimez le caractère de terminaison. P>

*/
#include<stdio.h>

int main()
{
int ch;
char sentence[200]; //hard set a limit of 200 character sentence
char word[10] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0'}; //hard set limit of 10 character words
int i = 0; //character position in input
int w = 9; //character position in word
char terminator = '\0';
printf("Enter a sentence:");
   while  ( (ch=getchar()) != '\n' )
       {
       if ( ch == '.' || ch == '?' || ch == '!')
          terminator = ch;
       else
         {
         sentence[i] = ch;
         i++;
         }
//       printf("%d",i);
       }
       sentence[i] = '\0';//set last character to null


    int x;
    for ( x=i ; x >= 0 ; x-- )
        {
           if ( sentence[x] == ' ' )
           {
            printf(" ");//print the space followed by what is in the word buffer/array
//          printf("word length %d ",w);
            printf("%c",word[0]); //probably should have a for loop here
            printf("%c",word[1]);
            printf("%c",word[2]);
            printf("%c",word[3]);
            printf("%c",word[4]);
            printf("%c",word[5]);
            printf("%c",word[6]);
            printf("%c",word[7]);
            printf("%c",word[8]);
            printf("%c",word[9]);
            w = 9 ;
            word[0] = '\0'; //fill the word buffer/array with null
            word[1] = '\0';
            word[2] = '\0';
            word[3] = '\0';
            word[4] = '\0';
            word[5] = '\0';
            word[6] = '\0';
            word[7] = '\0';
            word[8] = '\0';
            word[9] = '\0';
//          printf("\n");
//          printf("sentence position %d ",x);
           }
           else //assign the letters from sentence[] to letters in word[]
           {
            word[w] = sentence[x];
            w--;
//          printf("word length %d ",w);
//          printf("%c",sentence[x]);
           }
         }
//print the first word because im using space to delimit the words unless i have a space at the
//beginning of the sentence the code above will skip the first word inputed
    printf(" ");//print the space followed by what is in the word buffer/array
    printf("%c",word[0]);
    printf("%c",word[1]);
    printf("%c",word[2]);
    printf("%c",word[3]);
    printf("%c",word[4]);
    printf("%c",word[5]);
    printf("%c",word[6]);
    printf("%c",word[7]);
    printf("%c",word[8]);
    printf("%c",word[9]);



if ( terminator != '\0' ) //prints a . ? or ! if it is including in the inputed sentence
    printf("%c",terminator);

    printf("\n");
    printf("\n");
return 0;


0 commentaires

0
votes

Les mots inversés dans une chaîne (les mots sont séparés par un ou plusieurs espaces) - Ce problème peut être manipulé de différentes manières, peu de solutions que j'ai vues jusqu'à présent, utilisez jusqu'à présent une mémoire supplémentaire. L'idée est d'obtenir la solution optimale, comme sans utiliser une solution de mémoire supplémentaire (en place) avec la complexité de temps O (n).

Alors, prenons l'exemple, disons que la chaîne est "Hello World" - et attendu O / P "World Hello"

  • Nous allons d'abord inverser la phrase entière en place , comme "Dlrow Olleh" (nous avons utilisé XOR Opération pour échanger. Veuillez consulter la méthode Swap ())
  • Nous augmentons maintenant l'index et nous nous arrêtons lorsque nous rencontrons ' '(espace).
  • Une fois que nous avons rencontré n'importe quel espace, nous savons que nous avons eu un mot. Invoquons la fonction inverse sur ce mot et inversez ce mot. Donc dans ce cas, ce sera comme "World Olleh"
  • Nous allons maintenant plus loin et arrêtons quand notre index atteigne la longueur de la phrase.
  • Une fois que nous atteignons à la fin, saisissez le dernier index -1 et inverser le dernier mot, donc ce sera comme "World Hello"

    Un point important à noter ici, lorsque nous invions la fonction inverse pour inverser le mot, nous devrons fournir l'index de démarrage et l'indice de fin de ce mot particulier dans la phrase respective.

    Le code exemple ressemblerait comme mentionné ci-dessous. Je n'ai pas testé avec des cas de bord - mais cela fournira une idée de base de l'approche.

    xxx


0 commentaires

1
votes

En prenant l'entrée en tant que tableau de caractères, puis inversez l'ensemble de l'ensemble. Suite à cela, mot inverse mot par mot où la division de la phrase en mots se produit à "", "?", "\ 0", etc. J'espère que cela aide.

 void reverse(char s[],int start,int stop){
 char t;
 while(start<stop){
    t = s[start];
    s[start]=s[stop];
    s[stop]=t;
    start++;
    stop--;
}
}

int main() {

char str[100];
gets(str);

int pos=0,begin=0,end;
reverse(str,begin,strlen(str)-1); //since the last character is null

while(pos<=strlen(str)){
    if((str[pos]==' ')||(str[pos]=='\0')||(str[pos]=='?')||(str[pos]=='!')){
        end = pos - 1; 
       reverse(str,begin,end);  
        begin = pos+1; //for the next word
    }

    pos++;

}   

cout<<str;
return 0;
}


0 commentaires

0
votes

Le code suivant pousse les mots sur une pile, puis lit la pile en arrière, comme Quonux allongé à . < Pré> xxx


2 commentaires

Veuillez inclure des explications pour les futurs visiteurs.


Bien que ce code puisse répondre à la question, fournissant un contexte supplémentaire concernant comment et / ou pourquoi il résout le problème améliorerait la valeur à long terme de la réponse. - de l'avis



0
votes

Les réponses jusqu'à présent ont contribué d'algorithmes alternatifs, qui peuvent être triés en deux classes:

  1. inverse la phrase entière et forte> inversez tous les mots dedans. Certaines versions inverseront d'abord les mots tandis que d'autres d'abord inversent la phrase; L'ordre dans lequel ces renversements sont appliqués n'a pas d'importance. L'effet net est que les mots apparaissent dans l'ordre inverse, mais les caractères de chaque mot sont dans leur ordre normal. LI>
  2. Mettez les mots sur une pile, puis les emmenez à nouveau de la pile de manière à ce que le dernier mot devienne le premier. Li> ol>

    plutôt que de suggérer un autre algorithme alternatif (qui tomberait probablement dans l'une des deux catégories ci-dessus), je vais expliquer pourquoi le code de la question initiale ne fonctionne pas comme prévu. p>

    Tout d'abord, observez que le code de la question est en réalité une variante de la classe 1. Il inverse d'abord toute la phrase, puis inverse chaque mot: p> xxx pré>

    à part quelques erreurs de débutant C'est en fait un moyen optimal d'inverser les mots d'une phrase. Il n'utilise pas de mémoire supplémentaire et ne perd pas de temps. P>

    L'astituteur a noté que l'algorithme fonctionne comme prévu, sauf qu'il n'imprime pas le premier mot de la phrase initiale (qui devrait devenir le dernier mot) . La raison en est que les travers de matrice s'arrêtent sur '' code> dans les deux sens. Lorsque la boucle externe atteint le début de la phrase, il ne trouve aucun espace, car le premier caractère de l'entrée de l'utilisateur écrase l'espace dans phrase [0] code>: p> xxx Pré>

    Par conséquent, lorsque i code> devient 0 code> dans la boucle extérieure, il n'y a pas d'espace et la boucle interne qui doit imprimer le mot commençant par la phrase [0] code> n'est jamais entré. i code> Les décréments de -1 code> et la boucle extérieure terminent. p>

    Vous pouvez tester cela sans changer le code en exécutant simplement le programme en tant qu'utilisateur. Si vous entrez un espace comme premier caractère, la réponse du programme sera correcte: p> xxx pré>

    Il y a deux façons dont vous pouvez appliquer l'inclusion du premier mot dans votre code. Le premier consiste simplement à mettre simplement un espace au début de votre phrase code>. Vous pouvez le faire en commençant à copier l'entrée de l'utilisateur à i = 1 code> au lieu de i = 0 code>: p> xxx pré>

    Une autre façon légèrement moins élégante serait de répéter la boucle interne après la terminaison de la boucle extérieure: P>

    #include<stdio.h>
    
    void print_word(char[] sentence, int i) {
        int j = 1;
        while(sentence[i + j] != ' ') {
            printf("%c", sentence[i + j]);
            j++;
        }
    }
    
    int main(void) {
        char sentence[100] = { ' ' }, c, tc;
        int i = 0, j = 1, size = 0;
        printf("Enter a sentence: \n");
        for(c = getchar(); (c != '.') && (c != '!') && 
            (c != '?') && (c != '\n'); c = getchar(), i++) {
            sentence[i] = c; /* Store the current character in the array */
            size++; /* Increase the sentence's size */
        }
        tc = c; /* Get the terminating character */
        for(i = 99; i >= 0; i--) {
            if(sentence[i] == ' ') {
                print_word(sentence, i);
                printf(" "); /* Print a tailing space */
            }
        }
        print_word(sentence, i);
        printf("\b%c\n", tc);
        return 0; /* Return 0 upon successful program execution */
    }
    


0 commentaires