【问题标题】:Merge sort of characters in string C合并字符串C中的字符
【发布时间】:2013-12-30 06:47:23
【问题描述】:

我在 C 中有这个工作的合并排序算法。但它只适用于整数。当我尝试将 int 更改为 char 时,我遇到了段错误。

你能帮我吗,我应该在这段代码中改变什么,所以我可以像这样使用 MergeSort:

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;
}

我迷路了。谢谢!

【问题讨论】:

  • 嗨。要求人们发现代码中的错误并不是特别有效。您应该使用调试器(或添加打印语句)来隔离问题,方法是跟踪程序的进度,并将其与您期望发生的情况进行比较。一旦两者发生分歧,你就发现了你的问题。 (然后如果有必要,你应该构造一个minimal test-case。)

标签: c string sorting merge


【解决方案1】:
#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;}
    }
}

【讨论】:

  • include stdio & ctype ,, 与字母相比,compare 函数赋予数字更多的权重,如函数 compare 所示
【解决方案2】:

在两个函数中将array 的声明从int * 更改为char *。将tempArray 设为char[] 而不是int[]。您正在尝试读取数组末尾超出范围的 4x(或 8x)内存,因此出现 seg-fault。换句话说,char 是 1 个字节(通常),而 int 是 4 或 8 个字节,因此您正在查看彼此相邻堆叠的不同大小的项目。另外,不要为您的字符串传入const *。将字符串声明为 char*str = "test_string"; 意味着在某些系统上是只读内存。请改用char str[] = "test_string";。如果您不使用严格的 C,则可以使用 C++ 模板来制作适用于 intchar 的函数:http://www.codeproject.com/Articles/257589/An-Idiots-Guide-to-Cplusplus-Templates-Part-1

【讨论】:

  • 谢谢,我尝试了这些更改,但仍然出现段错误。我使用的是严格的 C,所以我不能使用 C++ 模板。
  • 我怀疑这是发生段错误的唯一原因。他将const char* 字符串文字(几乎总是在只读受保护的内存中)传递给试图修改它的函数。如果他使用char str[] = "MyString",它就有机会工作。
  • @Marek Teuchner 没问题!
  • @IwillnotexistIdonotexist,将您的建议纳入答案。谢谢你的好点。
猜你喜欢
  • 2023-03-09
  • 2011-05-23
  • 2022-07-01
  • 1970-01-01
  • 2018-07-22
  • 2016-07-31
  • 1970-01-01
  • 2011-05-31
  • 2011-01-26
相关资源
最近更新 更多