合并两个字符串,删除重复的子字符串

时间:2014-05-22 16:34:09

标签: c

我想要组合两个字符串,删除重复的子字符串。请注意,每两个连续的数字构成一个子字符串。考虑字符串str1和str2:

str1 ="#1#.1.2.3#1#.6.7.8" str2 ="#1#.6.7.8#1#.5.6"

我想生成一个组合字符串:

comboStr ="#1#.1.2.3#1#.6.7.8#1#.5.6" (即我删除了副本#1#.6.7.8)。

我写了一个小函数来执行此操作:

char *combine (char *nodehashkey ,char *ngbrhashkey)
{
        char *suffix, *combo_hashkey;
        char prefix[5], token[15];
        short qid;

    short len = strlen(nodehashkey);

    combo_hashkey = (char*) malloc(sizeof(char) * (len+1));
    strcpy(combo_hashkey, nodehashkey);

    short offset = len;

    sscanf(nodehashkey, "#%hd#", &qid);

    sprintf(prefix, "#%hd#", qid);
    printf("prefix: %s\n", prefix);

    suffix = strtok(ngbrhashkey, prefix);

    while (suffix != NULL)
    {
            strcpy(token, prefix);
            strcpy(token + strlen(prefix), suffix);
            int token_len = strlen(token);

            if(strstr(nodehashkey, token) == NULL)
            {
                    if(!(combo_hashkey = (char*) realloc (
                    combo_hashkey, sizeof(char) * (offset+token_len+1))))
                    printf("malloc failed!");

                    strncpy(combo_hashkey + offset, token, token_len+1);
                    offset += token_len;
                    combo_hashkey[offset] = '\0';
            }

            suffix = strtok(NULL, prefix);
    }

    return combo_hashkey;

}

为了测试它,我尝试了以下内容。虽然,前两个组合调用产生了正确的组合字符串,但第三个调用没有。它不是产生#1#。1.6#1#。2.4#1#.3.5,而是产生#1#。1.6#1#。#2.4#1#。#1#。#3.5

int main (int argc, char *argv[])
{
    char *str1 = malloc(sizeof(char) * 8);
    strcpy(str1, "#1#.1.6");

    char *str2= malloc(sizeof(char) * 8);
    strcpy(str2, "#1#.2.4");

    char *str3 = malloc(sizeof(char) * 8);
    strcpy(str3, "#1#.3.5");

    str2 = combine(str1, str2);

    str3 = combine(str1, str3);

    char *weird = combine(str2, str3);

    printf("weird: %s\n", weird);

}

我再次追踪了这个功能,我无法找到额外的#1#.6来自哪里。

1 个答案:

答案 0 :(得分:0)

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

char *combine (const char *nodehashkey, const char *ngbrhashkey){
    int i, dup, len, pos_count = 0;
    const char *p1, *p2, *pos[64];
    char *combo_hashkey, *p3;

    if(!nodehashkey || !ngbrhashkey)
        return NULL;

    //store key position
    pos[0] = p1 = nodehashkey;
    while(*p1){
        sscanf(p1, "#%*d#%*[.0123456789]%n", &len);
        pos[++pos_count] = (p1 += len);
    }
    len = p1 - nodehashkey;
    p2 = ngbrhashkey;
    p3 = combo_hashkey = malloc(len + strlen(p2) + 1);
    memcpy(p3, nodehashkey, len);
    p3 += len;
    while(*p2){
        sscanf(p2, "#%*d#%*[.0123456789]%n", &len);
        for(dup=i=0;i<pos_count;++i){
            if(pos[i+1]-pos[i] == len && strncmp(pos[i], p2, len)==0){
                dup = 1;
                break;
            }
        }
        if(!dup){
            memcpy(p3, p2, len);
            p3 += len;
        }
        p2 += len;
    }
    *p3 = '\0';
    return combo_hashkey;
}

int main(){
    char *str1, *str2, *str3;
    str1 = combine("#1#.1.2.3#1#.6.7.8", "#1#.6.7.8#1#.5.6");
    printf("%s\n", str1);//#1#.1.2.3#1#.6.7.8#1#.5.6
    free(str1);

    str2 = combine("#1#.1.6", "#1#.2.4");
    str3 = combine("#1#.1.6", "#1#.3.5");
    printf("str2:%s\n", str2);
    printf("str3:%s\n", str3);

    char *weird = combine(str2, str3);

    printf("weird: %s\n", weird);//weird: #1#.1.6#1#.2.4#1#.3.5
    free(str2);free(str3);free(weird);
    return 0;
}