用于计算{a,b,c}长度为n的字符串数w的C ++程序

时间:2016-03-23 05:24:58

标签: c++ permutation

我尝试生成长度为n的所有字符串,以便字符串4的长度为w的所有子字符串都出现,而所有三个字母a, b, c都会出现。例如,abbcaabca时应打印n = 9,但不应包含aabbcabac

现在我只打印所有排列,但我不知道如何只打印这种语言的排列。

void swap(char *x, char *y)
{
  char temp;
  temp = *x;
  *x = *y;
  *y = temp;
}

void permute(char *a, int l, int r)
{

  int i;
  if (l == r)
    printf("%s\n", a);

  else
    {
      for (i = l; i <= r; i++)
        {
          swap((a+l), (a+i));
          permute(a, l+1, r);
          swap((a+l), (a+i));                                             
        }
    }
}

int main(){
  int n;
  cout << "Enter n: " << endl;
  cin >> n;
  char str[] = "abc";
  int x = n % 3;
  if (x != 0){
    for (int i = 0; i < x; i++)
      *str = *str + str[i];
  }
    permute(str, 0, n - 1);
  return 0;
}

2 个答案:

答案 0 :(得分:0)

这个解决方案怎么样?

#include <set>
#include <string>
#include <iostream>

void genStrList (std::set<std::string> & setStr,
                 std::size_t const       len,
                 std::string const     & nowStr,
                 std::string const     & poolCh)
 {
   int  i;

   std::set<char>  noLast3;

   std::string::const_reverse_iterator  cri;
   std::string::const_iterator          ci;

   if ( 2U < nowStr.size() )
    {
      for ( ci = poolCh.begin() ; ci != poolCh.end() ; ++ci )
         noLast3.insert(*ci);

      for ( cri = nowStr.rbegin(), i = 0 ; i < 3 ; ++cri, ++i )
         noLast3.erase(*cri);
    }

   if ( 2U > noLast3.size() )
    {
      for ( ci = poolCh.begin() ; ci != poolCh.end() ; ++ci )
         if ( noLast3.empty() || (noLast3.end() != noLast3.find(*ci)) )
          {
            if ( nowStr.size() + 1U == len )
               setStr.insert(nowStr+(*ci));
            else
               genStrList(setStr, len, nowStr+(*ci), poolCh);
       }
    }
 }


int main()
 {
   std::size_t n;

   std::cout << "Enter n: " << std::endl;
   std::cin >> n;

   std::set<std::string>  setStr;

   genStrList(setStr, n, "", "abc");

   std::set<std::string>::const_iterator  ci;

   for ( ci = setStr.begin() ; ci != setStr.end() ; ++ci )
      std::cout << "- " << (*ci) << '\n';

   return 0;
 }

答案 1 :(得分:0)

一个明显的解决方案是增加块

scope=openid%20profile

以便它检查字符串/* ... */ if (l == r) printf("%s\n", a); /* ... */ 是否满足条件,即,过去四个字符(a)中的每个索引3 <= i < n是否都满足条件{{1} },a[i-3], ..., a[i]a发生。这可以在b时轻松完成(其中c是字符串O(n)的长度)。总体运行时间从n增加到a

一个更“聪明”的解决方案是运行簿记 - 一个你在每次递归调用中修改的全局变量 - 这样你就可以提前修剪坏分支(即你不进行进一步的递归调用如果字符串的开头违反了条件)。在这种情况下,运行时间为O(n!)(即渐近地快于O(n!*n);请参阅little-o notation)。