• SSD6中Exercise4 (substitute.cpp) 答案解析


    今天终于把Exercise4搞定了,昨天大约优化了0.38秒,今天优化了0.52秒,跨越了一大步。

    在我们未加任何修饰执行此代码时,其执行后所用时间如图(摘抄主要): 

    Function Callee Exclusive Time
    main 1.495306

    IndexOf( String, int32 )

    0.771013
    insertChar( String, int32, String, int32 ) 0.444054

    我们发现insertChar()函数里面就一条return语句,这完全没必要,何必还调用一个函数呢,申请栈释放栈很浪费时间,然后我们去掉这个函数,直接在别的函数里面用它里面的语句。

    我们再来看

    1. for (int i = 0; i < replacement->Length; i++) {
    2.         data = insertChar(data, loc+i, replacement, i);
    3.         // data->Insert(loc + i, replacement->Substring(i, 1));
    4.     }

    这个也没必要,何必一个一个的插入呢?整体插入就算了。因而可以改为

    1. return data->Insert(loc,replacement);

    对于indeof函数,占的时间实在太多,是该解决一下它,在原函数中间是这样的:

    1. for (loc = data->IndexOf(pattern, 0); loc >= 0;
    2.                 loc = data->IndexOf(pattern, 0)) {
    3.                 // replace word
    4.                 data = replace_word(data, loc, pattern->Length, replacement);
    5.             }   

    没必要总是从第一个找起吧!起先我想的是从上一次查找的结束的下一个位置开始查找,但这样有一个问题。例如我们用dd替换cd,有一个字符串为cccd,第一次替换后为ccdd,不应该只是往后找,因为此时前面也出现了cd,故而在这里我们可以从新得到的loc 前 pattern->length处开始查找,再往前开始找没意义。在这里还就是pattern->Length最好在外面用一个变量代替,如pl,放置循环次次都计算pattern->Length(你可能认为编译器足够聪明,但我们不敢保证它在这里“敢”优化,毕竟pattern是个指针,随时可以变,还是我们替他提早优化,参考《深入理解计算机系统》)。

    故而这段程序改为:

     

    1. int location = 0;
    2.         int pl = pattern->Length;
    3.         // find every occurrence of pattern:
    4.         for (loc = data->IndexOf(pattern, 0); loc >= 0;
    5.             loc = data->IndexOf(pattern, location)) {
    6.                 // replace word
    7.                 int dis = loc - pl;
    8.                 if (dis >= 0)
    9.                 {
    10.                     location = dis;
    11.                 } 
    12.                 else
    13.                 {
    14.                     location = 0;
    15.                 }
    16.                 data = replace_word(data, loc, pl, replacement);

    改过的程序为:

    1. #include <iostream>
    2. using namespace std;
    3. using namespace System;
    4. using namespace System::IO;
    5. using namespace System::Text;
    6. //String* insertChar(String *data, int loc, String *replacement, int i) {
    7. //  return data->Insert(loc, replacement->Substring(i, 1));
    8. //}
    9. String* replace_word(String* data, int loc, int length, String* replacement) {
    10.     // delete the pattern string from loc:
    11.     data = data->Remove(loc, length);
    12.     // insert each character of the replacement string:
    13.     //for (int i = 0; i < replacement->Length; i++) {
    14.     //  data = insertChar(data, loc+i, replacement, i);
    15.     //  // data->Insert(loc + i, replacement->Substring(i, 1));
    16.     //}
    17.     return data->Insert(loc,replacement);
    18.     //->Insert(loc,replacement)
    19. }
    20. String* string_subst(String *data, String *pattern, String *replacement) {
    21.     try {
    22.         int loc;
    23.         int location = 0;
    24.         int pl = pattern->Length;
    25.         // find every occurrence of pattern:
    26.         for (loc = data->IndexOf(pattern, 0); loc >= 0;
    27.             loc = data->IndexOf(pattern, location)) {
    28.                 // replace word
    29.                 int dis = loc - pl;
    30.                 if (dis >= 0)
    31.                 {
    32.                     location = dis;
    33.                 } 
    34.                 else
    35.                 {
    36.                     location = 0;
    37.                 }
    38.                 data = replace_word(data, loc, pl, replacement);
    39.         }   
    40.         return data;
    41.     } catch (Exception *e) {
    42.         Console::WriteLine("Error in substitute ");
    43.         Console::WriteLine(e->ToString());
    44.         return data;
    45.     }
    46. }
    47. String* batch_subst(String *data, const char* subs_filename) {
    48.     try {
    49.         String *subs_file = new String(subs_filename);
    50.         StreamReader *subs_reader = new StreamReader(subs_file);
    51.         String *pattern, *replacement, *separator;
    52.         while (subs_reader->Peek() >= 0) {
    53.             pattern = subs_reader->ReadLine();
    54.             replacement = subs_reader->ReadLine();
    55.             separator = subs_reader->ReadLine();
    56.             data = string_subst(data, pattern, replacement);
    57.         }
    58.         return data;
    59.     } catch(Exception* e ) {
    60.         Console::WriteLine( "Error in do_substitutions ");
    61.         Console::WriteLine( e->ToString());
    62.         return data;
    63.     }
    64. }
    65. void process_file(const char* filename, const char* subs_filename) {
    66.     StreamReader *reader;
    67.     StreamWriter *writer;
    68.     String *file = new String(filename);
    69.     try {
    70.         reader = new StreamReader( file );
    71.         String *data = reader->ReadToEnd();
    72.         data = batch_subst(data, subs_filename);
    73.         reader->Close();
    74.         // write the data
    75.         writer = new StreamWriter(file, false);
    76.         writer->Write(data);
    77.         writer->Close();
    78.     }  catch(Exception* e) {
    79.         Console::WriteLine( "Error while processing file ");
    80.         Console::WriteLine( e->ToString());
    81.     }
    82. }
    83. int main(int argc, char *argv[]) {  
    84.     if (argc < 3) {
    85.         cout << "Not enough input arguments" << endl;
    86.         cout << "Usage: substitute subs-file src1 src2 ..." << endl;
    87.     } else {
    88.         for (int i = 2; i < argc; i++) {
    89.             process_file(argv[i], argv[1]);
    90.         }
    91.     }
    92.     return 0;
    93. }

    我还准备优化那个reader->Close();writer->Close();没必要每次都关闭。但尝试了一下,最终失败。希望看过此文章的人不吝赐教,多多指导,共同学习。

    ---
    可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
  • 相关阅读:
    Android随笔
    Android随笔
    阅读笔记
    Android随笔
    Android随笔
    Android随笔
    Android随笔
    Java随笔
    Android随笔
    NC20265 着色方案(dp)
  • 原文地址:https://www.cnblogs.com/null00/p/2065099.html
Copyright © 2020-2023  润新知