第一次个人项目进度(二)

  功能编码已经完成且输出格式正常。

  单词数、行数输出与样例差别不大,而字符数相差则略多。

  程序效率比较低,遍历测试用例需要1分钟左右。

  尚有一些时间可以进行优化工作,保险起见先提交一次。

 

  一个问题:

  今天80%的编程时间都用在了设计和实现词组统计上,最后得出的程序却在意想不到的地方遭到了滑铁卢,无奈之下只能推导重来。

  而导致错误的问题至今仍然无法得知。

  词组的计数方式较为特殊,在连续的文字中,每个单词都可能与前后两个单词构成词组。由于我的读取文件基于infile.get()函数,而不是一般的getline读入整行至字符数组,且不想过多申请辅助空间,因此试图通过操作文件指针来实现暂存中间的单词(且这样的方法可以直接合并到单词数的统计中去)。这样则要用到streampos这个数据类型。主要用到的操作如下。

ps=infile.tellg();   //获取当前文件指针位置,存在ps中
infile.tellg(ps);   //将文件指针置于ps处

  每读取一个单词(符合要求的单词)后,使用.tellg获取文件指针的位置(此时文件指针应该在第一个单词后的分隔符处),在下一个单词读取完毕后,退回到之前保存的指针位置,然后再继续读取连续的两个单词。

  基于此的统计算法对于大部分文件可以正常运行,但在某些源代码文件,比如样例中的Any.h和core.hpp之中,会变为死循环,一条一条代码的调试,得到了一个非常奇怪的问题,如下:

  

  读取完"separating"后,tellg得到ps位置在separating后的分隔符处,Fpos参量为指针在文件中的位置,此处返回了4222。

  中间操作删去后,下一条语句即为seekg,即将指针置入ps处,此处相当于位置没有变,本次循环结束。

  下一次循环,继续读取“this”。

  

  读取完this后,tellg得到ps位置,正常来说,这个指针位置应该是4227,但此时ps的Fpos参量竟然返回了4217,也就是说返回的位置在左侧"separating"的“a”字母处。

  seekg将指针置入ps处,指针回退至4217位置,进行下一次循环。

  到这里我们就能发现,这个奇怪的BUG,不仅会导致读取出错,也会导致程序在separating和this直接不断地进行循环。

  这个死循环并没有抛出异常信息(程序停止工作),因此定位花了我非常多的时间。

  更进一步。

  去除其他所有无关操作,仅执行读取位置和置入位置操作,且连续执行。代码如下:

while(infile.get(c)){
    ps=infile.tellg();
    infile.seekg(ps);
}

  连续执行读取和置入操作,应该是在哪读取,就置入在哪,结果相当于没有执行任何操作。

  但是实际上新建工程,仅使用上面几行代码,对Any.h或core.hpp文件进行操作,仍然会进入死循环,但程序保持执行,并不抛出异常信息。

  这个 BUG的原理我仍然没有查明,欢迎同学、助教和老师们回复指导!

 

  换用getline方法编写词组的统计,有每行字符数未知的问题(字符数组的大小难以初始化)。

  因此还是单独编写词组统计函数,使用infile.get()读取到字符数组的方式,申请更多的辅助空间。由于统计词组时不需要考虑行数的问题,因此根据单词大小的上限即可确定字符数组的大小,使用两个字符数组即可。

posted @ 2018-03-29 00:49  Ignoramus  阅读(149)  评论(1编辑  收藏  举报