全排列问题

一  给定一个字符串求该字符串的第k个子串。

1 一个长度为len的字符串,它的总的子串的个数为1+2+3...+len = len*(len+1)/2;
2 利用优先队列的方法:最开始先用char数组存入1个字符,因为刚开始肯定是1个字符,然后出队再将出队的那个字符串最后一个字符的下一个字符合并后再压入队列中,出队k-1次后第k次出队的就是第k大的。
比如abc,先进a,b,c,然后a先出,接着ab进,就这样反复模拟...
3 优先队列应该重载“<”,那么这样就可以使得队列里面是按照字典序排好。

代码:

例如输出字符串str,求字符串的第k个子串。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

#define MAXN 100010

int t , k;
char str[MAXN];

struct Node{
   char s[MAXN];
   int pos;
   int index;
   friend bool operator<(Node a , Node b){
      if(strcmp(a.s , b.s) > 0)
        return true;
      return false;
   }
};
priority_queue<Node>q;

int main(){
    scanf("%d" , &t);
    while(t--){
       scanf("%s%d" , str , &k);
       int len = strlen(str);

       if(k*2 > len*(len+1)){
          printf("No such line.\n\n");
          continue;
       }
       while(!q.empty())
           q.pop();
       for(int i = 0 ; i < len ; i++){
           Node node;
           node.pos = 0;
           node.index = i;
           memset(node.s , '\0' , sizeof(node.s));
           node.s[node.pos++] = str[i];
           q.push(node);
       } 

       for(int i = 0 ; i < k-1 ; i++){
          Node tmp = q.top();
          q.pop();
          if(tmp.index != len-1){
            tmp.s[tmp.pos++] = str[++tmp.index];
            q.push(tmp);
          }
       }
       printf("%s\n\n" , q.top().s);
    }
    return 0;
}

二  给定字符串求以该字符串为第一个排列,求第k个全排列的字符串
利用STL的next_perputation()函数,假设经过k次的循环后没有那么说明不存在输出-1,否则输出这第k个全排列字符串

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define N 20

int main(){
   char str[N];
   int k;
   scanf("%s" , str);
   scanf("%d" , &k);
   int len = strlen(str);
   int cnt = 1;
   sort(str , str+len);
   while(next_permutation(str , str+len)){
      if(cnt == k){
        printf("%s\n" , str);
        break;
      }
      cnt++;
   }
   if(cnt != k)
     printf("-1\n");
   return 0;
}

三  给定n个数求这n个数的第k个全排列

首先先对n个数进行排序,然后利用next_perputation()函数即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define N 20

int main(){
   int num[N];
   int n , k;
   scanf("%d%d" , &n , &k);
   for(int i = 0 ; i < n ; i++)
      scanf("%d" , &num[i]);
   sort(num , num+n);
   int cnt = 1;
   while(next_permutation(num , num+n)){
      if(cnt == k){
        printf("%d" , num[0]);
        for(int i = 1 ; i < n ; i++)
           printf(" %d" , num[i]);
        break;
      }
      cnt++;
   }
   if(cnt != k)/*没有输出-1*/
     printf("-1\n");
   return 0;
}
时间: 2024-11-02 02:53:42

全排列问题的相关文章

python标准算法实现数组全排列的方法

 这篇文章主要介绍了python标准算法实现数组全排列的方法,实例分析了全排列的原理与Python实现技巧,需要的朋友可以参考下     本文实例讲述了python标准算法实现数组全排列的方法,代码来自国外网站.分享给大家供大家参考.具体分析如下: 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列.当m=n时所有的排列情况叫全排列. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def Miden

C语言实现的全排列算法

#include <stdio.h> /************************************************************************/ /* 功能:实现两个整形参数值交换 /* 参数: /* lhs--int类型的指针,指向待交换数1的地址 /* rhs--int类型的指针,指向待交换数2的地址 /************************************************************************/

字母全排列快速算法C代码

全排列,比如字母ABC,所有排列有A ,AB,AC,ABC,ACB,B,BA,BC,BAC,BCA,C,CA,CB,CAB,CBA. //原理是插入, 在一个字符串的所有位置插入新字符.//如: AB 插入C , 位置有 1A2B3, 插入后形成 CAB ACB ABCchar *AllList(char *str, int *pNum)...{ int i, j, k, n; int len = strlen(str); int Total = 0; int count, oldcount;

求数组元素的全排列,数组不含重复元素

Permutations Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the following permutations:     [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. 求数组元素的全排列,数组不含重复元素 算法1:递归 类似于DFS的递归. 对于包含n个元素的数组,先确定第一位置

全排列的递归与非递归实现浅析

全排列问题在公司笔试的时候很常见,这里介绍其递归与非递归实现. 递归算法 1.算法简述 简单地说:就是第一个数分别以后面的数进行交换E.g:E = (a , b , c),则 prem(E)= a.perm(b,c)+ b.perm(a,c)+ c.perm(a,b)然后a.perm(b,c)= ab.perm(c)+ ac.perm(b)= abc + acb.依次递归进行. void swap(string &pszStr,int k,int m) { if(k==m) return ; c

使用javascript实现全排列算法

var Ann = function a(arr){ if(arr.length == 1){return arr;} var rr = new Array(); for(var i = 0; i<arr.length;i++){ //get a copy var ar = new Array(); for(var j = 0; j < arr.length;j++){ar[j] = arr[j];} //assume i var current = ar[i]; ar.splice(i,1)

UVa 140 Bandwidth:枚举全排列&amp;amp;剪枝搜索

140 - Bandwidth Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=108&page=show_problem&problem=76 Given a graph (V,E) where V is a set of nodes and E is a set of arcs in VxV, and anord

全排列递归算法

给出一个递归算法; 1.将一个n维数组初始化,第0位填1,第1位填2...... 第n-1位填n: 2.将数组看为两部分,一个是已排好的,剩下是待排的,分别用两个指针指向: 3.将第一个字符,依次与后n-1个字符交换值,每次交换得到一个新的首数字: 4.剩下的n-1个数字按2.3步骤重复直至所有数组完成排列: 使用c++实现,代码还有些繁琐,明天再仔细看看优化一下 1 #include<iostream> 2 using namespace std; 3 4 void swap(int *p1

全排列的编码与解码:康托展开 (附完整代码)

一.康托展开:全排列到一个自然数的双射 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! ai为整数,并且0<=ai<i(1<=i<=n) 适用范围:没有重复元素的全排列 二.全排列的编码: {1,2,3,4,...,n}的排列总共有n!种,将它们从小到大排序,怎样知道其中一种排列是有序序列中的第几个? 如 {1,2,3} 按从小到大排列一共6个:123 132 213 231 312 321.想知道321是{1,2,3}中

UVa 110 Meta-Loopless Sorts (递归&amp;amp;代码模拟&amp;amp;全排列)

110 - Meta-Loopless Sorts Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=46 Background Sorting holds an important place in computer science. Analyzing and