Example:
input:
Number of words user want to enter : 3
Word no. 1: cat
Word no. 2: rat
Word no. 3: dog
output:
cat rat dog
cat dog rat
rat cat dog
rat dog cat
dog cat rat
dog rat cat
something like this.
Here is the code of another program, where I arranged letters in different combinations.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char character_swap(char*, char*);
void permutation(char*, int, int);
int main()
{
char str[99];
printf("Enter a string to find its permutations.\n");
scanf("%s",str);
system("clear");
int n = strlen(str);
permutation(str, 0, n-1);
return 0;
}
char character_swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void permutation(char *a, int l, int r)
{
if (l == r)
printf("%s\n", a);
else
for (int i = l; i <= r; i++)
{
character_swap((a+l), (a+i));
permutation(a, l+1, r);
character_swap((a+l), (a+i));
}
}
Can anybody tell me, how can I do the same thing with words?
You have done a good job separating the permutation
implementation from the main
interface, such that this can this be done fairly easily. First, there are a few inconsistencies,
character_swap
, one has declare return type char
, but never
return anything; must be void
. It's used only in this file, so it should be static
; this will avoid namespace conflicts let the compiler perform more aggressive optimizations. It also prevents prototype warnings as long as it is declared above.int
is not really the right type for working with indices; size_t
is more appropriate.permutation
is always going to be called with 0 index as it's second parameter. It's better to drop that and fill it in later, I have accepted the size in character_permutation
, which calls character_permutation_r
.I have generalized the type from char
to type
using a typedef
; I just replaced char
by type
. It would be simpler and clearer to replace type
by equivalent char *
, but in the next iteration, we are going to replace it with a totally opaque type; a typedef
is warranted it because it keeps them all the type information together.
#include <stdio.h>
#include <string.h>
/* This is part of the interface. */
void character_array_output(const char *a, const size_t size) {
(void)size; /* Don't use the size -- it's null-terminated. */
printf("%s\n", a);
}
/* This is the implementation. */
typedef char type;
typedef void (*character_array_action)(const type *, size_t);
static character_array_action character_print = &character_array_output;
static void character_swap(type *x, type *y)
{
type temp;
temp = *x;
*x = *y;
*y = temp;
}
static void character_permutation_r(type *a, const size_t l, const size_t r)
{
if (l == r)
character_print(a, r + 1);
else
for (size_t i = l; i <= r; i++)
{
character_swap((a+l), (a+i));
character_permutation_r(a, l+1, r);
character_swap((a+l), (a+i));
}
}
static void character_permutation(type *a, const size_t size) {
if(size == 0) return;
else character_permutation_r(a, 0, size - 1);
}
/* This is part of the interface. */
int main(void)
{
char str[99];
printf("Enter a string to find its permutations.\n");
scanf("%98s", str);
character_permutation(str, strlen(str));
return 0;
}
For your question, type
is char
, and you want it to be char *
, you just replace it with typedef char *type
. However, a generalization to any assignable type is possible.
#include <stdio.h>
#include <string.h>
/* This is the implementation.
`name` satisfies `C` naming conventions when mangled
`nametype` is an assignable type
`array_output` is a function satisfying `name##_array_action` */
#define DEFINE_PERMUTATION(name, nametype, array_output) \
typedef nametype name##type; \
\
typedef void (*name##_array_action)(const name##type *, size_t); \
\
static name##_array_action name##_array_print = &array_output; \
\
static void name##_swap(name##type *x, name##type *y) \
{ \
name##type temp; \
\
temp = *x; \
*x = *y; \
*y = temp; \
} \
\
static void name##_permutation_r(name##type *a, const size_t l, const size_t r) \
{ \
if (l == r) \
name##_array_print(a, r + 1); \
\
else\
for (size_t i = l; i <= r; i++)\
{ \
name##_swap((a+l), (a+i)); \
name##_permutation_r(a, l+1, r); \
name##_swap((a+l), (a+i)); \
} \
} \
\
static void name##_permutation(name##type *a, size_t size) { \
if(size == 0) return; \
else name##_permutation_r(a, 0, size - 1); \
}
/* This is the interface. */
void character_array_output(const char *a, const size_t a_size) {
(void)a_size;
printf("%s\n", a);
}
void string_array_output(char *const a[], const size_t a_size) {
for(size_t i = 0; i < a_size; i++)
printf("%s%s", i ? ", " : "", a[i]);
printf("\n");
}
void integer_array_output(const int *a, const size_t a_size) {
printf("{");
for(size_t i = 0; i < a_size; i++)
printf("%s%d", i ? ", " : "", a[i]);
printf("}\n");
}
typedef int (*operation)(int);
static int value;
void operation_array_output(const operation *a, const size_t a_size) {
printf("{");
for(size_t i = 0; i < a_size; i++)
printf("%s%d", i ? ", " : "", value = a[i](value));
printf("}\n");
}
DEFINE_PERMUTATION(character, char, character_array_output)
DEFINE_PERMUTATION(string, char *, string_array_output)
DEFINE_PERMUTATION(integer, int, integer_array_output)
DEFINE_PERMUTATION(operation, operation, operation_array_output)
#include <math.h>
static int square_n(const int n) { return n * n; }
static int sqrt_n(const int n) { return sqrtl(n); }
static int double_n(const int n) { return 2 * n; }
int main(void)
{
char str[] = "abc";
character_permutation(str, strlen(str));
char *strings[] = { "cat", "rat", "dog" };
string_permutation(strings, sizeof strings / sizeof *strings);
int numbers[] = { 42, 99, 1, 0 };
integer_permutation(numbers, sizeof numbers / sizeof *numbers);
operation ops[] = { &square_n, &sqrt_n, &double_n };
value = 1;
operation_permutation(ops, sizeof ops / sizeof *ops);
value = 5;
operation_permutation(ops, sizeof ops / sizeof *ops);
return 0;
}