스레드와 병합 정렬을 구현할 때 잘못된 출력이 표시되고 무엇이 잘못되었는지 파악할 수 없습니다.

달 바코 더

나는이 문제를 3 일 정도 겪었고 왜 잘못된 출력이 나오는지 알아 내기 위해 전체 코드를 정리했습니다. 이 프로그램의 목적은 스레드를 사용하여 병합 정렬을 수행하는 것입니다. 첫 번째 부분은 사용자가 입력하는 여러 세그먼트로 요소를 병렬로 정렬하는 것입니다. 테스트 할 입력은 2, 5, 10뿐입니다. 정렬 할 배열은 항상 무작위로 생성 된 숫자의 50 int 배열입니다. 세그먼트가 입력되면 내 코드가 제대로 작동합니다 (맨 위에있는 '세그먼트'변수로 표시됨). main)은 2입니다. 그러나 세그먼트를 5 또는 10으로 변경하면 끝에 정렬 된 배열이 표시되지 않습니다. 나는 print 문을 사용하여 디버깅을 시도했지만 (내가 주석 처리했지만 여전히 볼 수 있음) 처음 두 번의 병합 반복 중에 문제가있는 것 같습니다. 어떤 이유로 이러한 병합 반복의 결과는 순서가 맞지 않으며 전달 된 원래 배열에 중복으로 존재하지 않는 중복 번호를 포함합니다. 정렬 방법과 병합 방법은 배열을 전달하고 스레드를 사용하지 않을 때 제대로 작동하지만 스레드를 사용하면 설명 할 수없는 동작이 발생합니다. 아래는 전체 프로그램입니다. 50 배열을 병합하려면 다음을 수행해야합니다.

  • 배열을 5 개씩 10 개의 세그먼트로 분할하고 각 세그먼트를 정렬합니다.
  • 세그먼트를 쌍으로 라운드로 전달하십시오. 그래서 하나는 한 세그먼트에서 0-5 세그먼트를, 다른 세그먼트에서 5-10, 10-15 및 15-20, 20-25 및 25-30, 그리고 40-45 및 45-50에 도달 할 때까지 계속해야합니다.
  • 그런 다음 라운드 2로 이동하여 라운드 1과 동일한 작업을 수행하지만 세그먼트를 10 쌍으로 통과합니다. 따라서 0-10과 10-20, 20-30 및 30-40, 10의 마지막 부분은 그대로 둡니다.
  • 3 라운드는 세그먼트를 통과하여 20 쌍으로 병합합니다 : 0-20 및 20-40, 그런 다음 중지합니다.
  • 마지막으로 세그먼트 0-40을 40-50과 병합해야합니다.

내 프로그램 : (주로 내 주요 기능에 집중해야하고 정렬도 괜찮고 병합도 괜찮아 보이지만 혹시라도 포함 시켰습니다)

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

/**
 * Struct to contain an array partition as well as the size of the    partition.
 * Use struct to pass multiple parameters to pthread_create
 */
struct array_struct{
int *partition;
int size;
};

/**
 * Struct that contains two arrays (should be sorted) to merge
 * Use struct to pass multiple parameters to pthread_create
*/
struct arrays_to_merge{
int *array1;
int *array2;
int size1;
int size2;
};

//comparison function to use with qsort, sorts in ascending order
int cmpfunc (const void * a, const void * b)
{
   return ( *(int*)a - *(int*)b );
}



/**
 * Method that takes a struct containing a pointer to the first int in          an array 
 * partition, as well as the partition size. Object must be type void, used with pthread_create
 * @param pointer to the partition object. Type void
  */
void *sort(void *object){

struct array_struct *structure;
structure = (struct array_struct *) object;

int *array = structure->partition;
int size = structure->size;

int *i, j = 0;
qsort(array, size, sizeof(int), cmpfunc);
printf("Sorted %d elements.\n", size);
}

