3.1.26

3.1.26 #

解答 #

字典文件:https://introcs.cs.princeton.edu/java/data/web2.txt

《双城记》:https://introcs.cs.princeton.edu/java/data/tale.txt

浏览器可能会直接打开 txt,此时右键链接-目标另存为即可下载。

FrequencyCounter 的官方实现:https://algs4.cs.princeton.edu/31elementary/FrequencyCounter.java.html

我们利用 BinarySearchST 会自动对键排序的性质来实现字典序排序。

首先将字典存到一个符号表中,按照 “单词-序号” 的形式保存。

然后读入文件,如果读入的单词存在于字典中,

则将其以 “序号-单词” 的形式存到 BinarySearchST 中去。

读入完毕后,遍历 BinarySearchST 即可获得字典序的单词列表。

对于按频率排序,我们基于已有的实现修改。

在每次取得最大值之后,输出并删除最大值,如此循环即可获得频率排序的单词序列。

也可以将单词-频率序列全部读出来存放到数组之中,然后用第二章的排序算法排序。

测试结果,取 minLength = 13,只截取了部分。

代码 #

public static void LookUpDictionary(string filename, string dictionaryFile, int minLength)
{
    // 初始化字典
    var sr = new StreamReader(File.OpenRead(dictionaryFile));
    var words = sr.ReadToEnd().Split(new[] { ' ', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
    var dictionary = new BinarySearchSt<string, int>();
    for (var i = 0; i < words.Length; i++)
    {
        if (words[i].Length > minLength)
            dictionary.Put(words[i], i);
    }
    sr.Close();

    // 读入单词
    var srFile = new StreamReader(File.OpenRead(filename));
    var inputs = srFile.ReadToEnd().Split(new[] { ' ', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
    srFile.Close();

    var stDictionary = new BinarySearchSt<int, string>();
    var stFrequency = new BinarySearchSt<string, int>();
    foreach (var s in inputs)
    {
        if (stFrequency.Contains(s))
            stFrequency.Put(s, stFrequency.Get(s) + 1);
        else if (dictionary.Contains(s))
        {
            stFrequency.Put(s, 1);
            stDictionary.Put(dictionary.Get(s), s);
        }
    }

    // 输出字典序
    Console.WriteLine("Alphabet");
    foreach (var i in stDictionary.Keys())
    {
        var s = stDictionary.Get(i);
        Console.WriteLine(s + "\t" + stFrequency.Get(s));
    }

    // 频率序
    Console.WriteLine("Frequency");
    var n = stFrequency.Size();
    for (var i = 0; i < n; i++)
    {
        var max = "";
        stFrequency.Put(max, 0);
        foreach (var s in stFrequency.Keys())
            if (stFrequency.Get(s) > stFrequency.Get(max))
                max = s;
        Console.WriteLine(max + "\t" + stFrequency.Get(max));
        stFrequency.Delete(max);
    }
}

另请参阅 #

SymbolTable 库