算法找到最大的区域

时间:2013-10-16 17:20:50

标签: java algorithm graph

................................
.XXXXXXXXXXXXXXX.....XXXXXXXXXX.
.X.....X.......X.....X........X.
.X.....X.......XXXXXXX........X.
.XXXXXXXXXXXX.................X.
.X....X.....X.................X.
.X....X.....XXXX..............X.
.XXXXXX........X..............X.
......X........X..............X.
......X........X..............X.
......X........X..............X.
......XXXXXXXXXXXXXXXXXXXXXXXXX.
................................

寻找找到最大区域的算法。这里,“区域”被定义为由Xs限定的点数(。)。

   private static void readFile(File inputFile) throws IOException {

    Scanner fileScanner = new Scanner(inputFile);

    Point previousPoint = null;

    int rowCount = 0;
    while(fileScanner.hasNext()){
        String line = fileScanner.next();

        String[] points = line.split(" ");

        for(int columnCount=0;columnCount<points.length;columnCount++){

            if(points[columnCount].equalsIgnoreCase("x")){
                Point currentPoint = new Point();
                currentPoint.setxValue(columnCount);
                currentPoint.setyValue(rowCount);
            }
        }

        rowCount++;
    }
  }

这是我的第一次,并且正在努力进一步前进。

3 个答案:

答案 0 :(得分:10)

此算法应该有效。您只需要在Java中实现它。

  
      
  1. 将文件加载到char [] []中。 (每行1个字符[])
  2.   
  3. 循环通过char [] [](2维)      
        
    1. 找到'。'后,执行flood fill,更改所有'。'到',',也在每次改变时增加一个计数器。
    2.   
    3. 在洪水填充结束时,将此计数器与全局设置的最大值进行比较。如果它更高,则将其设置为新的最高值。 (如果边缘不是合适的边界,那么如果在洪水填充期间通过在3期间设置标记到达边缘,则不要设置此计数器。)
    4.   
  4.   
  5. 返回你设置的最高值。
  6.   

如果您对Java实现有任何特定问题,请告诉我

Geobits:

  

注意:如果要将任何方框中的“区域”排除在外,请将其作为   通常,但在填充过程中丢弃任何撞击边缘的区域(跳过   步骤2.2为洪水)。

进行洪水填充时,您有两种类型的边界。墙('X')和数组的边缘(您需要显式检查以避免OutOfBounds异常)。如果你超出界限,继续进行填充,但设置一个标志,以便您稍后知道不考虑最大盒子的数量。

答案 1 :(得分:0)

我在面试过程中被赋予此作为任务,这是编译和运行代码

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class FindArea {
public static void main(String[] args) 
{
    String fileName="C:\\map.txt";
    FindArea area = new FindArea();
    try{
        FileReader inputFile = new FileReader(fileName);
        BufferedReader bufferReader = new BufferedReader(inputFile);

        char[][] twoArray= new char[100][100];
        String line;
        int i=0;

        while ((line = bufferReader.readLine()) != null) {
            twoArray[i] = line.toCharArray();
            System.out.println(line);
            i++;
        }
        bufferReader.close();

        System.out.println("file read");
        System.out.println("Max area: " + area.getMaxArea(twoArray));

    } catch(Exception e) {
        System.out.println("error : " + e.getMessage());
    }
}

/**
 * Get the maximum area from the given map
 * 
 * @param charArray
 * @return
 */
private int getMaxArea(char[][] charArray) {
    HashMap<Integer, ArrayList<String>> numberOfBoxes = convertToBoxes(charArray);

    numberOfBoxes = mergeOverlapAreas(numberOfBoxes);

    int largeSize = 0; 
    for (Integer key : numberOfBoxes.keySet()) {
        ArrayList<String> list = numberOfBoxes.get(key);
        System.out.println("Key : " + key + " Size : " + list.size());
        if (largeSize < list.size()) {
            largeSize = list.size();
        }
    }
    return largeSize;
}

/**
 * Convert the 2d Array to HashMap
 * Key being the count of boxes and 
 * Value being the list of indexes associations
 * 
 * @param charArray
 * @return
 */
private HashMap<Integer, ArrayList<String>> convertToBoxes(char[][] charArray) {
    HashMap<Integer, ArrayList<String>> numberOfBoxes = new HashMap<Integer, ArrayList<String>>();
    int boxes = 0;

    for(int i=1; i<charArray.length; i++) {

        for (int j=0; j<charArray[i].length; j++) {

            if (charArray[i][j] == '.') {

                boolean isExists = false;

                for(Integer key : numberOfBoxes.keySet()) {

                    ArrayList<String> arrList = numberOfBoxes.get(key);

                    if(arrList != null) {

                        if(arrList.contains((i-1) + "-" + j) ||
                           arrList.contains(i + "-" + (j-1))) {

                            isExists = true;
                            arrList.add(i + "-" + j);
                            numberOfBoxes.put(key, arrList);
                        }
                    } 
                }

                if (!isExists) {
                    ArrayList<String> list = new ArrayList<String>();
                    list.add(i + "-" + j);
                    numberOfBoxes.put(boxes, list);
                    boxes++;
                }
            }
        }
    }
    return numberOfBoxes;
}

/**
 * Check for the points exists in more than one area
 * @param numberOfBoxes
 * @return
 */
private  HashMap<Integer, ArrayList<String>> mergeOverlapAreas( HashMap<Integer, ArrayList<String>> numberOfBoxes) {

    for(Integer key : numberOfBoxes.keySet()) {
        ArrayList<String> list1 = numberOfBoxes.get(key);

        for (Integer key2 : numberOfBoxes.keySet()) {

            if (key < key2) {

                ArrayList<String> list2 = numberOfBoxes.get(key2);
                Iterator<String> listIter = list2.iterator();

                while(listIter.hasNext()) {

                    if (list1.contains(listIter.next())) {
                        list1.addAll(list2);
                        Set<String> noDuplicates = new HashSet<String>(list1);
                        numberOfBoxes.put(key, new ArrayList<String>(noDuplicates));
                        break;
                    }
                }
            }
        }

    }
    return numberOfBoxes;
}

}

答案 2 :(得分:-1)

这是一种可以替代洪水填充的算法。此方法扫描2d数组,每当遇到位于左侧(右侧,顶部,底部)外部的节点(像素)时,它会将当前节点标记为外部,即如果您的邻居是“外部”,则标记为“外面”。

算法继续这样,直到没有更新。这意味着可以标记从“外部”可到达的所有节点。顺便说一句,这是一个非常类似的问题,水平集功能和更新它们(也使用泛洪填充)。关于这种方法的好处是它非常适合并行化。

1. Load 2D Symbol Array from File 
2. hasupdates = false
3. Create 'isinside' bool array -> {
       if(symbolarray[row][col] == '.' and row or col is at boundary)
           isinside[row][col] = false
       else
           isinside[row][col] = true
   }

4. do{
    Do a sweep from left to right (for all rows) -> //This loop can be run parallely on all rows. 
        If (!isinside[row][col-1] and symbolarray[row][col] == '.'){
            isinside[row][col] = false //mark current value as 'outside'
            hasupdates = true
        }
    Do similar sweeps from right to left, top to bottom(all columns) and bottom to top.

}while(hasupdates)

5. Go through 'isinside' array and count the number of falses.

如果您有大量文件需要进行此区域计算,则可以沿着行和列并行运行扫描,因为每行更新(列更新)与其他更新无关。