【问题标题】:Generate all possible permutations in C在 C 中生成所有可能的排列
【发布时间】:2016-09-09 18:55:11
【问题描述】:

我正在尝试开发一个代码来解决 C 中的旅行推销员问题,但我有一些限制:我只能使用“for”、“while”、“do”、数组、矩阵和类似的简单事物,所以,没有函数或递归(不幸的是)。

到目前为止我得到了什么:

用户将像这样输入城市坐标 X 和 Y:

8.15    1.58
9.06    9.71
1.27    9.57
9.13    4.85

存储坐标的代码。

float city[4][2];
int i;

for (i=0; i<4; i++)
    scanf("%f %f", &cidade[i][0], &cidade[i][1]);

有 4 个城市,所以“i”从 0 到 3。X 和 Y 存储在矩阵的第二维,[0] 和 [1]。

现在的问题是我必须生成矩阵第一维的所有可能的排列。只有 4 个城市似乎很容易,因为所有可能的路线都是(每次都必须从城市 A 开始):

A B C D
A B D C
A C B D
A C D B
A D C B
A D B C

但我必须将其扩展到 10 个城市。人们告诉我它将使用 9 个嵌套的 foo 循环,但我无法开发它 =(

谁能给我一个想法?

【问题讨论】:

  • “没有功能”?这是一个非常愚蠢的约束。通过蛮力解决旅行商问题也是如此。
  • 如何为 10 个城市生成所有 1-long 组合?一个刚刚生成所有城市的 for 循环。现在,对于 2 长的城市,它是一个循环超过 10 个城市以获得第一个,对于每个“第一个”城市,一个循环超过其他城市以获得组合的第二个。对于 3 长,它是 10 个城市中的每一个,然后是其他城市的 2 长组合......等等,最多 10 个
  • @EugeneSh,这是一项任务。重点在于编写 C,而不是有效地解决旅行商问题。
  • @TheArchetypalPaul 编写没有函数的 C?那个怎么样?有时我只是想知道学校里的这些人想教什么。
  • @Shofukan 他应该尝试完全相反的教导。无论如何,完成你的课程并远离这个人。并尽量不要遵循他的指导方针......

标签: c algorithm permutation


【解决方案1】:

扩展至 10(并查找城市名称)作为读者练习。这很可怕,但这就是你教授的局限性所得到的结果

#include <stdio.h>

int main(void) {
    for (int one = 0; one < 4; one++) {
        for (int two = 0; two < 4; two++) {
            if (two != one) {
                for (int three = 0; three < 4; three++) {
                    if (one != three && two != three) {
                        for (int four = 0; four < 4; four++)
                            if (one != four && two != four && three != four) {
                                printf("%d %d %d %d\n", one, two, three, four);
                            }
                    }
                }
            }
        }
    }
    return 0;

}

【讨论】:

  • 我很确定作业会说“main 的主体中没有函数”,或者其他什么,否则这将是一个无法回答的作业!
  • 而且,是的,printf 是一个函数,但真正的答案不需要printf。虽然我很想知道它会如何显示结果!
  • 好吧,好吧,太可怕了。我会选择“令人毛骨悚然”。
  • "(informal)= 不愉快、可怕、可怕、冒犯、讨厌、恶心、可怕、可怕、淫秽、不愉快、恶心" (collinsdictionary.com/dictionary/english-thesaurus/horrid)。是的,所有这些都适用。
  • 我想我表达错了。我可以使用 printf、scanf 等。但我不允许创建新的“int main(SOMETHING_HERE)”。顺便说一句,我是初学者,我什至不知道该怎么做,而且我还很难用外语谈论一个我还不熟悉的话题,呵呵。
【解决方案2】:

这是基于https://stackoverflow.com/a/3928241/5264491

#include <stdio.h>

int main(void)
{
    enum { num_perm = 10 };
    int perm[num_perm];
    int i;

    for (i = 0; i < num_perm; i++) {
        perm[i] = i;
    }

    for (;;) {
        int j, k, l, tmp;

        for (i = 0; i < num_perm; i++) {
            printf("%d%c", perm[i],
                   (i == num_perm - 1 ? '\n' : ' '));
        }

        /*
         * Find largest j such that perm[j] < perm[j+1].
         * Break if no such j.
         */
        j = num_perm;
        for (i = 0; i < num_perm - 1; i++) {
            if (perm[i + 1] > perm[i]) {
                j = i;
            }
        }
        if (j == num_perm) {
            break;
        }

        for (i = j + 1; i < num_perm; i++) {
            if (perm[i] > perm[j]) {
                l = i;
            }
        }

        tmp = perm[j];
        perm[j] = perm[l];
        perm[l] = tmp;

        /* reverse j+1 to end */
        k = (num_perm - 1 - j) / 2; /* pairs to swap */
        for (i = 0; i < k; i++) {
            tmp = perm[j + 1 + i];
            perm[j + 1 + i] = perm[num_perm - 1 - i];
            perm[num_perm - 1 - i] = tmp;
        }
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多