如何在 C 中的二维数组中显示两个相同列的各个元素
How to display the individual elements of two identical columns inside a 2D array in C
我的任务是找到两个相同的列并在二维数组中显示它们的每个元素。
之后,我必须按升序对同一列中的一列进行排序,对另一列进行降序排序。
我已经编写了用于查找相同列的代码,但是在找到列的各个元素后,我在显示它们时遇到了很多麻烦。我更愿意以列形式显示 show_columns()
函数内的元素,就像在 declaration()
.
中一样
寻找任何提示
#include <stdio.h>
#include <stdbool.h>
void declaration(int a[100][100], int n) {
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("a[%i][%i]=", i, j);
scanf("%i", &a[i][j]);
}
}
printf("\nThe matrix is : \n");
for (i = 0; i < n; i++) {
printf("\n");
for (j = 0; j < n; j++) {
printf("%d\t", a[i][j]);
}
}
printf("\n\n");
}
bool columns(int rows, int cols, int i, int j, int a[rows][cols]) {
for (int k = 0; k < rows; k++) {
if (a[k][i] != a[k][j]) {
return false;
}
}
return true;
}
void show_columns(int rows, int cols, int a[rows][cols]) {
for (int i = 0; i < cols; i++) {
for (int j = i + 1; j < cols; j++) {
if (columns(rows, cols, i, j, a)) {
printf("\nThe columns %i si %i are identical\n", i, j);
}
}
}
}
int main() {
int a[100][100], n;
int k;
printf("Enter n:");
scanf("%i", &n);
int rows = n, cols = n;
declaration(a, n);
show_columns(rows, cols, a);
return 0;
}
It would also be helpful if anyone could help me find identical columns in an array without resorting to a bool function
好吧,这可能是可能的,但布尔函数是核心(例如,如果两个不同的列匹配,则 returns 为真的函数)。
但是,要找到所有匹配项,还需要另一个函数。它必须遍历唯一的列对并调用匹配函数以查看两列是否匹配。
它有助于定义一个“迭代器”结构来跟踪搜索索引和最大几何数。
这是一个 [完全] 重构的版本。它有一个诊断测试,可以生成一个具有随机相同列的随机矩阵。它遍历所有列对并打印唯一匹配的列号。
请注意,它不会对任何列进行排序。这留作 reader.
的练习
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned int opt_R;
int opt_M;
typedef struct {
int maxrow; // maximum number of rows
int maxcol; // maximum number of columns
int lcol; // starting left column
int rcol; // starting right column
int match; // 1=match
} search_t;
#define MAXROW 100
#define MAXCOL 100
int arrbig[MAXROW][MAXCOL];
// search_init -- initialize for full matrix search
void
search_init(search_t *srch,int maxrow,int maxcol)
{
srch->maxrow = maxrow;
srch->maxcol = maxcol;
srch->lcol = 0;
srch->rcol = 1;
}
// search_match -- decide if two given columns match
// RETURNS: 1=match
int
search_match(int lcol,int rcol,int maxrow,int arr[MAXROW][MAXCOL])
{
int match = 0;
for (int irow = 0; irow < maxrow; ++irow) {
match = (arr[irow][lcol] == arr[irow][rcol]);
if (! match)
break;
}
return match;
}
// search_next -- advance to next search starting point
// RETURNS: 1=more to do
int
search_next(search_t *srch)
{
int maxcol = srch->maxcol;
srch->rcol += 1;
if (srch->rcol >= maxcol) {
srch->lcol += 1;
srch->rcol = srch->lcol + 1;
}
return (srch->lcol < (maxcol - 1));
}
// search_find -- find next column pair that matches
int
search_find(search_t *srch,int arr[MAXROW][MAXCOL])
{
int lcol = srch->lcol;
int rcol = srch->rcol;
int maxrow = srch->maxrow;
int maxcol = srch->maxcol;
int match = 0;
while (lcol < (maxcol - 1)) {
for (; rcol < maxcol; ++rcol) {
match = search_match(lcol,rcol,maxrow,arr);
if (match)
break;
}
if (match)
break;
if (! search_next(srch))
break;
rcol = srch->rcol;
lcol = srch->lcol;
}
srch->lcol = lcol;
srch->rcol = rcol;
srch->match = match;
return match;
}
// dojoin -- ensure unique pairing
void
dojoin(const search_t *srch,int arr[MAXROW][MAXCOL])
{
int lcol;
int rcol;
search_t *uniq;
search_t uniqlist[opt_M];
// make certain columns identical
for (int iter = 0; iter < opt_M; ++iter) {
while (1) {
// get two different column numbers
while (1) {
lcol = rand() % srch->maxcol;
rcol = rand() % srch->maxcol;
if (lcol != rcol)
break;
}
// we want low/high
if (lcol > rcol) {
int tmp = lcol;
lcol = rcol;
rcol = tmp;
}
// have we set this before?
int match = 0;
for (int uniqidx = 0; uniqidx < iter; ++uniqidx) {
uniq = &uniqlist[uniqidx];
match = ((lcol == uniq->lcol) && (rcol == uniq->rcol));
if (match)
break;
}
// got a _unique_ pair of column numbers
if (! match) {
uniq = &uniqlist[iter];
uniq->lcol = lcol;
uniq->rcol = rcol;
break;
}
}
// copy from one column to another
for (int irow = 0; irow < srch->maxrow; ++irow)
arr[irow][rcol] = arr[irow][lcol];
printf("dojoin: EXPECTED %d,%d\n",lcol,rcol);
}
}
// dotest -- perform test
void
dotest(int arr[MAXROW][MAXCOL])
{
search_t srch;
// NOTE: a smaller geometry can be used if desired
search_init(&srch,MAXROW,MAXCOL);
// create random matrix
for (int irow = 0; irow < srch.maxrow; ++irow) {
for (int icol = 0; icol < srch.maxcol; ++icol)
arr[irow][icol] = rand();
}
// create columns that are the same
dojoin(&srch,arr);
// search entire matrix looking for matching columns
for (int iter = 0; iter < (opt_M * 2); ++iter) {
int match = search_find(&srch,arr);
if (! match)
break;
printf("dotest: ACTUAL %d,%d\n",srch.lcol,srch.rcol);
if (! search_next(&srch))
break;
}
}
int
main(int argc,char **argv)
{
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
char *cp = *argv;
if (*cp != '-')
break;
cp += 2;
switch (cp[-1]) {
case 'M':
opt_M = (*cp != 0) ? atoi(cp) : (MAXCOL / 4);
break;
case 'R':
opt_R = (*cp != 0) ? atoi(cp) : 1;
break;
}
}
// by printing the random seed value, and using -R on a subsequent program
// invocation, we can make the result repeatable
if (opt_R == 0)
opt_R = time(NULL);
printf("R: %u\n",opt_R);
srand(opt_R);
// set number of matching columns
if (opt_M == 0)
opt_M = 5;
dotest(arrbig);
return 0;
}
这是使用 -R1612382146
的程序输出。它有多个相同的列:
R: 1612382146
dojoin: EXPECTED 12,99
dojoin: EXPECTED 2,74
dojoin: EXPECTED 18,91
dojoin: EXPECTED 18,34
dojoin: EXPECTED 64,93
dotest: ACTUAL 2,74
dotest: ACTUAL 12,99
dotest: ACTUAL 18,34
dotest: ACTUAL 18,91
dotest: ACTUAL 34,91
dotest: ACTUAL 64,93
这里有一些随机输出:
R: 1612387497
dojoin: EXPECTED 35,72
dojoin: EXPECTED 72,82
dojoin: EXPECTED 60,93
dojoin: EXPECTED 34,45
dojoin: EXPECTED 79,90
dotest: ACTUAL 34,45
dotest: ACTUAL 35,72
dotest: ACTUAL 35,82
dotest: ACTUAL 60,93
dotest: ACTUAL 72,82
dotest: ACTUAL 79,90
R: 1612387500
dojoin: EXPECTED 14,68
dojoin: EXPECTED 60,80
dojoin: EXPECTED 22,84
dojoin: EXPECTED 11,15
dojoin: EXPECTED 1,52
dotest: ACTUAL 1,52
dotest: ACTUAL 11,15
dotest: ACTUAL 14,68
dotest: ACTUAL 22,84
dotest: ACTUAL 60,80
R: 1612387503
dojoin: EXPECTED 40,42
dojoin: EXPECTED 16,29
dojoin: EXPECTED 8,69
dojoin: EXPECTED 23,74
dojoin: EXPECTED 44,67
dotest: ACTUAL 8,69
dotest: ACTUAL 16,29
dotest: ACTUAL 23,74
dotest: ACTUAL 40,42
dotest: ACTUAL 44,67
R: 1612387506
dojoin: EXPECTED 20,32
dojoin: EXPECTED 36,59
dojoin: EXPECTED 9,36
dojoin: EXPECTED 20,48
dojoin: EXPECTED 38,48
dotest: ACTUAL 9,36
dotest: ACTUAL 20,32
dotest: ACTUAL 38,48
R: 1612387508
dojoin: EXPECTED 40,71
dojoin: EXPECTED 34,84
dojoin: EXPECTED 53,72
dojoin: EXPECTED 8,73
dojoin: EXPECTED 17,75
dotest: ACTUAL 8,73
dotest: ACTUAL 17,75
dotest: ACTUAL 34,84
dotest: ACTUAL 40,71
dotest: ACTUAL 53,72
更新:
这是一个将所有信息放入 struct
的版本,因此不需要单独的数组指针参数。
它使用特殊的“指向数组的指针”来帮助处理以下形式的多维数组:
int (*arr)[MAXCOL];
参见:C pointer to array/array of pointers disambiguation
这为具有 arbitrary/dynamic 个数组维度的数组保留了正确的索引:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned int opt_R;
int opt_M;
int opt_W;
int opt_H;
typedef struct {
int maxrow; // maximum number of rows
int maxcol; // maximum number of columns
int *arr; // array base
int lcol; // starting/current left column
int rcol; // starting/current right column
int match; // 1=match
} search_t;
#define ARRDEF \
int (*arr)[srch->maxcol] = (__typeof__(arr)) srch->arr
#define MAXROW 100
#define MAXCOL 100
// search_init -- initialize for full matrix search
void
search_reset(search_t *srch)
{
srch->lcol = 0;
srch->rcol = 1;
}
// search_init -- initialize for full matrix search
search_t *
search_init(int maxrow,int maxcol)
{
search_t *srch;
srch = calloc(1,sizeof(*srch));
srch->maxrow = maxrow;
srch->maxcol = maxcol;
srch->arr = malloc(sizeof(*srch->arr) * maxrow * maxcol);
search_reset(srch);
return srch;
}
// search_free -- free up array
void
search_free(search_t *srch)
{
free(srch->arr);
free(srch);
}
// search_match -- decide if two given columns match
// RETURNS: 1=match
int
search_match(const search_t *srch)
{
ARRDEF;
int match = 0;
int lcol = srch->lcol;
int rcol = srch->rcol;
for (int irow = 0; irow < srch->maxrow; ++irow) {
match = (arr[irow][lcol] == arr[irow][rcol]);
if (! match)
break;
}
return match;
}
// search_next -- advance to next search starting point
// RETURNS: 1=more to do
int
search_next(search_t *srch)
{
int maxcol = srch->maxcol;
srch->rcol += 1;
if (srch->rcol >= maxcol) {
srch->lcol += 1;
srch->rcol = srch->lcol + 1;
}
return (srch->lcol < (maxcol - 1));
}
// search_find -- find next column pair that matches
int
search_find(search_t *srch)
{
int maxcol = srch->maxcol;
int match = 0;
while (srch->lcol < (maxcol - 1)) {
for (; srch->rcol < maxcol; ++srch->rcol) {
match = search_match(srch);
if (match)
break;
}
if (match)
break;
if (! search_next(srch))
break;
}
srch->match = match;
return match;
}
// dojoin -- ensure unique pairing
void
dojoin(const search_t *srch)
{
ARRDEF;
int lcol;
int rcol;
search_t *uniq;
search_t uniqlist[opt_M];
// make certain columns identical
for (int iter = 0; iter < opt_M; ++iter) {
while (1) {
// get two different column numbers
while (1) {
lcol = rand() % srch->maxcol;
rcol = rand() % srch->maxcol;
if (lcol != rcol)
break;
}
// we want low/high
if (lcol > rcol) {
int tmp = lcol;
lcol = rcol;
rcol = tmp;
}
// have we set this before?
int match = 0;
for (int uniqidx = 0; uniqidx < iter; ++uniqidx) {
uniq = &uniqlist[uniqidx];
match = ((lcol == uniq->lcol) && (rcol == uniq->rcol));
if (match)
break;
}
// got a _unique_ pair of column numbers
if (! match) {
uniq = &uniqlist[iter];
uniq->lcol = lcol;
uniq->rcol = rcol;
break;
}
}
// copy from one column to another
for (int irow = 0; irow < srch->maxrow; ++irow)
arr[irow][rcol] = arr[irow][lcol];
printf("dojoin: EXPECTED %d,%d\n",lcol,rcol);
}
}
// dofill -- fill matrix
void
dofill(const search_t *srch)
{
ARRDEF;
for (int irow = 0; irow < srch->maxrow; ++irow) {
for (int icol = 0; icol < srch->maxcol; ++icol)
arr[irow][icol] = rand();
}
}
// dotest -- perform test
void
dotest(int maxrow,int maxcol)
{
search_t *srch;
// NOTE: a smaller geometry can be used if desired
srch = search_init(maxrow,maxcol);
// create random matrix
dofill(srch);
// create columns that are the same
dojoin(srch);
// search entire matrix looking for matching columns
for (int iter = 0; iter < (opt_M * 2); ++iter) {
int match = search_find(srch);
if (! match)
break;
printf("dotest: ACTUAL %d,%d\n",srch->lcol,srch->rcol);
if (! search_next(srch))
break;
}
search_free(srch);
}
int
main(int argc,char **argv)
{
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
char *cp = *argv;
if (*cp != '-')
break;
cp += 2;
switch (cp[-1]) {
case 'M':
opt_M = (*cp != 0) ? atoi(cp) : (MAXCOL / 4);
break;
case 'R':
opt_R = (*cp != 0) ? atoi(cp) : 1;
break;
case 'H':
opt_H = atoi(cp);
break;
case 'W':
opt_W = atoi(cp);
break;
}
}
// by printing the random seed value, and using -R on a subsequent program
// invocation, we can make the result repeatable
if (opt_R == 0)
opt_R = time(NULL);
printf("R: %u\n",opt_R);
srand(opt_R);
// set number of matching columns
if (opt_M == 0)
opt_M = 5;
if (opt_H == 0)
opt_H = MAXROW;
if (opt_W == 0)
opt_W = MAXCOL;
dotest(opt_H,opt_W);
return 0;
}
我的任务是找到两个相同的列并在二维数组中显示它们的每个元素。
之后,我必须按升序对同一列中的一列进行排序,对另一列进行降序排序。
我已经编写了用于查找相同列的代码,但是在找到列的各个元素后,我在显示它们时遇到了很多麻烦。我更愿意以列形式显示 show_columns()
函数内的元素,就像在 declaration()
.
寻找任何提示
#include <stdio.h>
#include <stdbool.h>
void declaration(int a[100][100], int n) {
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("a[%i][%i]=", i, j);
scanf("%i", &a[i][j]);
}
}
printf("\nThe matrix is : \n");
for (i = 0; i < n; i++) {
printf("\n");
for (j = 0; j < n; j++) {
printf("%d\t", a[i][j]);
}
}
printf("\n\n");
}
bool columns(int rows, int cols, int i, int j, int a[rows][cols]) {
for (int k = 0; k < rows; k++) {
if (a[k][i] != a[k][j]) {
return false;
}
}
return true;
}
void show_columns(int rows, int cols, int a[rows][cols]) {
for (int i = 0; i < cols; i++) {
for (int j = i + 1; j < cols; j++) {
if (columns(rows, cols, i, j, a)) {
printf("\nThe columns %i si %i are identical\n", i, j);
}
}
}
}
int main() {
int a[100][100], n;
int k;
printf("Enter n:");
scanf("%i", &n);
int rows = n, cols = n;
declaration(a, n);
show_columns(rows, cols, a);
return 0;
}
It would also be helpful if anyone could help me find identical columns in an array without resorting to a bool function
好吧,这可能是可能的,但布尔函数是核心(例如,如果两个不同的列匹配,则 returns 为真的函数)。
但是,要找到所有匹配项,还需要另一个函数。它必须遍历唯一的列对并调用匹配函数以查看两列是否匹配。
它有助于定义一个“迭代器”结构来跟踪搜索索引和最大几何数。
这是一个 [完全] 重构的版本。它有一个诊断测试,可以生成一个具有随机相同列的随机矩阵。它遍历所有列对并打印唯一匹配的列号。
请注意,它不会对任何列进行排序。这留作 reader.
的练习#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned int opt_R;
int opt_M;
typedef struct {
int maxrow; // maximum number of rows
int maxcol; // maximum number of columns
int lcol; // starting left column
int rcol; // starting right column
int match; // 1=match
} search_t;
#define MAXROW 100
#define MAXCOL 100
int arrbig[MAXROW][MAXCOL];
// search_init -- initialize for full matrix search
void
search_init(search_t *srch,int maxrow,int maxcol)
{
srch->maxrow = maxrow;
srch->maxcol = maxcol;
srch->lcol = 0;
srch->rcol = 1;
}
// search_match -- decide if two given columns match
// RETURNS: 1=match
int
search_match(int lcol,int rcol,int maxrow,int arr[MAXROW][MAXCOL])
{
int match = 0;
for (int irow = 0; irow < maxrow; ++irow) {
match = (arr[irow][lcol] == arr[irow][rcol]);
if (! match)
break;
}
return match;
}
// search_next -- advance to next search starting point
// RETURNS: 1=more to do
int
search_next(search_t *srch)
{
int maxcol = srch->maxcol;
srch->rcol += 1;
if (srch->rcol >= maxcol) {
srch->lcol += 1;
srch->rcol = srch->lcol + 1;
}
return (srch->lcol < (maxcol - 1));
}
// search_find -- find next column pair that matches
int
search_find(search_t *srch,int arr[MAXROW][MAXCOL])
{
int lcol = srch->lcol;
int rcol = srch->rcol;
int maxrow = srch->maxrow;
int maxcol = srch->maxcol;
int match = 0;
while (lcol < (maxcol - 1)) {
for (; rcol < maxcol; ++rcol) {
match = search_match(lcol,rcol,maxrow,arr);
if (match)
break;
}
if (match)
break;
if (! search_next(srch))
break;
rcol = srch->rcol;
lcol = srch->lcol;
}
srch->lcol = lcol;
srch->rcol = rcol;
srch->match = match;
return match;
}
// dojoin -- ensure unique pairing
void
dojoin(const search_t *srch,int arr[MAXROW][MAXCOL])
{
int lcol;
int rcol;
search_t *uniq;
search_t uniqlist[opt_M];
// make certain columns identical
for (int iter = 0; iter < opt_M; ++iter) {
while (1) {
// get two different column numbers
while (1) {
lcol = rand() % srch->maxcol;
rcol = rand() % srch->maxcol;
if (lcol != rcol)
break;
}
// we want low/high
if (lcol > rcol) {
int tmp = lcol;
lcol = rcol;
rcol = tmp;
}
// have we set this before?
int match = 0;
for (int uniqidx = 0; uniqidx < iter; ++uniqidx) {
uniq = &uniqlist[uniqidx];
match = ((lcol == uniq->lcol) && (rcol == uniq->rcol));
if (match)
break;
}
// got a _unique_ pair of column numbers
if (! match) {
uniq = &uniqlist[iter];
uniq->lcol = lcol;
uniq->rcol = rcol;
break;
}
}
// copy from one column to another
for (int irow = 0; irow < srch->maxrow; ++irow)
arr[irow][rcol] = arr[irow][lcol];
printf("dojoin: EXPECTED %d,%d\n",lcol,rcol);
}
}
// dotest -- perform test
void
dotest(int arr[MAXROW][MAXCOL])
{
search_t srch;
// NOTE: a smaller geometry can be used if desired
search_init(&srch,MAXROW,MAXCOL);
// create random matrix
for (int irow = 0; irow < srch.maxrow; ++irow) {
for (int icol = 0; icol < srch.maxcol; ++icol)
arr[irow][icol] = rand();
}
// create columns that are the same
dojoin(&srch,arr);
// search entire matrix looking for matching columns
for (int iter = 0; iter < (opt_M * 2); ++iter) {
int match = search_find(&srch,arr);
if (! match)
break;
printf("dotest: ACTUAL %d,%d\n",srch.lcol,srch.rcol);
if (! search_next(&srch))
break;
}
}
int
main(int argc,char **argv)
{
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
char *cp = *argv;
if (*cp != '-')
break;
cp += 2;
switch (cp[-1]) {
case 'M':
opt_M = (*cp != 0) ? atoi(cp) : (MAXCOL / 4);
break;
case 'R':
opt_R = (*cp != 0) ? atoi(cp) : 1;
break;
}
}
// by printing the random seed value, and using -R on a subsequent program
// invocation, we can make the result repeatable
if (opt_R == 0)
opt_R = time(NULL);
printf("R: %u\n",opt_R);
srand(opt_R);
// set number of matching columns
if (opt_M == 0)
opt_M = 5;
dotest(arrbig);
return 0;
}
这是使用 -R1612382146
的程序输出。它有多个相同的列:
R: 1612382146
dojoin: EXPECTED 12,99
dojoin: EXPECTED 2,74
dojoin: EXPECTED 18,91
dojoin: EXPECTED 18,34
dojoin: EXPECTED 64,93
dotest: ACTUAL 2,74
dotest: ACTUAL 12,99
dotest: ACTUAL 18,34
dotest: ACTUAL 18,91
dotest: ACTUAL 34,91
dotest: ACTUAL 64,93
这里有一些随机输出:
R: 1612387497
dojoin: EXPECTED 35,72
dojoin: EXPECTED 72,82
dojoin: EXPECTED 60,93
dojoin: EXPECTED 34,45
dojoin: EXPECTED 79,90
dotest: ACTUAL 34,45
dotest: ACTUAL 35,72
dotest: ACTUAL 35,82
dotest: ACTUAL 60,93
dotest: ACTUAL 72,82
dotest: ACTUAL 79,90
R: 1612387500
dojoin: EXPECTED 14,68
dojoin: EXPECTED 60,80
dojoin: EXPECTED 22,84
dojoin: EXPECTED 11,15
dojoin: EXPECTED 1,52
dotest: ACTUAL 1,52
dotest: ACTUAL 11,15
dotest: ACTUAL 14,68
dotest: ACTUAL 22,84
dotest: ACTUAL 60,80
R: 1612387503
dojoin: EXPECTED 40,42
dojoin: EXPECTED 16,29
dojoin: EXPECTED 8,69
dojoin: EXPECTED 23,74
dojoin: EXPECTED 44,67
dotest: ACTUAL 8,69
dotest: ACTUAL 16,29
dotest: ACTUAL 23,74
dotest: ACTUAL 40,42
dotest: ACTUAL 44,67
R: 1612387506
dojoin: EXPECTED 20,32
dojoin: EXPECTED 36,59
dojoin: EXPECTED 9,36
dojoin: EXPECTED 20,48
dojoin: EXPECTED 38,48
dotest: ACTUAL 9,36
dotest: ACTUAL 20,32
dotest: ACTUAL 38,48
R: 1612387508
dojoin: EXPECTED 40,71
dojoin: EXPECTED 34,84
dojoin: EXPECTED 53,72
dojoin: EXPECTED 8,73
dojoin: EXPECTED 17,75
dotest: ACTUAL 8,73
dotest: ACTUAL 17,75
dotest: ACTUAL 34,84
dotest: ACTUAL 40,71
dotest: ACTUAL 53,72
更新:
这是一个将所有信息放入 struct
的版本,因此不需要单独的数组指针参数。
它使用特殊的“指向数组的指针”来帮助处理以下形式的多维数组:
int (*arr)[MAXCOL];
参见:C pointer to array/array of pointers disambiguation
这为具有 arbitrary/dynamic 个数组维度的数组保留了正确的索引:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
unsigned int opt_R;
int opt_M;
int opt_W;
int opt_H;
typedef struct {
int maxrow; // maximum number of rows
int maxcol; // maximum number of columns
int *arr; // array base
int lcol; // starting/current left column
int rcol; // starting/current right column
int match; // 1=match
} search_t;
#define ARRDEF \
int (*arr)[srch->maxcol] = (__typeof__(arr)) srch->arr
#define MAXROW 100
#define MAXCOL 100
// search_init -- initialize for full matrix search
void
search_reset(search_t *srch)
{
srch->lcol = 0;
srch->rcol = 1;
}
// search_init -- initialize for full matrix search
search_t *
search_init(int maxrow,int maxcol)
{
search_t *srch;
srch = calloc(1,sizeof(*srch));
srch->maxrow = maxrow;
srch->maxcol = maxcol;
srch->arr = malloc(sizeof(*srch->arr) * maxrow * maxcol);
search_reset(srch);
return srch;
}
// search_free -- free up array
void
search_free(search_t *srch)
{
free(srch->arr);
free(srch);
}
// search_match -- decide if two given columns match
// RETURNS: 1=match
int
search_match(const search_t *srch)
{
ARRDEF;
int match = 0;
int lcol = srch->lcol;
int rcol = srch->rcol;
for (int irow = 0; irow < srch->maxrow; ++irow) {
match = (arr[irow][lcol] == arr[irow][rcol]);
if (! match)
break;
}
return match;
}
// search_next -- advance to next search starting point
// RETURNS: 1=more to do
int
search_next(search_t *srch)
{
int maxcol = srch->maxcol;
srch->rcol += 1;
if (srch->rcol >= maxcol) {
srch->lcol += 1;
srch->rcol = srch->lcol + 1;
}
return (srch->lcol < (maxcol - 1));
}
// search_find -- find next column pair that matches
int
search_find(search_t *srch)
{
int maxcol = srch->maxcol;
int match = 0;
while (srch->lcol < (maxcol - 1)) {
for (; srch->rcol < maxcol; ++srch->rcol) {
match = search_match(srch);
if (match)
break;
}
if (match)
break;
if (! search_next(srch))
break;
}
srch->match = match;
return match;
}
// dojoin -- ensure unique pairing
void
dojoin(const search_t *srch)
{
ARRDEF;
int lcol;
int rcol;
search_t *uniq;
search_t uniqlist[opt_M];
// make certain columns identical
for (int iter = 0; iter < opt_M; ++iter) {
while (1) {
// get two different column numbers
while (1) {
lcol = rand() % srch->maxcol;
rcol = rand() % srch->maxcol;
if (lcol != rcol)
break;
}
// we want low/high
if (lcol > rcol) {
int tmp = lcol;
lcol = rcol;
rcol = tmp;
}
// have we set this before?
int match = 0;
for (int uniqidx = 0; uniqidx < iter; ++uniqidx) {
uniq = &uniqlist[uniqidx];
match = ((lcol == uniq->lcol) && (rcol == uniq->rcol));
if (match)
break;
}
// got a _unique_ pair of column numbers
if (! match) {
uniq = &uniqlist[iter];
uniq->lcol = lcol;
uniq->rcol = rcol;
break;
}
}
// copy from one column to another
for (int irow = 0; irow < srch->maxrow; ++irow)
arr[irow][rcol] = arr[irow][lcol];
printf("dojoin: EXPECTED %d,%d\n",lcol,rcol);
}
}
// dofill -- fill matrix
void
dofill(const search_t *srch)
{
ARRDEF;
for (int irow = 0; irow < srch->maxrow; ++irow) {
for (int icol = 0; icol < srch->maxcol; ++icol)
arr[irow][icol] = rand();
}
}
// dotest -- perform test
void
dotest(int maxrow,int maxcol)
{
search_t *srch;
// NOTE: a smaller geometry can be used if desired
srch = search_init(maxrow,maxcol);
// create random matrix
dofill(srch);
// create columns that are the same
dojoin(srch);
// search entire matrix looking for matching columns
for (int iter = 0; iter < (opt_M * 2); ++iter) {
int match = search_find(srch);
if (! match)
break;
printf("dotest: ACTUAL %d,%d\n",srch->lcol,srch->rcol);
if (! search_next(srch))
break;
}
search_free(srch);
}
int
main(int argc,char **argv)
{
--argc;
++argv;
for (; argc > 0; --argc, ++argv) {
char *cp = *argv;
if (*cp != '-')
break;
cp += 2;
switch (cp[-1]) {
case 'M':
opt_M = (*cp != 0) ? atoi(cp) : (MAXCOL / 4);
break;
case 'R':
opt_R = (*cp != 0) ? atoi(cp) : 1;
break;
case 'H':
opt_H = atoi(cp);
break;
case 'W':
opt_W = atoi(cp);
break;
}
}
// by printing the random seed value, and using -R on a subsequent program
// invocation, we can make the result repeatable
if (opt_R == 0)
opt_R = time(NULL);
printf("R: %u\n",opt_R);
srand(opt_R);
// set number of matching columns
if (opt_M == 0)
opt_M = 5;
if (opt_H == 0)
opt_H = MAXROW;
if (opt_W == 0)
opt_W = MAXCOL;
dotest(opt_H,opt_W);
return 0;
}