问题描述:

他递给你一个字符串,问你是否可以用它的字符创造尽可能多的不同的单词.

兴奋地想要试一试,你就得工作.这感觉有点像是解决了一个难题,并找到了新的方法来排列字母. 每一次的编排都透露了一个有趣的新词.你Eager 地投入到这项任务中,准备发现所有不同的单词 你可以用这些给定的字母来创造.

输入约束:1 <= n <= 8

输入:唯一的输入行有一个长度为n的字符串.每个字符都在"a-z"之间.

输出:首先打印一个整数k:字符串的个数. 然后打印k行:按字母顺序打印字符串.

这是我的代码,想问问如何修改,以获得所需的输出按字母顺序.时间限制为1秒.

#include <stdio.h>
#include <string.h>
#include "quick_sort.h"
#include "swap.h"

void permutations(char array[], short length, short left)
{
    if (left == length)
    {
        //swap(&array[left - 1], &array[i]);
        printf("%s", array);
    }
    else
    {
        for (int i = left; i <= length; i++)
        {
            int is_duplicate = 0;
            for (int j = left; j < i; j++)
            {
                if (array[j] == array[i])
                {
                    is_duplicate = 1;
                    break;
                }
            }
            if (!is_duplicate)
            {
                swap(&array[left], &array[i]);
                permutations(array, length, left + 1);
                swap(&array[left], &array[i]);
            }
        }
    }
}

void main(void)
{
    char input[10] = "";
    fgets(input, 9, stdin);
    short str_len = strlen(input);
    //printf("%hd", str_len);
    quicksort(input, str_len - 1);
    //fputs(input, stdout);
    permutations(input, str_len - 2, 0);
    /*quicksort(input, str_len);*/
}

推荐答案

以下是基于Knuth的《计算机编程的艺术》第四卷第二章中的算法L的内容.

在输出任何字符串之前,程序需要输出字符串的数量.count_permutations()函数用于计算将输出的字符串数.如果长度为n的字符串中的所有字符都不同,则数字只是n的阶乘.对于字符串中的每个不同字母,该数字需要除以该字母出现次数的阶乘.例如,如果字符串由1‘a’、2‘b和5’c组成,总长度为8,则字符串数将为8!/(1!×2!×5!)=40320/(1×2×120)=168.

#include <stdio.h>
#include <string.h>
//#include "quick_sort.h"
//#include "swap.h"
#include <stdlib.h>

void swap(char *a, char *b)
{
    char x = *a;
    *a = *b;
    *b = x;
}

int cmpchar(const void *a, const void *b)
{
    char av = *(const char *)a;
    char bv = *(const char *)b;
    return (av > bv) - (av < bv);
}

void quicksort(char *arr, size_t len)
{
    qsort(arr, len, sizeof *arr, cmpchar);
}

unsigned int factorial(unsigned int n)
{
    unsigned int fac = 1;
    unsigned int i;

    for (i = 2; i <= n; i++)
    {
        fac *= i;
    }
    return fac;
}

unsigned int count_permutations(const char *a, unsigned int n)
{
    unsigned int count = factorial(n);
    unsigned int i;
    unsigned int run;

    run = 0;
    for (i = 0; i < n; i++)
    {
        if (i == 0 || a[i] != a[i - 1])
        {
            count /= factorial(run);
            run = 0;
        }
        run++;
    }
    count /= factorial(run);
    return count;
}

/* Steps L2 to L4 of Knuth's 算法rithm L. */
int permute(char *a, int n)
{
    int j;
    int k;
    int l;

    if (n < 1)
    {
        n = 1;
    }
    /* L2. [Find j.] (N.B. reduce indices by 1 for C arrays.) */
    for (j = n - 1; j > 0 && a[j - 1] >= a[j]; j--)
        ;
    if (j == 0)
        return 0;
    /* L3. [Increase a_j.] (N.B. reduce indices by 1 for C arrays.) */
    for (l = n; a[j - 1] >= a[l - 1]; l--)
        ;
    swap(&a[j - 1], &a[l - 1]);
    /* L4. [Reverse a_(j+1) ... a_n.] (N.B. reduce indices by 1 for C arrays.) */
    for (k = j + 1, l = n; k < l; k++, l--)
    {
        swap(&a[k - 1], &a[l - 1]);
    }
    return 1;
}

int main(void)
{
    char input[10] = "";
    int len;

    if (fgets(input, 10, stdin) && input[0] != '\n')
    {
        len = strlen(input);
        /* Limit length. */
        if (len > 8)
        {
            len = 8;
        }
        /* Remove newline. */
        if (input[len - 1] == '\n')
        {
            len--;
        }
        input[len] = '\0';
        /* Initially sort in ascending order. */
        quicksort(input, len);
        /* Print number of permutations. */
        printf("%u\n", count_permutations(input, len));
        /* Use Knuth's 算法rithm L (Lexicographic permutation algorithm). */
        do
        {
            /* L1. [Visit.] */
            puts(input);
        }
        while (permute(input, len)); /* Steps L2. to L4. */
    }
    return 0;
}

C++相关问答推荐

有效地计算由一组点构成的等边三角形和等腰三角形的数量

exit(EXIT_FAILURE):Tcl C API类似功能

为什么在此程序中必须使用Volatile关键字?

C语言编译阶段与翻译阶段的关系

C中的指针增量和减量(*--*++p)

使用双指针动态分配和初始化2D数组

FRIDA-服务器成为端口扫描的目标?

关于scanf()和空格的问题

无法访问共享目标文件内的共享指针

Wcstok导致分段故障

C:如何将此代码转换为与数组一起使用?

C";中的ANN运行时判断失败#2-变量outputLayer;周围的堆栈已损坏.运行后出错

C中的回文数字

用C++高效解析HTTP请求的方法

隐藏测试用例无法在c程序中计算位数.

*S=0;正在优化中.可能是GCC 13号虫?或者是一些不明确的行为?

Linux/C:带有子进程的进程在添加waitid后都挂起

GDB 用内容初始化数组

为什么需要struct in_addr

我该如何处理这个 C 90 代码中的内存泄漏?