I want to print all permutation of string in lexicographic order. I wrote this code:
void permute(char *a, int i, int n) {
if (i == (n-1)) printf(\"\\\"%s
The basic idea is to start with our main string as "" and remaining string as "abc" (or any you want).
Now to the main string append character by character. Such a way that it don't repeat the used characters (for all possible characters).
Repeat the same until you get length n ( length of main string ).
Okay, the explanation isn't clear but watch out the code. It will make everything clear.
#include<iostream>
void perm(std::string sub, std::string rem, int n)
{
if(n==0)
//print if n is zero i.e length achieved
std::cout<<sub<<"\n";
for(int i=0; i<n; i++)
//append a character and pass remaining to rem string
perm(sub + rem[i] , rem.substr(0,i) + rem.substr(i+1,n-1), n-1);
}
int main()
{
perm("", "abc", 3);
}
Output
abc
acb
bac
bca
cab
cba
Another twist on the lexical string permutations is to store the permutation in a dynamically allocated array of pointers-to-string and pass the array to qsort
to provide output in lexical order. Since permutations grow exponentially, checks for memory exhaustion after each allocation are especially important. The string size below is limited to 16 characters, which may still result in memory exhaustion depending on the amount of memory available.
Updated passing the address of the array to hold the string permutations was required for reallocation to work in the recursive function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXS 128
#define MAXC 16
size_t maxs;
void swap (char *x, char *y);
int cmp_pa (const void * a, const void * b);
char **realloc_char (char **sp, size_t *n);
void permute_pa (char ***pa, size_t *idx, char *a, int i, int n);
int main (int argc, char **argv)
{
size_t i = 0;
size_t idx = 0;
size_t len = 0;
char a[MAXC] = {0};
char **pa = NULL;
maxs = MAXS; /* initialize realloc counter */
if (argc > 1) /* set string to permute */
strcpy (a, argv[1]);
else
strcpy (a, "abc");
len = strlen (a); /* lenght to permute or MAXC */
if (len > MAXC) len = MAXC;
if (!(pa = calloc (MAXS, sizeof *pa))) /* allocate MAXS pointers */
return 1;
permute_pa (&pa, &idx, a, 0, len - 1); /* call permute function */
printf ("\n no of permutations : %zu\n\n", idx);
printf (" unsorted permutations of %s\n\n", a);
for (i = 0; i < idx; i++)
printf (" %s\n", pa[i]);
qsort (pa, idx, sizeof *pa, cmp_pa); /* sort array of permutations */
printf ("\n sorted permutations of %s\n\n", a);
for (i = 0; i < idx; i++)
printf (" %s\n", pa[i]);
for (i = 0; i < idx; i++) /* free all allocated memory */
free (pa[i]);
free (pa);
return 0;
}
/* Function to swap values at two pointers */
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
/* qsort compare function */
int cmp_pa (const void * a, const void * b)
{ return strcmp (*(char**)a, *(char**)b); }
/* realloc an array of pointers to strings setting memory to 0. */
char **realloc_char (char **sp, size_t *n)
{
char **tmp = realloc (sp, 2 * *n * sizeof *sp);
if (!tmp) {
fprintf (stderr, "Error: struct reallocation failure.\n");
// return NULL;
exit (EXIT_FAILURE);
}
sp = tmp;
memset (sp + *n, 0, *n * sizeof *sp); /* memset new ptrs 0 */
*n *= 2;
return sp;
}
/* Function to store permutations of string in array of pointers-to-string
This function takes five parameters:
1. allocated array of pointers-to-string
2. pointer to array index
3. string to permute
4. starting index of the string (zero based)
5. ending index of the string. (zero based)
*/
void permute_pa (char ***pa, size_t *idx, char *a, int i, int n)
{
int j;
if (i == n) {
(*pa)[*idx] = strdup (a);
if (!(*pa)[*idx]) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
exit (EXIT_FAILURE);
}
(*idx)++;
if (*idx == maxs)
*pa = realloc_char (*pa, &maxs);
}
else {
for (j = i; j <= n; j++) {
swap ((a+i), (a+j));
permute_pa (pa, idx, a, i+1, n);
swap ((a+i), (a+j));
}
}
}
Output
$ ./bin/str_permute_lex
no of permutations : 6
unsorted permutations of abc
abc
acb
bac
bca
cba
cab
sorted permutations of abc
abc
acb
bac
bca
cab
cba
Memory Error Check
$ valgrind ./bin/str_permute_lex
==29709== Memcheck, a memory error detector
==29709== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==29709== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==29709== Command: ./bin/str_permute_lex
==29709==
no of permutations : 6
<snip>
==29709==
==29709== HEAP SUMMARY:
==29709== in use at exit: 0 bytes in 0 blocks
==29709== total heap usage: 7 allocs, 7 frees, 1,048 bytes allocated
==29709==
==29709== All heap blocks were freed -- no leaks are possible
==29709==
==29709== For counts of detected and suppressed errors, rerun with: -v
==29709== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
from itertools import combinations
S,k = input().split()
for i in list(range(int(k)+1))[1:]:
for e in combinations(sorted(S),i ):
print(''.join(e))