2014-05-18 2 views
0

중복 하위 문자열을 제거하고 결합하려는 두 개의 문자열이 있습니다. 두 개의 연속 된 숫자는 하위 문자열을 구성합니다. 문자열 str1과 str2와를 고려중복 하위 문자열을 제거하여 두 문자열 결합

str1 = "#100#123#100#678" 
str2 = "#100#678#100#56" 

나뿐만 결합 된 문자열을 생성하고 싶습니다 :

comboStr = "#100#123#100#678#100#56" (i.e. I removed the duplicate #100#678) 

이 작업을 수행하는 가장 쉬운 방법은 무엇입니까? 정규 표현식을 사용하여이 작업을 수행 할 수있는 방법이 있습니까?

+0

아무 것도 시도해 보지 않으셨습니까? 가지고있는 것을 게시하십시오. –

+0

# 100 # 678이 (가) 삭제되었지만 추가 # 100이 (가) 아닌 이유는 무엇입니까? 문자열이 # 기호로 나뉘어 있습니까? – user184994

+0

두 번째 접두어가 붙은 첫 번째 접미사를 제거하고 그 접미사를 연결하려는 것을 의미합니까? –

답변

1

정규식이이 문제를 해결하는 좋은 방법이라고 생각하지 않습니다. Regexes는 #123 토큰을 찾는 데 유용 할 수 있지만 정규 표현식의 역 참조가 필요없는 방식으로 문제를 자체 문자열로 역 추적해야합니다.

나는 또한 이것을 해결하기위한 쉬운 방법 (코드 세 줄 에서처럼)이 없다고 생각한다.

문자열이 항상 (#\d+)* 패턴을 따르고 두 문자열을 결합 할 때 이음새에서 생성 된 쌍이 특별하지 않은 것으로 가정합니다. 즉 결과 쌍이 중복으로 간주 될 수 있습니다. 즉, 연결 제거와 쌍 분리를 구분할 수 있습니다.

문자열을 정수 목록으로 변환하고이 목록을 조작 한 다음 다시 결합하십시오. 이것은 약간의 작업이지만, 실제 코드를 사용하면 복제본을 쉽게 제거 할 수 있습니다. 충분히 복잡하기 때문에 비슷한 문자열을 자주 사용해야 할 때 편리 할 수 ​​있습니다.

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

/* 
*  Convert a string to a list of at most max integers. The 
*  return value is the number of integers in the list (which 
*  max be greater than max!) or -1 if the string is invalid. 
*/ 
int ilist_split(int *ilist, int max, const char *str) 
{ 
    const char *p = str; 
    int n = 0; 

    while (*p) { 
     int x; 
     int pos; 

     if (sscanf(p, "#%d %n", &x, &pos) < 1) return -1; 
     if (n < max) ilist[n] = x; 
     n++; 
     p += pos; 
    } 

    return n; 
} 

/* 
*  Convert a list of integers back to a string. The string 
*  is at most nbuf - 1 characters long and is assured to be 
*  zero-terminated if nbuf isn't 0. It is legal to pass NULL 
*  as char buffer if nbuf is 0. Returns the number of characters 
*  that would have been written ha dthe buffer been long enough, 
*  snprintf-style. 
*/ 
int ilist_join(const int *ilist, int n, char *buf, int nbuf) 
{ 
    int len = 0; 
    int i; 

    for (i = 0; i < n; i++) { 
     len += snprintf(buf + len, 
      nbuf > len ? nbuf - len : 0, "#%d", ilist[i]); 
    } 

    return len; 
} 

/* 
*  Auxliary function to find a pair in an inteher list. 
*/ 
int ilist_find_pair(int *ilist, int n, int a1, int a2) 
{ 
    int i; 

    for (i = 1; i < n; i++) { 
     if (ilist[i - 1] == a1 && ilist[i] == a2) return i - 1; 
    } 

    return -1; 
} 

/* 
*  Remove duplicate pairs from an integer list. The first 
*  pair is kept, subsequent pairs are deleted. Returns the 
*  new length of the array. 
*/ 
int ilist_remove_dup_pairs(int *ilist, int n) 
{ 
    int i, j; 

    j = 1; 
    for (i = 1; i < n; i++) { 
     int a1 = ilist[i - 1]; 
     int a2 = ilist[i]; 

     if (ilist_find_pair(ilist, i - 1, a1, a2) < 0) { 
      ilist[j++] = ilist[i]; 
     } else { 
      i++; 
     } 
    } 

    return j; 
} 



#define MAX 40 

int main() 
{ 
    const char *str1 = "#100#123#100#678"; 
    const char *str2 = "#100#678#100#56"; 
    char res[80]; 

    int ilist[MAX]; 
    int nlist; 

    /* convert str1 */ 
    nlist = ilist_split(ilist, MAX, str1); 
    if (nlist > MAX) nlist = MAX; 

    /* convert and concatenate str2 */ 
    nlist += ilist_split(ilist + nlist, MAX - nlist, str2); 
    if (nlist > MAX) nlist = MAX; 

    /* remove duplicate pairs */ 
    nlist = ilist_remove_dup_pairs(ilist, nlist); 

    /* convert back to string */ 
    ilist_join(ilist, nlist, res, sizeof(res)); 
    printf("%s\n", res); 

    return 0; 
} 
관련 문제