具有不同长度字符串的交错功能

时间:2014-09-10 02:49:11

标签: c pointers

我正在尝试构建一个函数,无论大小如何都将两个字符串交错在一起(虽然可以假设它不到100个字符)并输出指向新字符串的指针。

char* interleaved(const char* s1, const char* s2){
    char *word = malloc (sizeof (char) * 100);
    const char *p = s1;
    const char *p2 = s2;
    int i = 0;
    while(*p != '\0' || *p2 != '\0'){
        if(i%2 == 0){
            word[i] = *p;
            p++;
        }
        if(i%2 == 1){
            word[i] = *p2;
            p2++;
        }
        i++;
    }
    if(*p == '\0'){
        while(*p2 != '\0'){
            word[i] = *p2;
            p2++;
            i++;
        }
    }
    if(*p2 == '\0'){
        while(*p != '\0'){
            word[i] = *p;
            p++;
            i++;
        }
    }
    word[i] = '\0';
    return word;
}

目前,如果两个字符串长度相同,它将起作用,例如'dog'和'cat'将产生'dcoagt',但如果字符串不均匀,例如'dogbird'和'cat',我会得到'dcoagtb',并且如果第二个字符串更长,我就得到'dcoagt'。在原来的while循环之后我的两个if语句中出现了一些错误,但是我不确定它是什么,有人可以看看并帮助我吗?

干杯

2 个答案:

答案 0 :(得分:3)

第一个循环应该使用&&而不是||

while(*p != '\0' && *p2 != '\0')

使用&&会在字符串耗尽时立即停止。使用||会继续,直到两个字符串都用完为止。这很糟糕,因为较短的弦乐指针会从最后一直延伸到无人区域。

答案 1 :(得分:0)

John Kugelmananswer已解决了主要问题,但代码相当冗长。你可以写:

char *interleaved(const char *s1, const char *s2)
{
    char *word = malloc(strlen(s1) + strlen(s2) + 1);
    if (word == 0)
        return 0;
    int i = 0;
    const char *p1 = s1;
    const char *p2 = s2;
    while (*p1 != '\0' && *p2 != '\0')
    {
        word[i++] = *p1++;
        word[i++] = *p2++;
    }
    while (*p1 != '\0')
        word[i++] = *p1++;
    while (*p2 != '\0')
        word[i++] = *p2++;
    word[i] = '\0';
    return word;
}

请注意,这会检查内存分配是否成功。代码分配了必要的空间量;它既不会在传递短字符串时浪费空间,也不会在传递长字符串时失败。

循环更紧凑,充分利用++运算符。 if测试是多余的。在主循环结束时,将执行以下两个循环中的至多一个循环的主体(一个用于较长的字符串,或者如果输入字符串的长度相同,则不执行)。

我保留p1(好吧,将p重命名为p1)和p2,但代码同样可以使用s1和{{1相反。我还保留了下标s2并使用了i符号;在word[i++]代替char *dst = word;代替*dst++当然可以使用word[i++]然后*dst代替word[i]。这甚至可能在显微镜下更有效 - 但这不是使用符号的理由;另一方面,对称性是使用符号的原因。

这些变化导致:

char *interleaved(const char *s1, const char *s2)
{
    char *word = malloc(strlen(s1) + strlen(s2) + 1);
    if (word == 0)
        return 0;
    char *dst = word;
    while (*s1 != '\0' && *s2 != '\0')
    {
        *dst++ = *s1++;
        *dst++ = *s2++;
    }
    while (*s1 != '\0')
        *dst++ = *s1++;
    while (*s2 != '\0')
        *dst++ = *s2++;
    *dst = '\0';
    return word;
}