将数组拆分为4个部分

时间:2015-06-14 12:57:02

标签: java split

我必须创建一个方法,将作为输入的整数数组划分为以这种方式生成的数组:

  • 第一部分由除以4的元素组成,产生静止0
  • 第二部分由除以4的元素组成,给予休息1
  • 第三部分由除以4的元素组成,给出余数2
  • 第四部分由元素组成,除以4,得到休息3

例如,以下数组:

[0,2,4,5,6,8,7,9,10,12,14,15,17,20,1]

必须在这里成为:

[0,4,8,12,20,5,9,17,1,2,6,10,14,7,15]

我得到的结果是:

[0,4,5,8,6,2,7,9,10,12,14,15,17,20,1]

在子序列中,无论项目的顺序如何,只需在子序列中正确。

我写了这个方法但是没有正常工作,有些项目不合适。

public static void separate4Colors(int[] a) {
    int i = 0;
    int j = 0;
    int k = 0;
    int h = a.length - 1;
    while(k <= h) {
        if(a[k] % 4 == 0) {
            swap(a, k, i);
            k++;
            i++;
            j++;
        }
        else if(a[k] % 4 == 1) {
            swap(a, k, i);
            k++;
            i++;
        }
        else if(a[k] % 4 == 2) {
            k++;
        }
        else {
            while(h > k && a[k] % 4 == 3)
                h--;
            swap(a, k, h);
            h--;
        }
    }
}

private static void swap(int[] a, int x, int y) {
    int temp = a[x];
    a[x] = a[y];
    a[y] = temp;
}

有人可以帮我解决吗?

我已经完成的类似练习,其工作是将数组分为3部分而不是4部分:

public static void separate3Colors(int[] a) {
    int j = 0;
    int k = a.length - 1;
    int i = 0;
    while(j <= k) {
        if(a[j] % 3 == 0) { 
            swap(a, j, i); 
            j++;
            i++;
        }
        else if(a[j] % 3 == 1) {
            j++;
        }
        else { 
            swap(a, j, k);
            k--;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您可以通过使用比较数字模数4的比较器对数组进行排序,从而在一行中完成。不幸的是,它需要一组Integer个对象。

另一种方法是将结果写入不同的数组。您可以遍历数组一次以确定每个余数的值将开始的索引,然后再次遍历数组以生成有序副本:

int[] index = new int[4];
for(int n : a) {
    int r = n % 4;
    if (r != 3) {
        index[r+1]++;
    }
}
index[2] += index[1];
index[3] += index[2];
// At this point each index[k] has the position where elements
// with remainder of k will start
int[] res = new int[a.length];
for(int n : a) {
    res[index[n%4]++] = n;
}

这会将重新排序的数组放入res变量。

Demo.

答案 1 :(得分:0)

这个练习显然是已故E. Dijkstra https://en.wikipedia.org/wiki/Dutch_national_flag_problem着名的荷兰国旗问题的变种。 并且可以应用相同的分辨率技术(当然,成功)。

考虑到,在运行算法的某个时刻,阵列有五个部分。一部分包含你知道的余数为0的数字,一部分用于余数1,等等。还有一部分用于未分类的数字。算法的每一步都包含

  • 查看第一个未分类的号码
  • 在边框处交换一些数字,使数字落在右边。

所以&#34;未分类&#34;区域缩小一个单位。

有时候一张照片有帮助(去图)。我选择在1&2和2之间有未分类的元素。

 000000000111111uuuuuuu22222333333333
                ?

如果被测号码的剩余部分为1,请将其留在那里。如果为零,则将其与第一个&#34; 1&#34;交换。等

当然,在开始时,情况被描述为

 uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
 ?