(C) 获取矩阵中一行最小的 3 个元素,并随机选择一个
Posted
技术标签:
【中文标题】(C) 获取矩阵中一行最小的 3 个元素,并随机选择一个【英文标题】:(C) Getting the 3 minimum elements of an row in a matrix, and choose one randomly 【发布时间】:2013-05-07 06:28:20 【问题描述】:我有一个 8x8 矩阵,在选择我想要的行之后,我想得到它的三个最小元素,并随机选择这三个中的一个。问题是我不知道如何处理这三个元素。我只知道如何获取最小元素,就是下面的代码。
int piezas[8][8] =
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
;
int myrow = 3; // the row I want to analyze
int index;
int min=0;
for (index=0;index<8;index++)
printf("%d", piezas[myrow][index] );
if(piezas[myrow][index]<min)
min=piezas[myrow][index];
printf("\t\t");
printf("min: %d", min);
我想要的输出是,如果初始矩阵是:
int piezas[8][8] =
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
;
我选择第 3 行:
0, 3, 1, 5, 1, 2, 3, 4,
算法必须选择
0, 1, 1
并从这三个中随机选择一个。
有人可以告诉我我该怎么做吗?从今天早上开始,我就一直坚持这个。谢谢
【问题讨论】:
【参考方案1】:我会尝试对该行进行排序,然后随机选择前三个元素中的一个。
// integer comparator
int compare(int * a, int * b) return *a - *b;
// allocate memory to hold the copy
int rowCopy[sizeof(piezas[myrow])/sizeof(int)];
// copy the row
memcpy(rowCopy, piezas[myrow], sizeof(piezas[myrow]));
// sort it
qsort(rowCopy, sizeof(piezas[myrow])/sizeof(int), sizeof(rowCopy[0]), compare);
// initialize the random number generator
srand(time(NULL));
// return randomly one of the first 3 elements
return rowCopy[rand() % 3]
【讨论】:
一切似乎都很好,但我遇到了 qsort 行的问题。这是它显示的错误:main.cpp:64: error: invalid conversion from 'int (*)(int*, int*)' to 'int (*)(const void*, const void*)' main.cpp:64: error: initializing argument 4 of 'void qsort(void*, size_t, size_t, int (*)(const void*, const void*))'
是的,这是一个警告,我将比较器定义为不是真正的原型。除非您正在开发一些奇怪的嵌入式系统,否则将其类型转换为int (*)(const void*, const void*)
是安全的。否则将其定义为int compare(void * a, void * b) return *(int*)a - *(int*)b;
。我通常在开发代码中将其设置为警告,并在发布代码中使用函数指针类型转换。在 x84 上它可以正常工作,在某些嵌入式架构上,使用双 void*
定义函数并在其中对参数进行类型转换会更安全。
调用你的第二个解决方案线性时间是......误导。它只是线性的,因为请求的数字是一个固定常数。如果您想去那里,可以说由于行的大小也是固定的,因此整个解决方案在恒定时间内运行。它更像是一个 O(N*M),它可能比您在 nlogn 时间内的排序解决方案更糟糕。
@xaxxon 是的,你说得对。起初我想将3
硬编码到函数中,但后来决定不这样做。最终,它变成了一种或多或少受元素限制的廉价插入排序。
第二次通过输入 2、1 的第二个解决方案 j 循环,它将 2 移到位置 [1],在 [0] 处插入 1 并将 j 增加到 j =1 不小于 numfound==1。然后它将命中 numfound = numfound。基本上是告诉你是否在 j-loop 中添加了任何内容。或者只是使用一个标志。或者也许只是在之前插入前 3 个【参考方案2】:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE_ROW 8
#define N_MIN 3
int piezas[SIZE_ROW][SIZE_ROW] =
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
;
int sort(const void *x, const void *y)
return (*(int*)x - *(int*)y);
int* sort_array(int* row, int size_row)
int* output = (int*) calloc(size_row, sizeof(int) );
memcpy(output, row, size_row*sizeof(int) ); // copy array
qsort (output, size_row, sizeof (int), sort);
return output;
int random_pick(int* array, int size_row)
return array[ rand() % size_row ]; // possible buffer overflow if size_row too big.
int main(void)
srand(time(NULL));
int myrow = 3; // the row I want to analyze
int* sorted_row = NULL;
int i,j;
sorted_row = sort_array(piezas[myrow],SIZE_ROW );
printf("N mins : \n");
for(i=0;i<N_MIN;i++)
printf(" %d ", sorted_row[i] );
printf("\n");
printf("Random Pick : %d \n", random_pick(sorted_row, N_MIN) );
【讨论】:
【参考方案3】:在 tmp_array(8 个元素)中创建一行的副本,然后是 qsort(tmp_array)
,最后使用 rand() % 3
作为您的答案元素编号。
【讨论】:
【参考方案4】:简单的解决方案是你有三个变量 min1、min2、min3 来保存三个最小变量。
【讨论】:
【参考方案5】:取一个数组 numbers[3] 并将这三个值保存在其中。现在
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
【讨论】:
找到最小的 3 比随机选择一个要困难得多。正如他的评论所述,他在找到 3 时遇到了问题。【参考方案6】:一般来说,你可以使用堆排序来获取数组中的N个最小元素,比如你选择的行,你不需要对所有元素进行排序。但记住不要将排序结果保存在行本身中。 并使用 rand() 来选择其中之一。
【讨论】:
【参考方案7】:#include <stdio.h>
int main(void)
int piezas[8][8] =
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
;
int myrow = 3; // the row I want to analyze
int index;
int min[3]=99,99,99;//or INT_MAX at <limits.h>
for (index=0;index<8;index++)
printf("%d", piezas[myrow][index] );
int i, temp = piezas[myrow][index];
for(i=0;i<3;++i)
if(temp<=min[i])
int wk = min[i];
min[i]=temp;
temp = wk;
printf(" ");
printf("min:");
for(index=0;index<3;++index)
printf(" %d", min[index]);
return 0;
【讨论】:
以上是关于(C) 获取矩阵中一行最小的 3 个元素,并随机选择一个的主要内容,如果未能解决你的问题,请参考以下文章
matlab中已知一矩阵,如何将其中的已知的元素打乱顺序进行随机排列得到新的矩阵,如: