计算令牌在文档中出现的次数

本文关键字:令牌 文档 计算 | 更新日期: 2023-09-27 18:29:27

我已经从文档中提取了标记,并将它们插入到一个数组中。现在我想要的是确定一个令牌在文档中出现的次数。

我脑海中的当前算法获取每个令牌,并扫描整个令牌阵列以找到类似的令牌。正如您所猜测的,这不是很容易扩展。

我一直在寻找其他一些好的算法来帮助我解决这个问题。

我对SO有一些类似的问题,但他们都认为令牌是在编译时提供的。

计算令牌在文档中出现的次数

为了简化示例,假设"令牌"是整数。使用group by将令牌划分为等价类,然后计算每个组的大小。

var tokens = new[] { 10, 20, 30, 10, 30, 20, 20, 20, 10 };
var grouped = from token in tokens group token by token;
foreach (var grp in grouped)
     Console.WriteLine("{0} {1}", grp.Key, grp.Count());

输出为:

10 3
20 4
30 2

使用id为String(这是令牌)和Integer(这是计数)的Map/Hashmap。

以下是您需要的逻辑。

对于每个代币:

如果存在令牌,则通过按令牌id获取对象来增加计数,并替换旧令牌
如果令牌不存在,请将令牌添加到映射中,并将整数值设置为1。

不一定完全理解这个问题,但这就是如何对值(令牌)进行分组,然后计算它们出现的次数。

List<string> tokens = new List<string> { "A", "B", "A", "A", "B", "C"};
var tokensCount = tokens.GroupBy(g => g).Select(g => new KeyValuePair<string, int>(g.Key, g.Count()));
// Returns A 3, B 2, C 1

这个答案适用于Java

您可以使用HashMap<String,Integer>(或SortedMap<String,Integer>,如果您希望按字母顺序显示结果),其中key s是标记,value是计数。对于列表中的每个元素,您需要检查它是否已经存在于映射中。如果不是,则创建一个值为1的新密钥。如果它已经存在,只需将value(计数)增加1。

HashMap<String,Integer> counts= new HashMap<String,Integer>() ;
for(String e: myTokenList ) {
    if( counts.get(e) == null )
        counts.put(e,1);
    else
        counts.put(e,counts.get(e)+1);
}

有一种可能的微观优化:

HashMap<String,Integer> counts= new HashMap<String,Integer>() ;
for(String e: myTokenList ) {
    Integer c= counts.get(e) ;
    if( c == null )
        counts.put(e,1);
    else
        counts.put(e,c+1);
}

好的,根据其他一些建议,不要将文档中的单词插入数组中(除非你有很好的理由,这在你的问题中还没有突出显示)。

相反,将其插入到地图/字典中,例如下面的示例(注意可以更有效地完成,但这明确显示了所采取的每一步)。

var wordCounts = new Dictionary<string, int>();
var wordSeparators = new char[] {',', ' ', ''t', ';' /* etc */ };
using (var reader = File.OpenText("allmaywords.txt")
{
    while (!reader.EndOfStream)
    {
        var words = reader
            .ReadLine() 
            .Split(wordSeparators, StringSplitOptions.RemoveEmptyEntries)
            .Select(f => f.Trim()).ToList();
        foreach (var word in words)
        {
            if (!wordCounts.ContainsKey(word))
                wordCounts[word] = 1;
            else
                wordCounts[word] = wordCounts[word] + 1;
        } 
    }    
}

现在,您还可以通过以下方式访问所有唯一的单词(或令牌):

var uniqueTokens = wordCounts.Keys;

你可以发现是否存在代币:

var gotAFoo = wordCounts.ContainsKey("Foo");

以及它的出现频率:

var numbeOfFoosGiven = wordCounts["Foo"];