首页 > 解决方案 > 从 char 数组中删除连续的元音

问题描述

所以我有一个作业要求使用附加字符串删除字符串中的所有元音。我的问题是,即使我有一些像 aabbbceee 这样的连续元音,我也想让它工作,我希望它打印 bbbc 但它会打印一些奇怪的东西。

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

bool isVowel(char a) { 
    if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u') return 
       true;
    return false;
}

void main () {
    char* sir = (char*)calloc(256, sizeof(char));

    scanf("%[^\n]s", sir);

    int numarVocale = 0, lungimeSir = strlen(sir);
    for (int i = 0; i < lungimeSir; ++i) {
        if (isVowel(sir[i])) numarVocale++;
    }

    for (int i = 0; i < lungimeSir; ++i) {
        if (isVowel(sir[i])) {
            int pozitie = i;
            pozitie++;
            while (isVowel(sir[pozitie]) && pozitie < lungimeSir) {
               pozitie++;
            }
            sir[i] = sir[pozitie];
            sir[pozitie] = '\0';
       }
   }

   sir = realloc(sir, lungimeSir - numarVocale);

   printf("The string after I deleted the vowels: %s", sir);
}

我的想法是找到第一个元音,然后保存它的位置,如果下一个字符也是一个元音循环,直到我找到一个辅音。

标签: c

解决方案


无需事先计算元音的数量。

只需执行一个循环并一次处理一个字符。

没有必要使用strlen. 如果当前字符是 EOS(例如 0),则停止循环。

重要的一点是不要复制当前字符,如果元音。

维护两个索引变量:(1)源/输入索引(例如isrc)和(2)目标/输出索引(例如idst)。

idst 只有在复制字符(即非元音)时才前进。

一个改进是复制字符 if idstis isrc。(即您只是将相同的字符复制到自身)。但是,您仍然需要增加输出索引 ( idst)。

而且,您必须在循环结束时添加一个新的 EOS(字符串终止符)。

这是重构的代码(带有一些注释):

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

bool
isVowel(char a)
{
    if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')
        return true;
    return false;
}

void
main(void)
{
// NOTE/BUG: don't cast the result of malloc
#if 0
    char* sir = (char*)calloc(256,sizeof(char));
#else
    char* sir = calloc(256,sizeof(*sir));
#endif

    scanf("%[^\n]s",sir);
    printf("The string before I deleted the vowels: '%s'\n",sir);

    int isrc = 0;
    int idst = 0;

    while (1) {
        // get next char (and advance the source index)
        char chr = sir[isrc++];

        // end of string
        if (chr == 0)
            break;

        // skip any vowel
        if (isVowel(chr))
            continue;

        // copy over char [if different]
        // NOTE: using the "if" is a nicety/speedup
        if (idst != (isrc - 1))
            sir[idst] = chr;

        // advance destination index
        ++idst;
    }

    // add EOS to new [possibly] shorter string
    sir[idst] = 0;

    // trim the output string
    sir = realloc(sir,idst + 1);

    printf("The string after I deleted the vowels: '%s'\n",sir);
}

推荐阅读