2013-12-12 5 views
0

나는이 작업 병합 정렬 알고리즘을 C로 가지고 있습니다. 그러나 정수에서만 작동합니다. int를 char로 변경하려고하면 segfault가 발생합니다. 나는이 코드를 변경해야합니다 당신이 좀 도와 주시겠습니까 문자열 C에서 문자 정렬 병합

, 그래서 나는 다음과 같이 머지 소트를 사용할 수 있습니다 내가

char*str = "test_string"; 
MergeSort(str, 0, strlen(str)-1); 

void Merge(int *array, int left, int mid, int right){ 

    int tempArray[right-left+1]; 
    int pos=0,lpos = left,rpos = mid + 1; 

    while(lpos <= mid && rpos <= right){ 
      if(array[lpos] <= array[rpos]){ 
        tempArray[pos++] = array[lpos++]; 
      } 
      else{ 
        tempArray[pos++] = array[rpos++]; 
      } 
    } 

    while(lpos <= mid) tempArray[pos++] = array[lpos++]; 
    while(rpos <= right)tempArray[pos++] = array[rpos++]; 

    int iter; 
    for(iter = 0;iter < pos; iter++){ 
      array[iter+left] = tempArray[iter]; 
    } 

    return; 
} 

void MergeSort(int *array, int left, int right){ 
    int mid = (left+right)/2; 

    if(left<right){ 
      MergeSort(array,left,mid); 
      MergeSort(array,mid+1,right); 
      Merge(array,left,mid,right); 
    } 
    return; 
} 

을 잃었어요합니다. 감사!

+1

안녕하세요 : 당신이 엄격하게 C를 사용하지 않는 경우 intchar 작동 기능을 만들기 위해 C++ 템플릿을 사용할 수 있습니다. 코드에서 오류를 발견하도록 사람들에게 요청하는 것은 특히 생산적이지 않습니다. 디버거를 사용하거나 인쇄 문을 추가하여 프로그램의 진행 상황을 추적하고 발생할 것으로 예상되는 것과 비교하여 문제를 격리해야합니다. 이 둘이 갈라지면 문제를 발견했습니다. (그리고 필요한 경우, [최소 테스트 케이스] (http://sscce.org)를 구성해야합니다.) –

답변

4

array의 선언을 두 기능 모두에서 int *에서 char *으로 변경하십시오. int[] 대신 tempArraychar[]으로 지정하십시오. 배열 끝에서 4x (또는 8x) 범위 밖의 메모리를 읽으려고하므로 seg-fault가 발생합니다. 다른 말로하면 char은 1 바이트 (일반적으로) 인 반면 int은 4 또는 8이므로 서로 다른 크기의 항목이 나란히 놓여 있습니다. 또한 문자열에 const *을 전달하지 마세요. char*str = "test_string";으로 문자열을 선언하면 일부 시스템에서 읽기 전용 메모리가 사용됩니다. 대신 char str[] = "test_string";을 사용하십시오. http://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part-1

+0

고마워, 나는 이러한 변화를 시도했지만 여전히 세그 폴트를 얻는다. 엄격하게 C를 사용하고 있으므로 C++ 템플릿을 사용할 수 없습니다. –

+2

그게 segfault가 일어나는 유일한 이유는 아닌지 나는 의심 스럽다. 그는 'const char *'문자열 리터럴 (거의 항상 읽기 전용 보호 메모리에 있음)을 수정하려고하는 함수에 전달하고 있습니다. 'char str [] = "MyString"'을 사용하면 작업 할 가능성이 있습니다. –

+0

@IwillnotexistIdonotexist 정말 고마워요, 이젠 작동합니다! –

0
#include <stdio.h> 

#include<ctype.h> 

#include<string.h> 

int Run_count=-1; 

int main (int argc , char *argv[]) 
{ 

    /* if you dont want to use argv, put the elements in A yourself, 
    size being the number of string*/ 

    /*L --> left side, R --> right side*/ 

    int i = 0; 

    int size = argc-1; 

    char *A[argc-1]; 

    for(i=1;i<=argc;i++){*(A+i-1) = argv[i];} 

    Caller(A,size); 

    for(i=0;i<size;i++){ 

     printf("%s\n", A[i]); 

    } 

    printf("%d",Run_count); 
} 

int Caller(char* A[] , int n){ 

    Run_count++; 

    int sizeL, sizeR ,i; 

    char *L[n/2+1] , *R[n-n/2+1]; 

    if (n < 2){return 1;} 

    sizeL = n/2; 
    sizeR = n - sizeL; 

    for(i=0;i<sizeL;i++) {L[i] = *(A+i);} 
    for(i=0;i<n - n/2;i++) {R[i] = *(A+i+n/2);} 

    Caller(L, sizeL); 
    Caller(R, sizeR); 
    merger(L,sizeL, R,sizeR, A); 
} 

void merger(char* L[], int lengthL , char* R[] , int lengthR , char *A[]){ 

    int i, j, k ,t =0 ; 

    for(k = 0 , j = 0; k < lengthL && j < lengthR ;t++){ 

     if(compare(*(L+k),*(R+j))){ 
      *(A+t) = *(L+k); 
      k++;} 

     else{*(A+t) = *(R+j);j++;} 
    } 

    while(k < lengthL){ 
     *(A+t) = *(L+k); 
     k++;t++; 
     } 

    while(j < lengthR){ 
     *(A+t) = *(R+j); 
     j++;t++;} 
} 

int compare(char *line1 , char *line2) 
{ 
    int i; 

    for(i = 0;*(line1 + i) != '\0' && *(line2 + i) != '\0' ;){ 
     if(isdigit(*(line1+i)) && isalpha(*(line2+i))){return 0;} 

     else if(isdigit(*(line2+i)) && isalpha(*(line1+i))){return 1;} 

     else if(*(line1 + i) > *(line2 + i)){return 0;} 

     else if(*(line1 + i) == *(line2 + i)){i++;} 

     else{return 1;} 
    } 
} 
+1

에는 stdio & ctype ...이 포함되어 있습니다. 또한 compare 함수는 alphabets와 비교하여 숫자에 더 많은 가중치를 부여합니다. –