【问题标题】:Would this method be efficient at finding string permuations这种方法在查找字符串排列方面是否有效
【发布时间】:2015-10-16 11:16:17
【问题描述】:
#include <iostream> 
#include <string>
using namespace std; 
int main()
{
    string word;
    cin>>word; 
    int s = word.size();
    string original_word = word; 
    do
    {          
        for(decltype(s) i =1; i!= s;++i){
            auto temp =word[i-1]; 
            word[i-1] = word[i];
            word[i] = temp; 
            cout<<word<<endl; 
        }
    }while(word!=original_word); 
}

此解决方案是否有效?通过递归执行此解决方案的效果如何?

编辑:当我测试程序时,它显示了所有排列 即猫生产: 猫 行为 atc tac tca cta

【问题讨论】:

  • 我会比较它与使用std::next_permutation()
  • 从考虑正确性开始,而不是效率。上面的代码不可能生成所有的排列。
  • 这需要 2 * s^2 时间。 (它会将第一个字母冒泡到列表的末尾)。它基本上会显示需要反转单词然后反转反转单词的步骤。这并没有给你所有的排列。你至少需要(s!时间来找到这个词的所有排列)。我建议只在字符串上使用std::next_permutation()。这是正确的,它应该是相当有效的。
  • here 一个演示,其中您的代码显示缺少排列:1342、1324、1432... 丢失。

标签: c++ string performance c++11 permutation


【解决方案1】:

让我们想象在输入 12345 上跟踪此代码。在第一次通过 do ... while 循环时,您的代码将通过这些配置逐步执行数组:

 21345
 23145
 23415
 23451

请注意,在此循环迭代完成后,您已将数组循环移动了一步。这意味着在下一个 do ... while 循环结束时,您将循环移动数组两次,然后是 3 次,然后是 4 次,等等。在 n 次迭代之后,这会将数组重置回其原始配置.由于每次将字符冒泡到末尾都会经过 n 个中间步骤,这意味着您的方法将生成最多 n2 个输入字符串的不同排列。但是,有 n!输入字符串的可能排列,以及 n!对于所有 n ≥ 4,都大大超过了 n2。因此,这种方法无法生成所有可能的排列,因为它在返回开始之前不会产生足够的唯一组合。

如果您有兴趣了解通过单个交换枚举排列的大量不同方法,您可能需要获取《计算机编程艺术》的副本或在线搜索不同的方法。这是一个非常有趣的话题,在研究这些算法的过程中,我认为你会学到很多方法来分析不同的算法并证明其正确性。

【讨论】:

    猜你喜欢
    • 2016-12-12
    • 2014-07-31
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    • 2012-09-03
    • 2013-09-10
    相关资源
    最近更新 更多