2

私はいくつかのテキスト分析を行っており、文字遷移の頻度を に記録する必要がありますString。私は文字のnカテゴリを持っています: 例のためにisUpperCase()isNumber()、 、isSpace().

n 個のカテゴリがあるとすると、 " -- > "、" --> "、" --> " など、n^2 個の遷移カテゴリがあります。isUpperCase()isUpperCase()isUpperCaseisLetter()isLetter()isUpperCase()

テキストのブロックを指定して、発生した遷移の数を記録したいと思います。Mapトランジション タイプを として、Keysを として、Integerをそれぞれとして構築することを想像しますValue

テキストのブロック " TO" の場合、は次のMapようになります。[isUpper -> isUpper : 1, isUpper -> isSpace : 1]

しかし、私が理解できない部分は、Map私が見ることができるところKeyから、2つのメソッドで構成される場所を構築するboolean方法です。

4

2 に答える 2

4

文字タイプを表す を作成します。指定されたenum文字タイプを取得する方法が必要ですenum。以下で行った方法よりも良い方法があると確信していますが、それは読者への演習として残されています。

次に、前の文字と現在の文字を取得し、それらの型を一意の に連結するメソッドを作成しますString

最後に、入力文字列をループして、さあさあ。

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 ミリ秒かかりました。

于 2013-03-20T12:33:56.613 に答える
0

ほとんどの遷移が存在すると思われる場合は、2 次元配列が最適です。

int n = _categories.size();
int[][] _transitionFreq = new int[n][n];

解析配列になると考えられる場合、マップはメモリ使用量の点でより効率的になりますが、パフォーマンスの点では効率が低下します。

これは、データと文字タイプの数に応じて行う必要があるトレードオフです。

于 2013-03-20T12:45:15.983 に答える