2012-08-04 2 views
1

나는 D 언어 오늘 약에 대한 호기심이었고, 그래서 나는 웹 사이트를 살펴 가져다가 웹 사이트에 다음과 같은 화장실 구현 건너 온 : 코드 세트 버피에 라인 (86)에이 예제에서 문자열이 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; 
} 

어쨌든 사전에서 단어가 처음 나오는 경우 null입니다.

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

이렇게하면 어떤 이점이 있습니까? 나는 그 부분이 빠져있는 방법을 테스트했고, 나는 같은 결과를 얻었다.

+3

예는 실제로 날짜가 오래되었습니다. 나는 그것이 심지어 D2보다 선행한다고 믿는다. buf를 null로 설정하는 이유를 알 수 없습니다. Associative Array 페이지 [버전 있음] (http://dlang.org/hash-map.html)은 D 코딩 규칙에 따라 최신으로 보입니다. – eco

+0

@eco : 답으로 답을 넣을 수 있습니다. – Infiltrator

답변

0

저는 여기서 추측하고 있습니다. 하지만 꽤 오래된 코드이기 때문에 이유는 아마도 불변의 것과 관련이 있습니다. 이전 버전의 D에서는 타입 시스템에 불변 (immutable)이 없었기 때문에 문자열은 일반 char []에 대한 별명이었습니다.

연관 배열에서 키를 변경하면 해시가 일치하지 않으므로 깨질 수 있습니다. 트리에서 하나만 있어야하고 다른 버그를 찾기 위해 두 개의 항목을 얻을 수 있습니다 (따라서 최신 D 버전에서는 int [char []]를 사용하면 키가 변경되지 않아야한다고 불평 할 것입니다.

코드가 새 단어에 대해 수행하는 길이를 0으로 변경하면 기존 버퍼를 다시 사용할 수 있습니다. 나는 지금 당장은 아니 겠지만, 아마도 그 당시에했을 것이라고 확신합니다. 이렇게하면 해시 테이블의 기존 항목을 덮어 쓸 수 있습니다. 이것을 null로 설정하면 실제로 새로운 버퍼가 할당됩니다.

결론 : 작성 당시의 라인이 없으면 무작위로 작동하지 않을 가능성이 높습니다.

관련 문제