package org.fastcatsearch.util;
import java.util.ArrayList;
import java.util.List;
/**
* Created by swsong on 2015. 7. 29..
*/
public class WordCombination {
/**
* 긴 조합부터 후보를 뽑아낸다. 단어 순서는 지켜준다. 단어순서가 없는 permutation은 연산비용이 너무 많이 들게 되므로 지원하지 않음.
* */
public static List<WordEntry> getDescCombination(List<String> candidates) {
return getDescCombination(candidates, null, 4, 10);
}
public static List<WordEntry> getDescCombination(List<String> candidates, String delimiter, int maxCombinationSize, int maxCandidateSize) {
List<WordEntry> result = new ArrayList<WordEntry>();
/*
* candidates 길이가 10을 넘을 경우 그 이상의 Term들은 제거한다.
* */
for (int i = candidates.size() - 1; i >= maxCandidateSize; i--) {
candidates.remove(i);
}
int SIZE = Math.min(candidates.size(), maxCombinationSize);
for(int m = SIZE; m > 0; m--) {
//기준위치를 앞에서 부터 한칸씩 이동시키며 후보를 찾는다.
for(int p = 0; p < SIZE; p++) {
getCombination(null, candidates, p, m, result, delimiter);
}
}
return result;
}
private static void getCombination(WordEntry word, List<String> candidates, int pos, int m, List<WordEntry> result, String delimiter) {
if(word != null) {
word.append(candidates.get(pos));
} else {
word = new WordEntry(candidates.get(pos), delimiter);
}
pos++;
m--;
if(m > 0) {
for(int p = pos; p + m - 1 < candidates.size(); p++ ){
//다음 pos부터 n-1개를 재귀적으로 뽑는다.
if( pos + m <= candidates.size() ) {
getCombination(word.deepCopy(), candidates, p, m, result, delimiter);
}
}
return;
}
result.add(word);
}
public static class WordEntry {
private String delimiter;
private StringBuffer sb;
private List<String> elements;
public WordEntry() {
this(null);
}
public WordEntry(String delimiter) {
this.delimiter = delimiter;
sb = new StringBuffer();
}
public WordEntry(String word, String delimiter) {
this.delimiter = delimiter;
sb = new StringBuffer();
append(word);
}
@Override
public boolean equals(Object o) {
return sb.toString().equals(o.toString());
}
public void append(String word){
if(delimiter != null) {
if (sb.length() > 0) {
sb.append(delimiter);
}
}
sb.append(word);
if(elements == null) {
elements = new ArrayList<String>();
}
elements.add(word);
}
public String getWord() {
return sb.toString();
}
public List<String> getElements() {
return elements;
}
@Override
public String toString() {
return sb.toString();
}
public WordEntry deepCopy() {
WordEntry newEntry = new WordEntry();
newEntry.delimiter = delimiter;
newEntry.sb = new StringBuffer(sb.toString());
List<String> newElements = null;
if(elements != null) {
newElements = new ArrayList<String>();
for(String s : elements) {
newElements.add(s);
}
}
newEntry.elements = newElements;
return newEntry;
}
}
public static class WordEntryPair {
private WordEntry entry;
private String value;
public WordEntryPair(WordEntry entry, String value) {
this.entry = entry;
this.value = value;
}
public WordEntry getEntry() {
return entry;
}
public String getValue() {
return value;
}
}
}