私はマージソートを実装し、それをこの codechef 問題の解決策として使用しました。ここに提出物があります。コードは以下に配置されます。
実行が遅い原因と思われる問題は、IO がmain
関数内で遅いことです。入力される要素の数を知っているので、私が行っている方法ではなく、入力を読み取るためのより高速な方法が必要です。
関数で使用しているよりも高速な IO メソッドはありmain
ますか? バッファの使用について聞いたことがfgets
ありますが、バッファsscanf
が高速かどうかはわかりません。
コード例は役に立ちます。
#include<stdio.h>
#include<stdlib.h>
void merge_parts(int arr[], int length)
{
int *ans;
int i, j, k;
int temp = length/2;
ans = malloc(sizeof(int) * length);
//This while and next if-else puts the merged array into temporary array ans
for (j = temp, i = k = 0; (i < temp && j < length); k++){
ans[k] = (arr[i] < arr[j]) ? arr[i++] : arr[j++];
}
if(i >= temp){
while(j < length){
ans[k++] = arr[j++];
}
}
else{
while(i < temp){
ans[k++] = arr[i++];
}
}
//This while loops puts array ans into original array arr
for(i = 0; i < length; i++){
arr[i] = ans[i];
}
free(ans);
}
void merge_sort(int arr[], int length)
{
if(length > 1)
{
merge_sort(&arr[0], (length/2));
merge_sort(&arr[length/2], (length - length/2));
merge_parts(arr, length);
}
}
int main()
{
int length;
int *arr;
scanf("%d", &length);
arr = malloc(sizeof(int) * length);
for(int i = 0; i < length; i++)
scanf("%d", &arr[i]);
merge_sort(arr, length);
for(int i = 0; i < length; i++)
printf("%d ", arr[i]);
free(arr);
return 0;
}
EDIT3:
[EDIT AND EDIT2 は関連性がなくなったため削除しました]
私が使用しているmerge_sortアルゴリズム
void merge_parts(int arr[], int length)
{
int ans[length];
int i, j, k;
int temp = length/2;
//This while and next if-else puts the merged array into temporary array ans
for (j = temp, i = k = 0; (i < temp && j < length); k++){
ans[k] = (arr[i] < arr[j]) ? arr[i++] : arr[j++];
}
if(i >= temp){
while(j < length){
ans[k++] = arr[j++];
}
}
else{
while(i < temp){
ans[k++] = arr[i++];
}
}
//This while loops puts array ans into original array arr
for(i = 0; i < length; i++){
arr[i] = ans[i];
}
}
void merge_sort(int arr[], int length)
{
if(length > 1)
{
merge_sort(&arr[0], (length/2));
merge_sort(&arr[length/2], (length - length/2));
merge_parts(arr, length);
}
}
merge1.c
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#define SORTING_ALGO_CALL merge_sort
char buffer[4096];
int bufcount;
int bufpos;
int get_next_char()
{
if (!bufcount)
{
bufcount = fread(buffer, 1, 4096, stdin);
bufpos = 0;
if (!bufcount){
return EOF;
}
}
bufcount--;
return buffer[bufpos++];
}
int readnum()
{
int res = 0;
char ch;
do
{
ch = get_next_char();
} while (!isdigit(ch) && ch != EOF);
if (ch == EOF){
return 0xbaadbeef; // Don't expect this to happen.
}
do
{
res = (res * 10) + ch - '0';
ch = get_next_char();
} while(isdigit(ch));
return res;
}
int main()
{
clock_t time1, time2;
double time_taken;
//FIRST READ
time1 = clock();
int length = readnum();
while (length < 1)
{
printf("\nYou entered length = %d\n", length);
printf("\nEnter a positive length: ");
length = readnum();
}
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nReading length = %f\n", time_taken);
time1 = clock();
int *arr;
if ((arr = malloc(sizeof(int) * length)) == NULL)
{
perror("The following error occurred");
exit(-1);
}
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nAllocating array = %f\n", time_taken);
time1 = clock();
for (int i = 0; i < length; i++){
arr[i] = readnum();
}
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nReading array = %f\n", time_taken);
time1 = clock();
SORTING_ALGO_CALL(arr, length);
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nSorting array = %f\n", time_taken);
time1 = clock();
/*
for (int i = 0; i < length; i++){
printf("%d ", arr[i]);
}
*/
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nPrinting Sorted array = %f\n", time_taken);
time1 = clock();
free(arr);
//SECOND READ, PRINT
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nFreeing array = %f\n", time_taken);
return 0;
}
merge2.c
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SORTING_ALGO_CALL merge_sort
int main()
{
clock_t time1, time2;
double time_taken;
//FIRST READ
time1 = clock();
int length;
scanf("%d", &length);
while (length < 1)
{
printf("\nYou entered length = %d\n", length);
printf("\nEnter a positive length: ");
scanf("%d", &length);
}
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nReading length = %f\n", time_taken);
time1 = clock();
int *arr;
if ((arr = malloc(sizeof(int) * length)) == NULL)
{
perror("The following error occurred");
exit(-1);
}
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nAllocating array = %f\n", time_taken);
time1 = clock();
for (int i = 0; i < length; i++){
scanf("%d", &arr[i]);
}
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nReading array = %f\n", time_taken);
time1 = clock();
SORTING_ALGO_CALL(arr, length);
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nSorting array = %f\n", time_taken);
time1 = clock();
/*
for (int i = 0; i < length; i++){
printf("%d ", arr[i]);
}
*/
//SECOND READ, PRINT AND NEXT FIRST READ
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nPrinting Sorted array = %f\n", time_taken);
time1 = clock();
free(arr);
//SECOND READ, PRINT
time2 = clock();
time_taken = (double)(time2 - time1) / CLOCKS_PER_SEC;
printf("\nFreeing array = %f\n", time_taken);
return 0;
}
merge1.c と merge2.c の両方に、merge-sort の 2 つの関数が含まれています。
2 つのファイルの最悪のケース (降順) の入力を生成するために使用しているファイル。
#include<stdio.h>
int main()
{
int j = 100000;
printf("%d\n", j);
for(int i = j; i > 0; i--)
printf("%d\n", i);
return 0;
}
merge1.c のタイミング結果
Reading length = 23.055000
Allocating array = 0.000000
Reading array = 0.010000
Sorting array = 0.020000
Printing Sorted array = 0.000000
Freeing array = 0.000000
merge2.c のタイミング結果
Reading length = 22.763000
Allocating array = 0.000000
Reading array = 0.020000
Sorting array = 0.020000
Printing Sorted array = 0.000000
Freeing array = 0.000000