C-列出矩阵中相同数字的最大附近

时间:2015-11-22 15:49:32

标签: c matrix iteration

我是编程新手。我知道我的问题可能不是很聪明,但请耐心等待。我提到这不是作业。

我想找到附近的数量,每个1和1的数量以及每个附近最左边的单元格的坐标。

例如,对于以下矩阵:

{1, 1, 1, 0, 1}
{0, 0, 1, 0, 1}
{0, 1, 1, 0, 0}
{0, 0, 0, 0, 0}

在这个例子中有两组1#。第一个有六个1,第二个有两个1。

下面我发布我的源代码到目前为止。它仅为某些矩阵打印正确的答案,因为我的代码仅检查1个字段向上,一个字段向下,一个字段向右,一个字段向左。我想知道如何摆脱这个问题,而不使用递归方法。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define m 4
#define n 5

int Check(int A[][100],int i,int j,int Checked[][100])
{
    if(A[i][j]==1 && Checked[i][j]==0)
    {
        Checked[i][j]=1;
        return 1;
    }
    return 0;
}

int main()
{
    int A[100][100],i,j,Checked[100][100],begin=0;
    int counter=0;
    int base[100];
    int k=0,x=0;
    int lines[100],cols[100];

srand(time(NULL));

for(i=0;i<m;i++)//generating random matrix
{
    for(j=0;j<n;j++)
    {
        A[i][j]=rand()%2;
        printf("%d ",A[i][j]);
    }
    printf("\n");
}

for(i=0;i<m;i++)//initialising with 0 the Checked matrix
{
    for(j=0;j<n;j++)
    {
        Checked[i][j]=0;
    }
}

for(i=0;i<m;i++)
{
    for(j=0;j<n;j++)
    {
        if(Checked[i][j]==0)
        {
            Checked[i][j]=1;

            if(A[i][j]==1 && begin==0)
            {
                lines[x]=i;
                cols[x]=j;
                begin=1;
                x++;
                counter++;
            }
            if(A[i][j]==1)
            {
                if(Check(A,i-1,j,Checked)==1)
                    counter++;
                if(Check(A,i,j+1,Checked)==1)
                    counter++;
                if(Check(A,i+1,j,Checked)==1)
                    counter++;
                if(Check(A,i,j-1,Checked)==1)
                    counter++;
                if(Check(A,i-1,j,Checked)==0 && Check(A,i,j+1,Checked)==0 && Check(A,i+1,j,Checked)==0 && Check(A,i,j-1,Checked)==0)
                {
                    base[k]=counter;
                    counter=0;
                    k++;
                    begin=0;
                }
            }
        }
    }
}

for(i=0;i<k;i++)
{
    printf("\nNumber of bases: %d\n",base[i]);
    printf("Most up-left base coords: <%d, %d> \n",lines[i],cols[i]);
}
return 0;
}

谢谢,Polb

1 个答案:

答案 0 :(得分:1)

单向,愚蠢的伪代码:

@receiver(post_save, sender=Tel)
def meli_publicar_signal(sender, instance, **kwargs):
   for attr, value in instance.__dict__.items():
       if isinstance(value, ImageFieldFile) and value:
           print(value.url)
           # output : /media/images/filename.png
尝试插入副本时,

int count_connected(set* traversed, element starting_element): { int count = 0 if set_insert(traversed, starting_element): { stack* to_process = stack_create() stack_push(to_process, starting_element) while not stack_empty(to_process): { element current_element = to_process.pop() for each adj_element to current_element: { if set_insert(traversed, adj_element): { ++count stack_push(to_process, adj_element) } } } stack_destroy(to_process) } return count } 将返回false。

针对您的案例对此基本伪代码进行了一些修改:set_insert将是矩阵中的位置(element的点/位置类型或两个单独的整数。)

struct将遍历值为for each adj_element的相邻位置(就像您当前的代码现在通过边界检查检查左侧,上方,下方和右侧的条目)。为了避免大量代码,您可以在堆栈上构造一个由相邻位置组成的4个位置的数组,循环遍历它们,检查它们是否在边界内,以及它们是否已经在1集合中。 / p>

您的traversed集可以是相同大小的矩阵,被视为初始化为0(错误)的布尔矩阵,用于恒定时间集插入。或者你也可以将普通矩阵变成traversed的矩阵,该矩阵存储structs标志。如果您使用非常大的矩阵并且经常访问此标记(热),那么这种交错的rep会更有效。如果不总是需要降低内存需求和可能的对齐开销,则将其分离可能是有用的。你也可以使用按位逻辑将它们全部塞在一起,其中矩阵条目存储traversed值以及它是否已遍历一个整数类型。

实现上述功能后,您可以通过循环调用它来循环遍历从左上角到右下角的矩阵,用于1/0条目。由于我们在调用之间保持此1集,因此对于已经遍历的矩阵条目,它将返回0。返回非零的那些只会对左上角附近进行,因为我们从左上角到右下角遍历矩阵调用此traversed函数。

例如,当我们将位置0,0的函数调用为count_connected时,我们最终使用堆栈以深度优先的方式遍历此区域并设置:

starting_element

该函数返回{*, *, *, 0, 1} {0, 0, *, 0, 1} {0, *, *, 0, 0} {0, 0, 0, 0, 0} ,您可以将其与左上角坐标6一起打印出来。当您下次为0,0调用它时,它会返回1,0,您可以跳过它。

如果你想允许以任意顺序调用函数并仍然返回左上角的元素,你可以跟踪函数中的元素位置并返回左上角的那个(最小值) 0y)。请注意,如果您有x,那么top-left会有些含糊不清,例如:

{0, 0, 1, 0, 1}
{0, 0, 1, 0, 1}
{1, 1, 1, 0, 0}
{0, 0, 0, 0, 0}

我假设您希望在这种情况下2,0以及您使用上述方法获得的计数。如果你想要一个左上角(就像一个边界框的角落),如果你在遍历的元素位置中输出min(x)min(y),第二种方法将会起作用,在这种情况下,你可以使用得到0,0

我会把剩下的留给你。