简体   繁体   中英

add additional letters in a string if there are two same letters beside each other

I'm trying to add an additional letter if there are two equal letters beside each other. That's what I was thinking, but it doesn't put in an x between the two letters; instead of that, it copies one of the double letters, and now I have, for example, MMM instead of MXM.

for (index_X = 0; new_text[index_X] != '\0'; index_X++)
  {
    if (new_text[index_X] == new_text[index_X - 1])
    {
      double_falg = 1;
    }
    text[index_X] = new_text[index_X];
  }
  
  
  if (double_falg == 1)
  {
    for (counter_X = 0; text[counter_X] != '\0'; counter_X++)
    {
      transfer_X = counter_X;
      if (text[transfer_X - 1] == text[transfer_X])
      {
        text_X[transfer_X] = 'X';
        cnt_double++;
        printf("%c\n", text[transfer_X]);

      }
      text_X[transfer_X] = text[transfer_X - cnt_double];
    }
    printf("%s\n", text_X);
  }

If you're trying to create the modified array in text_X , copying data from new_text and putting an X between adjacent repeated letters (ignoring the possibility that the input contains XX ), then you only need:

char new_text[] = "data with appalling repeats";
char text_X[SOME_SIZE];
int out_pos = 0;

for (int i = 0; new_text[i] != '\0'; i++)
{
    text_X[out_pos++] = new_text[i];
    if (new_text[i] == new_text[i+1])
        text_X[out_pos++] = 'X';
}
text_X[out_pos] = '\0';

printf("Input:  [%s]\n", new_text);
printf("Output: [%s]\n", text_X);

When wrapped in a basic main() function (and enum { SOME_SIZE = 64 }; ), that produces:

Input:  [data with appalling repeats]
Output: [data with apXpalXling repeats]

To deal with repeated X's in the input, you could use:

text_X[out_pos++] = (new_text[i] == 'X') ? 'Q' : 'X';

It seems that your approach is more complicated than needed - too many loops and too many arrays involved. A single loop and two arrays should do.

The code below iterates the original string with idx to track position and uses the variable char_added to count how many extra chars that has been added to the new array.

#include <stdio.h>

#define MAX_LEN 20

int main(void) {
    char org_arr[MAX_LEN] = "aabbcc";
    char new_arr[MAX_LEN] = {0};
    int char_added = 0;
    int idx = 1;
    new_arr[0] = org_arr[0];
    if (new_arr[0])
    {
        while(org_arr[idx])
        {
            if (org_arr[idx] == org_arr[idx-1])
            {
                new_arr[idx + char_added] = '*';
                ++char_added;
            }
            new_arr[idx + char_added] = org_arr[idx];
            ++idx;
        }
    }
    puts(new_arr);
    return 0;
}

Output:

a*ab*bc*c

Note: The code isn't fully tested. Also it lacks out-of-bounds checking.

There is a lot left to be desired in your Minimal, Complete, and Verifiable Example (MCVE) (MCVE). However, that said, what you will need to do is fairly straight-forward. Take a simple example:

"ssi"

According to your statement, you need to add a character between the adjacent 's' characters. (you can use whatever you like for the separator, but if your input are normal ASCII character, then you can set the current char to the next ASCII character (or subtract one if current is the last ASCII char '~' )) See ASCII Table and Description .

For example, you could use memmove() to shift all characters beginning with the current character up by one and then set the current character to the replacement. You also need to track the current length so you don't write beyond your array bounds.

A simple function could be:

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

#define MAXC 1024

char *betweenduplicates (char *s)
{
    size_t len = strlen(s);                         /* get length to validate room */
    
    if (!len)                                       /* if empty string, nothing to do */
        return s;
    
    for (int i = 1; s[i] && len + 1 < MAXC; i++)    /* loop until end, or out of room */
        if (s[i-1] == s[i]) {                           /* adjacent chars equal? */
            memmove (s + i + 1, s + i, len - i + 1);    /* move current+ up by one */
            if (s[i-1] != '~')                          /* not last ASCII char */
                s[i] = s[i-1] + 1;                      /* set to next ASCII char */
            else
                s[i] = s[i-1] - 1;                      /* set to previous ASCII char */
            len += 1;                                   /* add one to len */
        }
    
    return s;       /* convenience return so it can be used immediately if needed */
}

A short example program taking the string to check as the first argument could be:

int main (int argc, char **argv) {
    
    char str[MAXC];
    
    if (argc > 1)                           /* if argument given */
        strcpy (str, argv[1]);              /* copy to str */
    else
        strcpy (str, "mississippi");        /* otherwise use default */
    
    puts (str);                             /* output original */
    puts (betweenduplicates (str));         /* output result */
}

Example Use/Output

$ ./bin/betweenduplicated
mississippi
mistsistsipqpi

or when there is nothing to replace:

$ ./bin/betweenduplicated dog
dog
dog

Or checking the extremes:

$ ./bin/betweenduplicated "two  spaces  and  alligators  ~~"
two  spaces  and  alligators  ~~
two ! spaces ! and ! almligators ! ~}~

There are a number of ways to approach it. Let me know if you have further questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM