你如何遍历不同数量的数组中元素的排列?遍历、排列、组中、元素

2023-09-11 02:32:32 作者:此人须珍藏

编辑:我的溶液加入到这个问题的结束。谢谢你的提示。

我只是去用一个例子。假设我有长度的数组 N

  ARR = {1,4,8,2,5,...}
 

如果我想遍历的两个元素的所有排列我会写:

 的for(int i = 0;我n种;我++){
    为(诠释J = 0; J&n种; J ++){
        //做些事情改编[i]和改编[J]。
    }
}
 

我如果我要穿越三个元素的所有排列我只想补充的另一层为迭代:

 的for(int i = 0;我n种;我++){
    为(诠释J = 0; J&n种; J ++){
        为(中间体K = 0; K&n种; k ++){
            //做些事情改编[i]和改编[J]。
        }
    }
}
 
那个 只出现一次的数 ,是怎么找到的

如果元素的数量由用户给出(比如 v ),而我们不知道它到底是什么?我应该怎么写呢?

(我想不出最好的标题为这个问题,而且标签是不准确的任何。帮我这些也一样,如果你想要的。)

答案 解决的办法是这样的功能:

 无效forPermutation(INT深度,为int *数组,INT的长度,为int *指数,诠释CURDEPTH){
    如果(CURDEPTH == 0){
        的for(int i = 0; I<深度;我++){
            的printf(%D,指数[I]);
        }
        的printf(\ N);
        返回;
    }

    的for(int i = 0; I<长度;我++){
        指数[CURDEPTH  -  1] =我;
        forPermutation(深度,数组,长度,指数,CURDEPTH  -  1);
    }
}
 

上面的函数的用法如下:

  INT一个[] = {9,8,7,6,5,4,3,2,1};
INT permutationSize = 3;
INT *指数=新INT [permutationSize]
forPermutation(permutationSize,一,9,指数,permutationSize);
 

,控制台在显示阵列中的元件的给定大小的所有排列:

  0 0 0
1 0 0
2 0 0
3 0 0
4 0 0
...
5 8 8
6 8 8
7 8 8
8 8 8
 

解决方案

您可以简单地使用递归。

有些伪code:

无效someFunction(INT []改编,整数N,INT深度) {   如果(深度== 0)   {     //做一些与存储的元素     返回;   }   的for(int i = 0;我n种;我++)   {     //商店改编[I]     someFunction(ARR,正,深度-1);   } }

有几种方法来存储改编[I] 。一种方式是通过尺寸 initialDepth 阵列通过递归调用了下来,连同该数组的当前索引。我们加大对每一个递归调用索引,并把改编[I] 当前索引。然后,当深入== 0 if语句触发,我们将有一个包含一个排列,这是我们可以做一个数组什么用。

此,作为你的code,将重复的元素(即,一个置换将独家的第一要素包括重复几次)。如果要避免此情况,而是可以交换彼此元件的第一元件在所述第一步骤,然后递归,彼此元件在第二步骤交换第二元件,等等。

无效someFunction(INT []改编,整数N,INT POS,INT深度) {   如果(POS ==深度)   {     //做一些与改编的元素从0到POS     返回;   }   的for(int i = POS;我n种;我++)   {     //交换ARR [POS]和改编[I]     someFunction(ARR,N,POS + 1,深度);     //交换ARR [POS]和改编[I]回   } }

通话与 someFunction(inputArray,N,O,desiredDepth)

EDIT: My solution is added to the end of the question. Thanks for the hint.

I'll just go with an example. Suppose I have an array with length n:

arr = { 1, 4, 8, 2, 5, ... }

If I want to traverse all permutations of TWO elements I would write:

for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        // do something with arr[i] and arr[j]
    }
}

I If I want to traverse all permutations of THREE elements I would simply add another layer of for iteration:

for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        for (int k = 0; k < n; k++) {
            // do something with arr[i] and arr[j]
        }
    }
}

What if the number of elements is given by user (say v), and we don't know exactly what it is? What should I write then?

(I couldn't figure out the best title for this question. And the tags are not accurate either. Help me with these too, if you want.)

Answer The solution is this function:

void forPermutation(int depth, int* array, int length, int* indices, int curDepth) {
    if (curDepth == 0) {
        for (int i = 0; i < depth; i++) {
            printf("%d ", indices[i]);
        }
        printf("\n");
        return;
    }

    for (int i = 0; i < length; i++) {
        indices[curDepth - 1] = i;
        forPermutation(depth, array, length, indices, curDepth - 1);
    }
}

The usage of the function above is shown below:

int a[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int permutationSize = 3;
int* indices = new int[permutationSize];
forPermutation(permutationSize, a, 9, indices, permutationSize);

The console will show all permutations of the given size of the elements in the array:

0 0 0 
1 0 0 
2 0 0 
3 0 0 
4 0 0 
...
5 8 8 
6 8 8 
7 8 8 
8 8 8 

解决方案

You can simply use recursion.

Some pseudo-code:

void someFunction(int[] arr, int n, int depth)
{
  if (depth == 0)
  {
    // do something with the stored elements
    return;
  }

  for (int i = 0; i < n; i++)
  {
    // store arr[i]
    someFunction(arr, n, depth-1);
  }
}

There are a few ways to store arr[i]. One way could be to pass an array of size initialDepth down via the recursive call, along with the current index in that array. We increase the index on every recursive call, and put arr[i] at the current index. Then, when the depth == 0 if-statement triggers, we'll have an array containing a permutation, which we could do whatever with.

This, as your code, would repeat elements (i.e. one permutation will consist exclusively of the first element repeated a few times). If you wish to avoid this, you can instead swap the first element with each other element at the first step, then recurse, swapping the second element with each other element at the second step, and so on.

void someFunction(int[] arr, int n, int pos, int depth)
{
  if (pos == depth)
  {
    // do something with the elements in arr from 0 to pos
    return;
  }

  for (int i = pos; i < n; i++)
  {
    // swap arr[pos] and arr[i]
    someFunction(arr, n, pos+1, depth);
    // swap arr[pos] and arr[i] back
  }
}

Call with someFunction(inputArray, n, 0, desiredDepth).