2012-08-04 101 views
1

我正要好奇今天d的语言,所以我看了看网站,并遇到下列WC实施来到网站:为什么在这个wc例子中字符串设置为null?

import std.stdio; 
import std.stream; 

int main (string[] args) 
{ 
    int w_total; 
    int l_total; 
    ulong c_total; 
    int[string] dictionary; 

    writefln(" lines words bytes file"); 
    foreach (arg; args[1 .. args.length]) 
    { 
     int w_cnt, l_cnt; 
     bool inword; 

     auto c_cnt = std.file.getSize(arg); 
     if (c_cnt < 10_000_000) 
     { 
      size_t wstart; 
      auto input = cast(string)std.file.read(arg); 

      foreach (j, c; input) 
      { 
       if (c == '\n') 
       ++l_cnt; 
       if (c >= '0' && c <= '9') 
       { 
       } 
       else if (c >= 'a' && c <= 'z' || 
        c >= 'A' && c <= 'Z') 
       { 
        if (!inword) 
        { 
         wstart = j; 
         inword = true; 
         ++w_cnt; 
        } 
       } 
       else if (inword) 
       { 
        auto word = input[wstart .. j]; 

        dictionary[word]++; 
        inword = false; 
       } 
      } 
      if (inword) 
      { 
       auto w = input[wstart .. input.length]; 
       dictionary[w]++; 
      } 
     } 
     else 
     { 
      auto f = new BufferedFile(arg); 
      string buf; 

      while (!f.eof()) 
      { 
       char c; 

       f.read(c); 
       if (c == '\n') 
       ++l_cnt; 
       if (c >= '0' && c <= '9') 
       { 
        if (inword) 
        buf ~= c; 
       } 
       else if (c >= 'a' && c <= 'z' || 
        c >= 'A' && c <= 'Z') 
       { 
        if (!inword) 
        { 
         buf.length = 0; 
         buf ~= c; 
         inword = 1; 
         ++w_cnt; 
        } 
        else 
         buf ~= c; 
       } 
       else if (inword) 
       { 
        if (++dictionary[buf] == 1) 
         buf = null; 
        inword = 0; 
       } 
      } 
      if (inword) 
      { 
       dictionary[buf]++; 
      } 
     } 
     writefln("%8s%8s%8s %s\n", l_cnt, w_cnt, c_cnt, arg); 
     l_total += l_cnt; 
     w_total += w_cnt; 
     c_total += c_cnt; 
    } 

    if (args.length > 2) 
    { 
     writefln("--------------------------------------\n%8s%8s%8s total", 
     l_total, w_total, c_total); 
    } 

    writefln("--------------------------------------"); 

    foreach (word1; dictionary.keys.sort) 
    { 
     writefln("%3s %s", dictionary[word1], word1); 
    } 
    return 0; 
} 

不管怎么说,在线86,代码集BUF到当它是字典中第一个出现的单词时为空。

   if (++dictionary[buf] == 1) 
       buf = null; 
      inword = 0; 
      } 

这样做的好处是什么?我测试了该部分遗漏的方法,并得到了相同的结果。

+3

这个例子其实很过时。我相信它甚至早于D2。我看不出它将buf设置为null的原因。关联数组页面[有一个版本](http://dlang.org/hash-map.html)似乎更符合D编码惯例。 – eco 2012-08-04 01:03:04

+0

@eco:您可能想将其作为答案。 – Infiltrator 2012-09-13 05:10:23

回答

0

我只是猜测在这里。但是,这是非常古老的代码,所以原因可能与不可变的。在旧版本的D中,类型系统中不存在不可变的情况,所以字符串只是普通字符[]的别名。

在一个关联数组中,如果你改变一个键,它可以打破它,因为散列不匹配 - 你可以在树中得到两个条目,应该只有一个和其他难以发现的错误(因此在较新的D版本,如果你尝试int [char []],它会抱怨密钥必须是不可变的)。

将代码为新单词执行的更改长度为零可能会重新使用现有缓冲区。我很确定它现在不会,但也许当时是这样做的。这可能会覆盖散列表中的现有条目。将其设置为空可确保实际上分配了新的缓冲区。底线:它在编写时可能会在没有该行的情况下随机不工作。

相关问题