c++ 我试图用字符数组解决完全置换问题,结果“超出了输出限制”,我用字符串成功了

cnwbcb6i  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(92)

描述

你要写一个程序,从一组给定的字母中生成所有可能的单词。例如:给定单词“abc”,你的程序应该-通过探索三个字母的所有不同组合-输出单词“abc”,“acb”,“bac”,“bca”,“cab”和“cba”。在从输入文件中取出的单词中,一些字母可能会出现不止一次。对于给定的单词,你的程序不应该多次产生相同的单词,并且单词应当以字母升序输出。

输入

输入由几个单词组成。第一行包含一个数字,表示后面的单词数。接下来的每一行包含一个单词。一个单词由从A到Z的大写或小写字母组成。大写字母和小写字母被认为是不同的。每个单词的长度小于13。

输出

对于输入中的每个单词,输出应该包含可以由给定单词的字母生成的所有不同单词。从同一输入单词生成的单词应该按字母升序输出。大写字母在相应的小写字母之前。

下面是使用字符数组得到“output limit exceeded”的代码

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
bool cmp(char a, char b)
{
    double aa = a;
    double bb = b;
    double d = 'a' - 'A' - 0.5;
    if (aa >= 'a')
    {
        aa = a - d;
    }
    if (bb >= 'a')
    {
        bb = b - d;
    }
    return aa < bb;
}
void swap(char *s, int a, int b)
{
    int t = s[a];
    s[a] = s[b];
    s[b] = t;
}
void permutation(char *s, int m, int n)
{
    if (m == n)
    {
        printf("%s\n", s);
    }
    else
    {
        char t[100];
        for (int i = m; i < n + 1; i++)
        {
            if (i == m)
            {
                for (int j = 0; j < n + 1; j++)
                {
                    t[j] = s[j];
                }
            }
//prevent dumplication
            if (i != m && s[i] == s[m])
            {
                continue;
            }

            swap(s, i, m);
            permutation(s, m + 1, n);
            if (i == n)
            {
                for (int j = 0; j < n + 1; j++)
                {
                    s[j] = t[j];
                }
            }
        }
    }
}
int main(int argc, char const *argv[])
{
    int n;
    cin >> n;
    while (n--)
    {
        char s[100];
        cin >> s;
        int lenth = strlen(s);
        sort(s, s + lenth, cmp);
        permutation(s, 0, lenth - 1);
    }

    return 0;
}

下面是使用string并被接受的代码

#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
void swap(string &s, int a, int b)
{
    char t = s[a];
    s[a] = s[b];
    s[b] = t;
}
bool cmp(char a, char b)
{
    double aa = a;
    double bb = b;
    double d = 'a' - 'A' - 0.5;
    if (aa >= 'a')
    {
        aa = a - d;
    }
    if (bb >= 'a')
    {
        bb = b - d;
    }
    return aa < bb;
}
void permutation(string s, int m, int n)
{
    if (m == n)
    {
        cout << s;
        cout << endl;
    }
    else
    {
        for (int i = m; i <= n; i++)
        {
            if (i != m && s[i] == s[m])
            {
                continue;
            }
            swap(s, i, m);
            permutation(s, m + 1, n);
        }
    }
}
int main(int argc, char const *argv[])
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        string str;
        cin >> str;
        sort(str.begin(), str.end(), cmp);
        permutation(str, 0, str.size() - 1);
    }
    return 0;
}

我试着用字符数组传递的字符串来给予一个输出,或者用字符串得到一个输入,然后传递到字符数组,但是都得到了“超出输出限制”。然后我想可能是字符数组的大小太小了(虽然问题说一个单词小于13),所以我用10000的大小声明数组,然后我得到了错误的答案。
我只是想用字符数组来解决这个问题。

rqqzpn5f

rqqzpn5f1#

感谢@n.m..是他指出了我的错误。我发现在函数置换的循环中,如果i==n和i!=m和s[i]==s[m],循环将直接终止,不会使字符数组“s”回到最初进入循环时的条件。下面是接受的答案。

#include <iostream>
    #include <algorithm>
    #include <string>
    #include <cstring>
    using namespace std;
    bool cmp(char a, char b)
    {
        double aa = a;
        double bb = b;
        double d = 'a' - 'A' - 0.5;
        if (aa >= 'a')
        {
            aa = a - d;
        }
        if (bb >= 'a')
        {
            bb = b - d;
        }
        return aa < bb;
    }
    void swap(char *s, int a, int b)
    {
        int t = s[a];
        s[a] = s[b];
        s[b] = t;
    }
    void mycopy(char *a, char *b, int size)
    {
        for (int j = 0; j < size; j++)
        {
            a[j] = b[j];
        }
    }
    void permutation(char *s, int m, int n)
    {
        if (m == n)
        {
            printf("%s\n", s);
        }
        else
        {
            char t[100];
            for (int i = m; i < n + 1; i++)
            {
                if (i == m)
                {
                    mycopy(t, s, n + 1);
                }
                if (i == n && i != m && s[i] == s[m])
                {
                    mycopy(s, t, n + 1);
                    continue;
                }
                if (i != m && s[i] == s[m])
                {
                    continue;
                }
                swap(s, i, m);
                permutation(s, m + 1, n);
                if (i == n)
                {
                    mycopy(s, t, n + 1);
                }
            }
        }
    }
    int main(int argc, char const *argv[])
    {
        int n;
        cin >> n;
        while (n--)
        {
            char s[100];
            cin >> s;
            int lenth = strlen(s);
            sort(s, s + lenth, cmp);
            permutation(s, 0, lenth - 1);
        }
    
        return 0;
    }

这告诉我们,当我们使用continue和类似的东西(如break)时,我们应该小心。

相关问题