2
votes

Comment réorganiser le tableau en utilisant des espaces?

J'ai du mal à réorganiser mon tableau. J'ai utilisé des boucles simples à multiples en essayant de mettre des espaces (caractères blancs) entre deux paires de caractères, mais je réécrivais constamment l'entrée d'origine. Il y a donc toujours une entrée de longueur paire, par exemple ABCDEFGH . Et ma tâche serait d'étendre la taille du tableau en mettant des espaces après tous les 2 caractères (sauf le dernier). Donc, la sortie serait:

// output = "ABCDEFGHIJKL
char c1;
  char c2;
  char c3;
  int o_len = strlen(output);
  for(int i = 2; i < o_len + olen/2; i = i + 3){
    if(i == 2){
      c1 = output[i];
      c2 = output[i+1];
      c3 = output[i+2];
      output[i] = ' ';
      output[i+1] = c1;
      output[i+2] = c2;
    }
    else{
      c1 = output[i];
      c2 = output[i+1];
      output[i] = ' ';
      output[i+1] = c3;
      output[i+2] = c1;
      c3 = c2;
    }
  }

Donc, la taille de la sortie (si je suis correct) sera (2*input_len)-1 Merci.

EDIT: C'est mon code pour l'instant

AB CD EF GH

Donc les 3 premières paires sont imprimées correctement, alors tout est en désordre.

c

5 commentaires

Veuillez montrer ce que vous avez essayé, décrire le problème spécifique que vous rencontrez et poser une question spécifique liée à cette tentative.


La nouvelle longueur n'est pas (2 * input_len) - 1 mais input_len + (int)(input_len / 2) - 1 .


Veuillez fournir un exemple minimal, complet et vérifiable (MCVE) .


Réorganisez-vous votre tableau en place ou stockez-vous le résultat dans un autre tampon?


Si pour chaque deux éléments vous en ajoutez un, cela étend le nombre d'éléments requis à 0,5 du nombre d'éléments d'entrée. Donc: new = old + 0.5*old ou simplement new = 1.5*old


4 Réponses :


2
votes

Je pense que vous recherchez un morceau de code comme celui ci-dessous:
Cette fonction renvoie le tableau splitted sortie, comme vous l'avez demandé.

New splitted string is [AB CD EF GH]

Lorsqu'il est exécuté avec une valeur de pas de 2, le code ci-dessus génère:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

char* split_by_space(char* str, size_t length, size_t step) {
    size_t i = 0, j = 0, spaces = (length  / step);
    char* splitted = malloc(length + spaces + 1);

    for (i = 0, j = 0; i < length; ++i, ++j) {
        if (i % step == 0 && i != 0) {
            splitted[j] = ' ';
            ++j;
        }
        splitted[j] = str[i];
    }
    splitted[j] = '\0';
    return splitted;
}

int main(void) {
    // Use size_t instead of int.
    size_t step = 2; // Also works with odd numbers.
    char str[] = "ABCDEFGH";
    char* new_str;
    // Works with odd and even steps.
    new_str = split_by_space(str, strlen(str), step);
    printf("New splitted string is [%s]", new_str);
    // Don't forget to clean the memory that the function allocated.
    free(new_str);
    return 0;
}


1 commentaires

Les commentaires ne sont pas destinés à une discussion approfondie; cette conversation a été déplacée vers le chat .



1
votes

Essaye ça,

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void rearrange(char *str)
{
    int len=strlen(str),n=0,i;
    char *word=malloc((len+(int)(len/2)));
      
    if(word==NULL)
    {
       printf("Memory Error");
       exit(1);
    }

    for(i=0;i<len;i++)
    {
        if( i % 2 == 0 && i != 0)
        {
            word[n]=' ';
            n++;
            word[n]=str[i];
            n++;
        }
        else
        {
            word[n]=str[i];
            n++;
        }
    }
    
    word[n]='\0';
    strcpy(str,word);
    free(word);
    return;
}

int main()
{
     char word[40];

     printf("Enter word:");
     scanf("%s",word);

     rearrange(word);

     printf("\n%s",word);

     return 0;
 }

Voir ci-dessous:

La fonction de réorganisation enregistre les lettres de str en mot. si la position actuelle est divisible par 2, c'est-à-dire i% 2, elle enregistre un espace et une lettre dans str, sinon elle enregistre uniquement la lettre.


5 commentaires

Votre réponse doit contenir une description de son fonctionnement pour le cas de OP et aussi pour les futurs lecteurs.


@Ronak Dhoot Merci pour votre réponse, je pensais que le vote négatif était dû à des erreurs techniques, alors je trouve une erreur dans mon code et je l'ai corrigée mais je ne peux pas obtenir quelle est l'erreur exacte, alors pourquoi j'ai demandé une raison.


if(i%2==0&&i!=0) : la barre d'espace est votre ami, utilisez-la pour rendre le code plus lisible pour vous-même et pour les autres aussi: if (i % 2 == 0 && i != 0)


sprintf(word+n,"%c",str[i]); -> word[n] = str[i]; et ajoutez le terminateur nul à la fin. La surcharge sprintf utilisation de sprintf pour cette simple tâche dépasse probablement 100x


@chqrlie Merci pour vos conseils.



3
votes

