2016-10-16 3 views
1

Я хотел посчитать число 0 и 1 из 2d-массива с алгоритмом наводнения. Но, к сожалению, это показывает неправильный результат.кол-во 0 с алгоритмом floodfill

У меня есть матрица, как этот

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 

Предполагалось, чтобы показать число 0 = 10 и 1 = 15

но показывающий число 0 = 4 и 1 = 21

вот мой код

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; 
} 
+0

Это заливка наводнения и, как таковая, она посещает только соседние ячейки, которые находятся в пределах данного параметра (в данном случае 'currentColor == 0'). Вы начинаете в правом нижнем углу, и в группе этой группы есть 4 0. Ваш алгоритм делает именно то, что он должен делать, и вы просто неправильно интерпретируете результат. – Abion47

+0

, так что мне делать? – Dante

+0

Ваша цель использовать заливку залива или считать 1 и 0? – Abion47

ответ

1
int zero = apply(row, col); 

В вашем алгоритме заполнения залива вы идете только в четырех направлениях и покрываете область, соответствующую вашим критериям. И, к счастью, [row,col] индекс имеет 0 и он считает все четыре 0 от [row, col]. Теперь подумайте, что, если apply(row,col) имеют 1 на этом row, col индекс.

Чтобы получить эту вещь правильно, вам нужно перебрать всю матрицу и вызвать apply(i,j), где бы вы найти array[i,j]==0

Измените эту строку

int zero = apply(row, col); 

к

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); 
     } 
    } 
} 

Надеется, что это помогает.

0

С учетом требований вы должны изменить критерии поиска, чтобы найти 0 и 1.

Что вам нужно сделать, это искать в пределах прямоугольника, чтобы граница прямоугольника была ограничена для поиска.

т.е.

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; 
} 

, а затем изменить функцию визита, чтобы установить ячейку -1 вместо того, чтобы избежать посещения дважды.

0

Вы также можете использовать 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();  
      } 

Это даст вам следующий результат:

[0] {вал = "0", отсчет = 10} [1] {val = "1", count = 15}

 Смежные вопросы

  • Нет связанных вопросов^_^