我正在进行一些文本分析,需要在String
中记录字符转换的频率。我有 n 个字符类别:例如,isUpperCase()
,isNumber()
和isSpace()
。
鉴于存在 n 类别,将有 n ^ 2 类别的转换,例如“isUpperCase()
- > isUpperCase()
”,“isUpperCase
- > isLetter()
”,“isLetter()
- > isUpperCase()
”等等。
给定一个文本块,我想记录发生的转换次数。我想可以构建一个Map
,其转换类型为Keys
,Integer
为Value
。
对于文本块“TO
”,Map
看起来像[isUpper -> isUpper : 1, isUpper -> isSpace : 1]
但我无法弄清楚的部分是如何构建Map
,从我所看到的情况来看,Key
将包含2个boolean
方法。
答案 0 :(得分:4)
创建一个代表字符类型的enum
- 您需要一种方法来获得给定字符的字符类型enum
。我确信有更好的方法可以做到这一点,而不是我在下面所做的,但这是留给读者的练习。
接下来创建一个方法,该方法接收先前和当前字符并将其类型连接成唯一的String
。
最后循环输入字符串并嘿presto。
private static enum CharacterType {
UPPER {
@Override
boolean isA(final char c) {
return Character.isUpperCase(c);
}
},
LOWER {
@Override
boolean isA(final char c) {
return Character.isLowerCase(c);
}
},
SPACE {
@Override
boolean isA(final char c) {
return Character.isWhitespace(c);
}
},
UNKOWN {
@Override
boolean isA(char c) {
return false;
}
};
abstract boolean isA(final char c);
public static CharacterType toType(final char c) {
for (CharacterType type : values()) {
if (type.isA(c)) {
return type;
}
}
return UNKOWN;
}
}
private static String getTransitionType(final CharacterType prev, final CharacterType current) {
return prev + "_TO_" + current;
}
public static void main(String[] args) {
final String myString = "AAaaA Aaa AA";
final Map<String, Integer> countMap = new TreeMap<String, Integer>() {
@Override
public Integer put(final String key, final Integer value) {
final Integer currentCount = get(key);
if (currentCount == null) {
return super.put(key, value);
}
return super.put(key, currentCount + value);
}
};
final char[] myStringAsArray = myString.toCharArray();
CharacterType prev = CharacterType.toType(myStringAsArray[0]);
for (int i = 1; i < myStringAsArray.length; ++i) {
final CharacterType current = CharacterType.toType(myStringAsArray[i]);
countMap.put(getTransitionType(prev, current), 1);
prev = current;
}
for (final Entry<String, Integer> entry : countMap.entrySet()) {
System.out.println(entry);
}
}
输出:
LOWER_TO_LOWER=2
LOWER_TO_SPACE=1
LOWER_TO_UPPER=1
SPACE_TO_SPACE=1
SPACE_TO_UPPER=2
UPPER_TO_LOWER=2
UPPER_TO_SPACE=1
UPPER_TO_UPPER=2
对问题内容(825个字符)运行方法需要9毫秒。
答案 1 :(得分:0)
如果您认为大多数过渡都会出现,那么二维数组最有效:
int n = _categories.size();
int[][] _transitionFreq = new int[n][n];
如果您认为它将是一个解析数组,那么地图在内存使用方面将更有效,但在性能方面效率较低。
根据您的数据和字符类型的数量,这是您需要做出的权衡。