Алгоритм для поиска наибольшей площади

................................
.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.
................................

Ищете алгоритм для поиска наибольшей площади. Здесь "area" определяется как количество точек (.), Ограниченных 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++;
    }
  }

Это мой первый и изо всех сил пытаюсь двигаться дальше.

Ответ 1

Этот алгоритм должен работать. Вам просто нужно реализовать его на Java.

  • Загрузите файл в char [] []. (1 char [] в строке)
  • Пробел через char [] [] (2 размерно)
    1. после нахождения '.', выполните заливку заливки, изменив все. to ',', также увеличивая счетчик при каждом изменении.
    2. В конце заливки заливки сравните этот счетчик с глобально установленным максимумом. Если он выше, установите его как новый.
Верните максимальное значение, которое вы установили.

Если у вас есть какие-либо проблемы с реализацией Java, то дайте мне знать

Geobits:

Примечание. Если вы хотите исключить область "за пределами" любых полей, наводнения как обычно, но отбрасывать любую область, которая попадает в край во время заливки (пропустить шаг 2.2 для этого потока).

При заполнении заливки у вас есть 2 типа границ. Стена ( "X" ) и край массива (который вам нужно явно проверить, чтобы исключить исключения OutOfBounds). Если вы попали за пределы, продолжайте делать заполнение, но установите флаг, чтобы впоследствии узнать, не считая номер, который вы считали для самого большого окна.

Ответ 2

Мне дали это задание в процессе собеседования, и это компиляция и запуск кода

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

}

Ответ 3

Здесь алгоритм, который заполняет альтернатива потоку. Этот метод проходит по массиву 2d, и всякий раз, когда вы сталкиваетесь с node (пикселем), который находится снаружи слева (справа, сверху, снизу), он помещает текущий node как внешний, то есть, если ваш сосед "снаружи" , вы также отмечены "снаружи" .

Алгоритм продолжается так, пока не будет больше обновлений. Это означает, что все узлы, которые достижимы из "снаружи" , были помечены. BTW, это очень похожая проблема для определения функций уровней и их обновления (где также используется заливка заливки). Приятно отметить этот метод, что он идеально подходит для распараллеливания.

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.

Если у вас есть огромные файлы, в которых вы должны выполнить расчет этой области, вы можете прокручивать вдоль строк и столбцов параллельно, потому что каждое обновление строки (обновление столбца) не зависит от других обновлений.