微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将n个“words”文件8个随机字母按字典顺序排序,放到一个output.txt文件中

如何解决将n个“words”文件8个随机字母按字典顺序排序,放到一个output.txt文件中

我得到了 n文件,例如 3 个文件,大约有 400000 个单词,由八个“随机”字母组成,例如。 aaabcdfe。每个文件都按字典顺序排列,我应该按照排序和字典顺序将所有文件合并到一个输出文件中(无重复)。
我知道如何将它们从文件获取到数组,反之亦然。我的主要问题是空间(大约 32MB)。我正在尝试将文件分成小块(可能是 60000 个单词,每个文件 20k,然后将它们合并在一起),但我真的不确定如何去做。想象一下,我有一个大约 30k 字的数组,我可以从那里去哪里?我应该把它们放在一个文件还是输出文件中。我应该将它们合并在一起而不使用数组吗?另一个问题是我只能将一个文件写入输出,因为如果我先写入一个文件,然后再写入另一个文件,第二个文件会覆盖所有第一个文件,现在输出中只剩下第二个文件。我想过优先队列,但到目前为止还没有取得任何进展。
我还在学习,因为这对我来说是全新的,如果这有点小菜,很抱歉。只是在此类事情上寻求有经验的人的提示

解决方法

对于现代计算机来说,现在 100-200MB 的数据并不多,因此在许多情况下,文件合并和 Array.Sort() 可能会为您解决问题。

但是,如果条目或文件的数量急剧增加,也许您可​​以选择更安全的算法,例如,通过按首字母对条目进行分组。您可以将所有文件中以“A”或“a”开头的所有单词加载到列表中,然后对列表进行排序(yourList.Sort()),然后将其写入输出文件。然后,再选择字母“B”/“b”,依此类推。

通过按第一个字母(或前 2 个字母,如果需要)分组,您可以确保在任何时候完成的排序不会被后续条目加载修改。

编辑。在伪代码中它会是这样的:

  char[] myLetters = ['a','b','c','d',...];

// open a read connection to all involved files and store its read pointer in and array called myLetters

// create a file and open a write connection

outputFile = File.Open(filename,"Write");

 foreach(char lett in myLetters)
 {
   List myCurrentLetterEntriesList = new List();
   foreach(File f in allMyFiles)
   {
       string Entry = f.ReadLine();

       while(Entry.FirstLetter == lett )
       {
          myCurrentLetterEntriesList .Add( Entry );
  
          Entry = f.ReadLine();
       }

       f.Seek(-1,CurrentPosition); //to start in the last entry that was discarded

   }

    myCurrentLetterEntriesList.Sort();
 
    string previousEntry =  myCurrentLetterEntriesList[0]
    outputFile.WriteLine(previousEntry);

    for i=1:myCurrentLetterEntriesList.count-1
    {
      string entry = myCurrentLetterEntriesList[i];
      if(entry!=previousEntry )
      { 
          outputFile.WriteLine(entry);
          previousEntry=entry;
      }
     }
  }

  //Close connections to input and output files

,

(I'm really not sure on how to do it,where do I go from there? 这更多是程序开发方法和实践的问题Software Engineering Stack Exchange 的主题 - 堆栈上的主题溢出)和问题解决(不是我所知道的任何 SE 网站的主要主题)。


答案有帮助/正确的变化 - 1960 年代的真实情况不一定会延续到当前的千禧年,或今天的智慧到 2050 年:
学习问题和相应答案在生活中的用处不如备考。

  • My main problem is the space (around 32MB)
    你怎么知道的?
    32 MB 是 2020 年计算服务器处理器的“最远级缓存”的数量级。
    400000 个 8 个字母的单词更有可能出现在大约 3.2 MB 的文件中(是​​ 400000 个单词total 还是 每个文件?)。
    在许多现代运行时环境中,每个字符在内存中占用两个字节 - 即使是 3*400000*8 个字符,也不足 20 MB(如果一次转换/存储许多/所有单词,“每个单词的开销”可能加起来:测量)。
    虽然我认为在旅途中尝试发现可能的问题很有用:
    开始简单。测试按预期工作测量
  • divide the files into [say 20 chunks each…merge them together…Imagine…] an array sorted as [specified]
    刚刚做了:你怎么知道文件 2 中 next(未读)块的最后一个单词不需要在文件 1 中的第一个之前?
    作为一种极端情况,想象任何一个文件中的所有单词都以相同的字母开头,在所有文件中都是独一无二的,例如 'n''o''t'

对“这个”问题的传统回答似乎是

  • 构建一个优先队列PQ,其中包含来自每个序列的一个记录,并指示它来自哪个序列
  • 虽然 PQ 不为空
    • 将 PQ 中最高优先级的记录 R 替换为相同序列中的下一条记录(如果有),否则只需提取 R
    • 输出R,偏离“标准问题和解决方案”:如果不等于之前的输出
      (或者避免在 PQ 中插入重复项

-我不一定买。
我希望我能衡量一下“微不足道的方法”:阅读整个shebang并对其进行标准排序不行,接下来使用上面的方法。
如果两者都没有削减它,我应该寻找“其他”“明显”的改进,例如尝试将八个字母的词作为64位机器词处理.
失败了,我可能会尝试分批读取文件,将 PQ 保持在 已经从每个文件中读取的最后/最低优先级单词/记录的上面,并愉快地处理记录,直到输出一个等于来自 PQ 的最高优先级记录,从它的文件中读取另一个批次。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。