我正在研究我想要优化的代码。代码是关于按照第二个数字的升序排序双数组。
第一个输入是整数N,第二个是大小为N * 2的二维数组(称之为c),然后我们按c[.][1]
的升序排序数组,当有相等的元素时,说是否c[i][1]==c[j][1]
,对于两个整数i
和j
,我们按照第一列元素的升序对这些元素进行排序,因此c[i][1]
低于c[j][1]
c[i][1]<c[j][1]
{1}}。我们来举个例子:
input
3
2 3
1 3
4 2
output
4 2
1 3
2 3
事实是代码需要在不到0.5秒的时间内运行,而我的代码实际上太慢了。这是
#include <stdio.h>
#include <stdlib.h>
//determining the index of the max elments in an array
int max(int i, int N, int **c)
{
int j=0;
int M=0;
for(j=0;j<i;j++)
{if(c[j][1]>c[M][1]){M=j;}else{}}
return M;
}
int main ()
{
//integers used for the loops
int i;
int j;
//the size of the 2D array is N*2
int N;
scanf("%d",&N);
int **c;
int mx;
int maxi;
//this array is the output, thath is the 2D array sorted
int e[N][2];
//2D array we want to sort
c = malloc(N*sizeof(int*));
for (i=0;i<N;i++)
{
c[i] = malloc(2*sizeof(int));
for (j=0;j<2;j++)
{
scanf("%d",&c[i][j]);
}
}
//at the first step, we have initialized the value of the max
maxi=max(N,N,c);
for(i=0;i<N;i++)
{
//we sort the c[.][1], and we take the max (called 'mx') of the array. At each step of the loop, we throw away the max from the array c[.][1] (we mean the max found at the precedent step of the loop)
mx=max(N-i,N,c);
//Here, we look at the multiple occurence of the max, if there are, we sort the c[.][0] for which c[.][1]=c[mx][1] by ascending order
if(maxi==mx){int k;
for(k=0;k <N;k++){if(c[k][1]==c[mx][1]){if(c[k][0]>c[mx][0]){mx=k;}}else{}}
}else{}
//we keep the value of the max in order to verify that the same value of the max has another occurence in following steps
maxi=mx;
//e is the double array for the output
e[i][0]=c[mx][0];
e[i][1]=c[mx][1];
int j;
//here we throw away the max from the array
for(j=mx;j< N-i-1;j++){c[j][1]=c[j+1][1];c[j][0]=c[j+1][0];}
}
for(i=0;i<N;i++)
{printf("%d %d",e[N-1-i][0],e[N-1-i][1]);
printf("\n");}
}
有人可以帮忙吗?
答案 0 :(得分:0)
您的代码计算复杂度太高。此外,int e[N][2]
仅适用于GCC扩展,因为N
是在运行时而不是编译时确定的变量。
一个简单的(在编码方面)改进它的方法是在C标准库中使用qsort()
。
struct IntPair
{
int n[2];
};
int compareIntPair(const void* lhs, const void* rhs)
{
const struct IntPair *l = (const struct IntPair*)lhs;
const struct IntPair *r = (const struct IntPair*)rhs;
if(l->n[1] < r->n[1])
return -1;
if(l->n[1] > r->n[1])
return 1;
if(l->n[0] < r->n[0])
return -1;
if(l->n[0] > r->n[0])
return 1;
return 0;
}
int main(void)
{
//integers used for the loops
int i;
//the size of the 2D array is N*2
int N;
struct IntPair* c;
scanf("%d",&N);
c = (struct IntPair*)calloc(N, sizeof(struct IntPair));
for(i = 0; i < N; ++i)
{
scanf("%d%d", &c[i].n[0], &c[i].n[1]);
}
qsort(c, N, sizeof(struct IntPair), compareIntPair);
for(i = 0; i < N; ++i)
printf("%d %d\n", c[i].n[0], c[i].n[1]);
free(c);
return 0;
}
编辑:回答评论中的问题“N动态分配的每个元素都可以指向大小为2的1D数组吗?”
int compareElem(const void* lhs, const void* rhs)
{
const int *l = *(const int**)lhs;
const int *r = *(const int**)rhs;
if(l[1] < r[1])
return -1;
if(l[1] > r[1])
return 1;
if(l[0] < r[0])
return -1;
if(l[0] > r[0])
return 1;
return 0;
}
int main(void)
{
//integers used for the loops
int i;
//the size of the 2D array is N*2
int N;
int ** c;
scanf("%d",&N);
c = (int**)calloc(N, sizeof(int*));
for(i = 0; i < N; ++i)
{
c[i] = (int*)calloc(2, sizeof(int));
scanf("%d%d", &c[i][0], &c[i][1]);
}
qsort(c, N, sizeof(int*), compareElem);
for(i = 0; i < N; ++i)
{
printf("%d %d\n", c[i][0], c[i][1]);
free(c[i]);
}
free(c);
return 0;
}