• Как эффективно сгруппировать строки?

    leahch
    @leahch
    3D специалист. Dолго, Dорого, Dерьмово.
    Как ни странно, итерировать группы совсем не обязательно!
    1) группа у вас состоит из одного элемента. В вашем примере F и X - две группы, в которые нужно положить номера строк.
    2) за один проход бежим по строкам и добавляем их в соответствующие группы термов, которые держим в hashtable, где ключом у нас сам терм, а значением - массив из номеров строк.
    3) после того, как заполнили хеш, пробегаемся по нему один раз и смотрим, у кого длина массива больше единицы, это и будут исходные группы.

    Если нам нужно дополнительно сформировать группы из двух-трех термов, то делает все тоже самое, но ключом ставим treeset из этих элементов.

    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map.Entry;
    import java.util.TreeSet;
    
    public class Groups {
    
    	public static void main(String[] args) {
    		String[] myData = {
    				"F;I;J", 
    				"F;X;A",
    				"X;D;P",
    
    				"A;B;C",
    				"X;Y;Z",
    				"J;A;Z",
    				"U;V;W",
    				"E;E;E",
    				"D;F;G",
    		};
    		
    		HashMap<String, TreeSet<Integer>> groups = new HashMap<String, TreeSet<Integer>>();
    		
    		for(int line=0; line< myData.length; line++ ) { // бежим по строкам
    			
    			List<String> terms = Arrays.asList(myData[line].split(";")); // разбиваем на термы
    			
    			for(String term: terms) { // пробегаем по термам
    				TreeSet<Integer> group = groups.get(term); // выдергиваем группу
    				
    				if(group == null) { // если группы нет
    					group = new TreeSet<Integer>();
    					groups.put(term, group);
    				}
    				group.add(line); // добваляем строку
    			}
    		}
    		
    		// выводим результат
    		for(Entry<String, TreeSet<Integer>> group: groups.entrySet()) {
    			if(group.getValue().size() >1)
    				System.out.printf("%s - %s\n", group.getKey().toString(), group.getValue().toString());
    		}
    	}
    }


    И результат

    A - [1, 3, 5]
    D - [2, 8]
    F - [0, 1, 8]
    J - [0, 5]
    X - [1, 2, 4]
    Z - [4, 5]
    Ответ написан
    33 комментария