En supposant que vous ayez besoin de stocker le résultat séparé de l'espace, le moyen le plus simple d'insérer les espaces est probablement d'utiliser une paire de pointeurs (un vers votre chaîne d'entrée et l'autre vers votre chaîne de sortie), puis d'écrire en boucle continuellement une paire dans votre chaîne de sortie, incrémentez les deux pointeurs de 2 , vérifiez si vous n'avez plus de caractères dans votre chaîne d'entrée (si c'est le cas, break; et nul-termine votre chaîne de sortie), sinon écrivez un space dans votre chaîne de sortie et répétez.

Vous pouvez le faire assez simplement en utilisant memcpy (ou vous pouvez simplement copier 2-chars vers le pointeur et le pointer + 1 actuels, votre choix, mais puisque vous incluez déjà string.h pour strlen() - simplifiez-vous la tâche) peut faire quelque chose de similaire à:

    if (len & 1) {  /* validate even number of characters */
        fputs ("error: odd number of characters in instr.\n", stderr);
        return 1;
    }
    if (len < 4) {  /* validate at least 2-pairs worth of input provided */
        puts(instr);   /* (otherwise output unchanged and exit) */
        return 0;
    }

Exemple d'utilisation / sortie

$ ./bin/strspaceseppairs AB
error: less than two-pairs to separate.

Nombre impair de caractères:

$ ./bin/strspaceseppairs ABCDEFGHIJLMNOP
error: odd number of characters in instr.

Ou chaîne courte:

$ ./bin/strspaceseppairs
instr  : ABCDEFGH
outstr : AB CD EF GH

$ ./bin/strspaceseppairs ABCDEFGHIJLMNOPQ
instr  : ABCDEFGHIJLMNOPQ
outstr : AB CD EF GH IJ LM NO PQ

Regardez les choses et faites-moi savoir si vous avez d'autres questions.


Modifier pour sortir simplement une paire ou une chaîne vide

Sur la base du commentaire de @chqrlie, cela peut avoir plus de sens que d'émettre un diagnostic pour une chaîne courte, juste pour la sortir inchangée. Dépend de vous. Vous pouvez modifier le premier conditionnel et le déplacer après la vérification des caractères impairs dans ce cas, par exemple

#include <stdio.h>
#include <string.h>

#define ARRSZ 128   /* constant for no. of chars in output string */

int main (int argc, char **argv) {
    
    char *instr = argc > 1 ? argv[1] : "ABCDEFGH",  /* in string */
        outstr[ARRSZ] = "",                         /* out string */
        *ip = instr, *op = outstr;                  /* pointers to each */
    size_t len = strlen (instr);                    /* len of instr */
    
    if (len < 4) {  /* validate at least 2-pairs worth of input provided */
        fputs ("error: less than two-pairs to separate.\n", stderr);
        return 1;
    }
    if (len & 1) {  /* validate even number of characters */
        fputs ("error: odd number of characters in instr.\n", stderr);
        return 1;
    }
    if (ARRSZ < len + len / 2) {  /* validate sufficient storage in outstr */
        fputs ("error: insufficient storage in outstr.\n", stderr);
        return 1;
    }
    
    for (;;) {  /* loop continually */
        memcpy (op, ip, 2);             /* copy pair to op */
        ip += 2;                        /* increment ip by 2 for next pair */
        op += 2;                        /* increment op by 2 for next pair */
        if (!*ip)                       /* check if last pair written */
            break;
        *op++ = ' ';                    /* write space between pairs in op */
    }
    *op = 0;                            /* nul-terminate outstr */
    
    printf ("instr  : %s\noutstr : %s\n", instr, outstr);
}

Vous pouvez décider comment vous souhaitez gérer n'importe quel aspect de votre programme et apporter les modifications en conséquence.


2 commentaires

Le test sur la longueur minimale d'entrée semble inutile et contre-productif: pourquoi ne pas accepter AB et la sortie AB ? Même la chaîne vide serait gérée avec élégance.


C'est un bon point. Je pensais juste à émettre un diagnostic si la chaîne fournie au programme n'avait pas au moins deux paires. Mais nous pourrions faire les deux je suppose.



1
votes

L'insertion de caractères à l'intérieur du tableau est fastidieuse et ne peut être effectuée que si vous savez que le tableau est suffisamment grand pour accueillir la nouvelle chaîne.

Vous souhaitez probablement allouer un nouveau tableau et y créer la chaîne modifiée.

La longueur de la nouvelle chaîne n'est pas (2 * input_len) - 1 , vous insérez un espace tous les 2 caractères, sauf les 2 derniers: si la chaîne comporte 2 caractères ou moins, sa longueur n'est pas modifiée, sinon elle augmente de (input_len - 2) / 2 . Et si la longueur est désactivée, vous devez arrondir cette valeur à l'entier suivant, ce qui est fait en arithmétique d'entiers de cette façon: (input_len - 2 + 1) / 2 .

Voici un exemple:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *reformat_with_spaces(const char *str) {
    size_t len = strlen(str);
    size_t newlen = len > 2 ? len + (len - 2 + 1) / 2 : len;
    char *out = malloc(newlen + 1);

    if (out) {
        for (size_t i = 0, j = 0; i < len; i++) {
            if (i > 0 && i % 2 == 0) {
                out[j++] = ' ';
            }
            out[j++] = str[i];
        }
        out[j] = '\0';
    }
    return out;
}

int main(void) {
    char buf[256];
    char *p;
    while (fgets(buf, sizeof buf, stdin)) {
        buf[strcspn(buf, "\n")] = '\0';  // strip the newline if any
        p = reformat_with_spaces(buf);
        if (p == NULL) {
            fprintf(stderr, "out of memory\n");
            return 1;
        }
        puts(p);
        free(p);
    }
    return 0;
}


0 commentaires