【问题标题】:Why am i getting output for permutations of a string of length only 3?为什么我得到一个长度仅为 3 的字符串排列的输出?
【发布时间】:2025-12-20 13:30:07
【问题描述】:

打印排列 - 字符串

给定一个字符串,查找并打印输入字符串的所有可能排列。 注意:排列的顺序并不重要。只需将它们打印在不同的行中即可。

示例输入:

abc

样本输出:

abc acb bac bca cab cba

#include <iostream>
#include <string>
using namespace std;

void printCurrentString(string input, string result, int count[], int level)
{
    if (level == input.size())
    {
        cout << result << endl;
        return;
    }
    else
    {
        for (int i = 0; i < input.size(); i++)
        {
            if (count[i] == 0)
                continue;
            else
            {
                result[level] = input[i];
                count[i]--;
                printCurrentString(input, result, count, level + 1);
                count[i]++;
            }
        }
    }
}

void printPermutations(string input)
{
    char *result = new char[input.size()];
    int *count = new int[input.size()];
    for (int i = 0; i < input.size(); i++)
        count[i] = 1;
    printCurrentString(input, result, count, 0);
}

int main()
{
    string input;
    cin >> input;
    printPermutations(input);
    return 0;
}

【问题讨论】:

  • 您的代码导致未定义的行为。您对printCurrentString 的调用会为result 参数创建一个std::string 对象,但此构造是使用printPermutations 中的C 样式空终止字节字符串result 创建的。问题是在printPermutations 中,以null 结尾的字节字符串result 不是 以null 结尾的。您分配的内存将具有 indeterminate 值,并且以任何方式使用它(例如初始化 std::string 对象)都会导致未定义的行为。
  • 那我该如何解决呢?
  • 一种方法:将result 增大一个字符并将\0 放在最后一个位置。此外,您的帖子似乎没有提及您为什么写它。你有什么问题?
  • 它只适用于我输入大小为 3(abc) 的字符串,但当我输入其他大小如 2(ab) 或 4(abcd) 时它会失败。
  • C++ 标准库具有可用于循环遍历容器元素的所有排列的工具。 std::string 就是这样一个容器。根本不需要动态创建数组 - 可以通过设置单个容器来获取所有排列,然后遍历其元素的所有排列,

标签: c++ arrays recursion data-structures permutation


【解决方案1】:

两大问题,都导致undefined behavior

首先来自printPermutations函数:

char *result = new char[input.size()];

正如我在评论中提到的,这将分配内存但不会以任何方式对其进行初始化。从此内存中创建std::string 是导致 UB(未定义行为)的原因之一。

第二个在printCurrentString 函数中,你有

result[level] = input[i];

由于您不知道result 中字符串的实际大小,因此您不知道level 是否是有效索引。它可能超出范围。索引越界也会导致 UB。

您可以通过一个简单的更改来解决这两个问题:在printPermutations 函数中,不要像您那样动态地创建结果字符串。而是创建一个正确长度的正确 std::string 对象并传递它:

printCurrentString(input, string(input.length()), count, 0);

考虑到你有内存泄漏(你没有delete[] 内存你new[])我还建议你使用std::vector&lt;int&gt;count,并且你通过引用传递这个向量。

【讨论】:

最近更新 更多