简体   繁体   English

使用洪水填充算法计算 0 的数量

[英]count number of 0 with floodfill algorithm

I wanted to count number of 0 and 1 from a 2d array with floodfill algorithm....But unfortunetly...it's showing the wrong result.我想用洪水填充算法从二维数组中计算 0 和 1 的数量......但不幸的是......它显示了错误的结果。

I have a matrix like this我有一个这样的矩阵

0,1,1,0,1

1,0,1,1,0

1,0,1,1,0

1,0,1,1,0

1,0,1,1,0

It supposed to show number of 0 = 10 and 1 =15它应该显示 0 = 10 和 1 =15 的数量

but it showing number of 0 = 4 and 1 = 21但它显示 0 = 4 和 1 = 21 的数量

here is my code这是我的代码

int[][] input;
public static int[,] reult;
public static int count = 0,col,row;
public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    string path;
    OpenFileDialog file = new OpenFileDialog();
    if (file.ShowDialog() == DialogResult.OK)
    {

        input = File.ReadLines(file.FileName)
                .Skip(0)
                .Select(l => l.Split(',')
                    .Select(n => int.Parse(n))
                    .ToArray())
                    .ToArray();

    }

    reult = JaggedToMultidimensional(input);

    int p = reult.GetLength(0); 
    int q = reult.GetLength(1); 
    row = p-1;
    col = q - 1;
    int one = p * q;
    int zero = apply(row, col);
    label1.Text = "" + zero;
    label2.Text = "" + (one - zero);

}

public T[,] JaggedToMultidimensional<T>(T[][] jaggedArray)
{
    int rows = jaggedArray.Length;
    int cols = jaggedArray.Max(subArray => subArray.Length);
    T[,] array = new T[rows, cols];
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            array[i, j] = jaggedArray[i][j];
        }
    }
    return array;
}

private static int apply(int x, int y)
{
    int currentColor = getValueAt(x, y);
    if (currentColor == 0)
    {
        visit(x, y);
        count++;

        if (x < row) apply(x + 1, y);
        if(y<col) apply(x, y + 1);
       if(x>0) apply(x - 1, y);
       if (y>0) apply(x, y - 1);
    }
    return count;
}

private static int getValueAt(int x, int y)
{
    if (x < 0 || y < 0 || x > row || y > col)
    {
        return -1;
    }
    else
    {
        return reult[x,y];
    }
}

private static void visit(int x, int y)
{
    reult[x,y] = 1;
}
int zero = apply(row, col);

In your flood fill algorithm, you are only going in four direction and cover the area which match your criteria.在您的洪水填充算法中,您只向四个方向前进并覆盖符合您标准的区域。 And fortunately [row,col] index has 0 and it count all four 0 from [row, col] .幸运的是[row,col]索引有0并且它从[row, col]计算所有四个 0 。 Now think what if apply(row,col) have 1 on that row, col index.现在想想如果apply(row,col)在该row, col上有1 row, col索引会怎样。

To get this thing right, you need to loop through whole matrix and call apply(i,j) where ever you find an array[i,j]==0为了把这件事做好,你需要遍历整个矩阵并在找到array[i,j]==0地方调用apply(i,j)

Change this line改变这一行

int zero = apply(row, col);

to

int zero = 0;
for(int i=0; i<=row; i++)
{
   for(int j=0; j<=col; j++)
   {
       if(array[i][j]==0)
       {
          count =0;
          zero+= apply(row, col);
       }
   }
}

Hope this helps.希望这可以帮助。

Given the requirements you should change the search criteria to search for 0's and 1's.根据要求,您应该更改搜索条件以搜索 0 和 1。

What you need to do is to search within the rectangle so the border of the rectangle is limit for searching.您需要做的是在矩形内搜索,因此矩形的边界是搜索的限制。

ie IE

int[] count = {0,0};

private static int apply(int x, int y)
{
    int currentColor = getValueAt(x, y);
    if (currentColor != -1)
    {
        visit(x, y);
        count[currentColor]++;

        if (x < row) apply(x + 1, y);
        if(y<col) apply(x, y + 1);
       if(x>0) apply(x - 1, y);
       if (y>0) apply(x, y - 1);
    }
    return count;
}

and then change your visit function to set the cell to -1 instead to avoid visiting it twice.然后更改您的访问函数以将单元格设置为 -1 以避免访问它两次。

You can also use linq if you want (I actually prefer):如果需要,您也可以使用 linq(我实际上更喜欢):

OpenFileDialog fileDialog = new OpenFileDialog();
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                var lines = File.ReadLines(fileDialog.FileName);
                var splittedValues = lines.Where(l => !string.IsNullOrEmpty(l)).Select(l => l.Split(',')).SelectMany(l => l).ToList();
                var valCount = splittedValues.GroupBy(s => s).Select(s => new { val = s.Key, count = s.Count() }).ToList();     
            }

It will give you following result:它会给你以下结果:

[0] { val= "0", count=10} [1] { val= "1", count=15} [0] { val="0", count=10} [1] { val="1", count=15}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM