为什么第二个for循环比第一个慢两倍?

时间:2014-07-23 17:54:43

标签: palindrome

我编写了这个函数来检查输入字符串的任何子字符串是否为回文结构。我期望以下两个版本的代码花费的时间完全相同,因为逻辑非常相似。但是,版本1大约需要151毫秒,而版本2在测试输入上需要350毫秒以上。

此外,如果我用cout<<替换setPalindrome “”<< endl ;,两个版本的运行时间完全相同。

我想知道在setPalindrome的情况下造成巨大时差的原因是什么?

我的测试输入是字符串s =“kwtbjmsjvbrwriqwxadwnufplszhqccayvdhhvscxjaqsrmrrqngmuvxnugdzjfxeihogzsdjtvdmkudckjoggltcuybddbjoizu”;

void setPalindrome(string s, int start, int length, map<pair<int, int>, bool>& palindrome){

   auto key = make_pair(start, length);

   // no key in map

   if (palindrome.find(key) == palindrome.end()){

         if (s[start] == s[start + length - 1] && length >= 3){

                palindrome[key] = palindrome[make_pair(start + 1, length - 2)];

         }

         else if (s[start] == s[start + length - 1] && length <= 2){

                palindrome[key] = true;

         }

         else{

                palindrome[key] = false;

         }

   }

}

版本1:

int minCut(string s) {

   int size = s.size();

   map<pair<int, int>, bool> palindrome;

   vector<int> minCuts;



   for (int i = 0; i < size; i++){

         palindrome[make_pair(i, 1)] = true;

         minCuts.push_back(size - i - 1);

   }



   for (int i = size; i >= 0; i--){

          for (int j = 2; i + j <= size; j++){

                setPalindrome(s, i, j, palindrome);

          }

   }

   return 0;

}

第2版:

int minCut(string s) {

   int size = s.size();

   map<pair<int, int>, bool> palindrome;

   vector<int> minCuts;



   for (int i = 0; i < size; i++){

         palindrome[make_pair(i, 1)] = true;

         minCuts.push_back(size - i - 1);

   }



   for (int i = size; i >= 0; i--){

         for (int j = size - i; j >= 2; j--){

                setPalindrome(s, i, j, palindrome);

         }

   }

   return 0;

}

1 个答案:

答案 0 :(得分:1)

造成这种时差的最可能原因是您正在使用的地图。因为c ++内部使用平衡树数据结构,所以插入树的顺序很重要。

您的第二版以严格递减的顺序插入树中,从而导致最大数量的平衡操作发生。这可能需要很长时间。

您的第二版也使循环索引搞砸了。你应该从大小开始 - 而不是大小。

for (int i = size - 1; i >= 0; i--){
         for (int j = size - i; j >= 2; j--){
                setPalindrome(s, i, j, palindrome);
         }
}