void *merge(void * object){

struct arrays_to_merge *arrays_struct;
arrays_struct = (struct arrays_to_merge *) object;


int *array1 = arrays_struct->array1;
int *array2 = arrays_struct->array2;
int size1 = arrays_struct->size1;
int size2 = arrays_struct->size2;
int tempArray[size1 + size2];

int i = 0, j = 0, k = 0, duplicates = 0;

while (i < size1 && j < size2) {
    // printf("Merge number : %d  Comparing %d and %d\n", mergenumber, array1[i], array2[j]);
    if (array1[i] <= array2[j]) {
        // printf("Picking %d\n", array1[i]);
        tempArray[k] = array1[i];
        if (array1[i] == array2[j])
        {
            duplicates++;
        }
        i++;
        k++;
    }else {
         // printf("Merge number : %d Picking %d\n", mergenumber, array2[j]);
        tempArray[k] = array2[j];
        k++; 
        j++;
    }
}
while (i < size1) {
    // printf("Merge number : %d   left over Picking %d\n", mergenumber, array1[i]);
    tempArray[k] = array1[i];
    i++;
    k++;
}
while (j < size2) {
    // printf("Merge number : %d   left over Picking %d\n", mergenumber, array2[j]);
    tempArray[k] = array2[j];
    k++;
    j++;
}

array1 = arrays_struct->array1;

for(i = 0; i < size1 + size2; i++){
    array1[i] = tempArray[i];
}

printf("Merged %d and %d elements with %d duplicates\n", size1, size2, duplicates);


}




//return an array of size 50 with randomly generated integers
int *randomArray(){

srand(time(NULL));
static int array[50];
int i;
for (i = 0; i < 50; ++i){
    array[i] = rand() % 51;
}

return array;
}



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

int segments = 10;//make equal to argv input after testing
pthread_t threads[segments];



int i, *numbers; //iterator i, and pointer to int array 'numbers'
numbers = randomArray(); //return an array of random ints and store in 'numbers'

struct array_struct array[segments];

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

    int *partition = numbers + (i * (50/segments));//obtain the first index of partition
    array[i].partition = partition;
    array[i].size = 50/segments;
    pthread_create(&threads[i], NULL, sort, (void *) &array[i]);

}

for(i = 0; i < segments; i++){
    pthread_join(threads[i], NULL);
}


int count = segments;

struct arrays_to_merge arrays[segments];    
int j;
int size = 50/ segments;

while(count > 1){

    for(i = 0, j = 0; i < count-1; j++, i += 2){
        int *partition = numbers + (i * (size));
        int *partition2 = numbers + (i+1 * (size));

        arrays[j].array1 = partition;
        arrays[j].array2 = partition2;
        arrays[j].size1 = size;
        arrays[j].size2 = size;
        pthread_create(&threads[j], NULL, merge, (void *) &arrays[j]);

    }
    for(i = 0; i < j; i++){
        pthread_join(threads[i], NULL);
    }

    size = size * 2;
    count = count/2;

}

if(segments != 2){//for segments = 2, no need for his
    int *partition = numbers;
    int *partition2 = numbers + (size);
    arrays[0].array1 = partition;
    arrays[0].array2 = partition2;
    arrays[0].size1 = size;
    arrays[0].size2 = 50 - size;
    pthread_create(&threads[0], NULL, merge, (void *) &arrays[0]);

    pthread_join(threads[0], NULL); 
}   


for(i = 0; i < 50; i++){
    printf("%d\n", numbers[i]);
}

pthread_exit(NULL);





return 0;
}

이것은 내 출력입니다.

Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Sorted 5 elements.
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 5 and 5 elements with 0 duplicates
Merged 10 and 10 elements with 3 duplicates
Merged 10 and 10 elements with 1 duplicates
Merged 20 and 20 elements with 7 duplicates
Merged 40 and 10 elements with 17 duplicates
0
6
9
11
12
13
13
14
15
17
19
23
25
25
25
26
26
28
28
28
28
30
32
32
32
34
39
41
41
44
44
44
44
44
50
50
9
15
50
9
15
19
26
50
50
9
15
11
14
50

긴 텍스트 벽에 대해 죄송합니다.이 문제를 스스로 해결하려고 시도했지만 수많은 머리카락을 뽑아 냈지만 이해할 수 없습니다. 내가 뭘 잘못하고 있는지 알아 내도록 도와주세요. 내가 생각 하는 방식 중 하나에 내 문제 거짓말은 내가 스레드, 또는 내 병합 기능을 결합하지만 확실히, 난 그냥 전체를 포함 질수 있기 때문에거야.

PP

시간이 좀 걸렸지 만 마침내 도착했습니다. :)

문제는 다음 줄에 있습니다.

    int *partition2 = numbers + (i+1 * (size));

(연산자 우선 순위로 인해)와 동일합니다.

int *partition2 = numbers + (i + size);

그리고 당신이 원하는 것이 아닙니다.

그것은해야한다:

    int *partition2 = numbers + ((i+1) * (size));

추가 괄호를 확인하십시오. 그렇지 않으면 partition2인덱스가 잘못 계산됩니다. 따라서 배열의 다른 부분과 병합 됩니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관