2016-10-16 2 views
1

Je voulais compter le nombre de 0 et 1 d'un tableau 2d avec l'algorithme de remplissage .... Mais malheureusement ... il montre le mauvais résultat.compte le nombre de 0 avec l'algorithme d'inondation

J'ai une matrice comme celui-ci

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 

Il censé montrer nombre de 0 = 10 et 1 = 15

mais montrant nombre de 0 = 4 et 1 = 21

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

Ceci est un remplissage d'inondation, et en tant que tel, il ne visite que les cellules adjacentes qui sont dans un paramètre donné (dans ce cas, 'currentColor == 0'). Vous commencez en bas à droite, et il y a 4 0 le groupe de cette cellule. Votre algorithme fait exactement ce qu'il devrait faire, et vous ne faites qu'interpréter le résultat. – Abion47

+0

alors que dois-je faire? – Dante

+0

Votre objectif est-il d'utiliser un remplissage d'inondation ou de compter les 1 et les 0? – Abion47

Répondre

1
int zero = apply(row, col); 

Dans votre algorithme de remplissage d'inondation, vous allez seulement dans quatre directions et couvrez la zone qui correspond à vos critères. Et heureusement [row,col] l'index a 0 et il compte les quatre 0 de [row, col]. Maintenant, pensez que si apply(row,col) ont 1 sur cet row, col indice.

Pour ce qui est juste, vous devez faire une boucle à travers la matrice entière et appeler apply(i,j) où jamais vous trouvez un array[i,j]==0

Modifier cette ligne

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

Hope this aide.

0

Compte tenu des exigences, vous devez changer les critères de recherche pour rechercher 0 et 1.

Ce que vous devez faire est de chercher dans le rectangle afin que la limite du rectangle soit limitée pour la recherche.

à savoir

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

puis changer votre fonction de visite pour définir la cellule à -1 au lieu d'éviter de visiter deux fois.

0

Vous pouvez également utiliser LINQ si vous voulez (je préfère):

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

Il vous donnera résultat suivant:

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