Java 中的高级数组排序/重新排列

发布于 2024-12-11 00:50:35 字数 2585 浏览 0 评论 0原文

因此,我有一个具有以下理论值的数组:

int[] elements = {A1, A2, B1, B2,
                  A3, A4, B3, B4,
                  C1, C2, D1, D2,
                  C3, C4, D3, D4};

说明图:

                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | C | C | D | D |
                  + - + - + - + - +
                  | C | C | D | D |
                  + - + - + - + - +

简单地说,我希望将数组重新排列为以下形式:

int[] elements = {A1, A2, A3, A4,
                  B1, B2, B3, B4,
                  C1, C2, C3, C4,
                  D1, D2, D3, D4};

说明图:

                  + - + - + - + - +
                  | A | A | A | A |
                  + - + - + - + - +
                  | B | B | B | B |
                  + - + - + - + - +
                  | C | C | C | C |
                  + - + - + - + - +
                  | D | D | D | D |
                  + - + - + - + - +

这个特定示例包含四个扇区(A、B、C 和 D),但是我需要的算法应该可以工作,无论数组包含多少个扇区,以及每个扇区包含多少个元素。

每个扇区的大小(扇区宽度和扇区高度)以及扇区数量(行和列)已知。 所有扇区的大小完全相同(宽度和高度)。扇区的数量必须描述为两个值(行和列),然后将其相乘以构成扇区的实际总和。例如。如果需要5个扇区,则可以指定1行5列。

下面是执行这种类型的方法的示例:

public int[] sectorSort(int[] elements,
                        int sectorWidth,
                        int sectorHeight,
                        int columns,
                        int rows);

其他扇区设置的示例:

                  Columns: 5
                  + - + - + - + - + - + - + - + - + - + - +
                  | A | A | B | B | C | C | D | D | E | E |
     Rows: 1      + - + - + - + - + - + - + - + - + - + - +
                  | A | A | B | B | C | C | D | D | E | E |
                  + - + - + - + - + - + - + - + - + - + - +

                  Columns: 2
                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | C | C | D | D |
     Rows: 3      + - + - + - + - +
                  | C | C | D | D |
                  + - + - + - + - +
                  | E | E | F | F |
                  + - + - + - + - +
                  | E | E | F | F |
                  + - + - + - + - +

我计划使用它为我正在制作的游戏引擎制作一个高效的精灵地图类。数组中的元素是 ARGB 颜色值,扇区是单独的精灵。如果不同的精灵按后一个顺序排列,那么搜索单个精灵会更快并且内存效率更高。

谢谢你!

编辑1:清晰度。

EDIT2:添加了更多条件和说明。

So I have an array with the following theoretical values:

int[] elements = {A1, A2, B1, B2,
                  A3, A4, B3, B4,
                  C1, C2, D1, D2,
                  C3, C4, D3, D4};

Illustrative figure:

                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | C | C | D | D |
                  + - + - + - + - +
                  | C | C | D | D |
                  + - + - + - + - +

Simply put I would like the array to be re-arranged to the following form:

int[] elements = {A1, A2, A3, A4,
                  B1, B2, B3, B4,
                  C1, C2, C3, C4,
                  D1, D2, D3, D4};

Illustrative figure:

                  + - + - + - + - +
                  | A | A | A | A |
                  + - + - + - + - +
                  | B | B | B | B |
                  + - + - + - + - +
                  | C | C | C | C |
                  + - + - + - + - +
                  | D | D | D | D |
                  + - + - + - + - +

This particular example contains four sectors (A, B, C and D), but the algorithm I need should work however many or few sectors the array contains, and however many elements each sector contains.

The size of each sector is known (sector width and sector height) and also the amount of sectors (rows and columns). All sectors are of the exact same size (width and height). The amount of sectors has to be described as two values (rows ans columns) which is then multiplied to make up the actual sum of sectors. Eg. if 5 sectors are wanted, then 1 row and 5 columns could be specified.

Here follows an example of what a method preforming this sort could look like:

public int[] sectorSort(int[] elements,
                        int sectorWidth,
                        int sectorHeight,
                        int columns,
                        int rows);

Example of other sector setups:

                  Columns: 5
                  + - + - + - + - + - + - + - + - + - + - +
                  | A | A | B | B | C | C | D | D | E | E |
     Rows: 1      + - + - + - + - + - + - + - + - + - + - +
                  | A | A | B | B | C | C | D | D | E | E |
                  + - + - + - + - + - + - + - + - + - + - +

                  Columns: 2
                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | A | A | B | B |
                  + - + - + - + - +
                  | C | C | D | D |
     Rows: 3      + - + - + - + - +
                  | C | C | D | D |
                  + - + - + - + - +
                  | E | E | F | F |
                  + - + - + - + - +
                  | E | E | F | F |
                  + - + - + - + - +

I plan on using this to make an efficient sprite map class for a game engine I'm making. The elements in the array are ARGB color values, and the sectors are individual sprites. If the different sprites are arranged in the latter order then searching for individual sprites goes a lot faster and memory efficient.

Thank you!

EDIT1: Clarity.

EDIT2: Added more conditions and clarifications.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

So尛奶瓶 2024-12-18 00:50:35

你不会得到比这更好的时间复杂度:
它创建一个新数组并将每个扇区复制到其中。

static T[] sectorSort<T>(T[] elements, int sectorWidth, int sectorHeight, int columns, int rows)
        {
            T[] sortedElements = new T[elements.Length];
            int n = 0;
            int arrWidth = sectorWidth * columns;
            for(int secY = 0; secY < rows; secY++)
                for (int secX = 0; secX < columns; secX++)
                {
                    int baseIndex = secY * arrWidth * sectorHeight + secX * sectorWidth;
                    for(int y = 0; y < sectorHeight; y++)
                        for (int x = 0; x < sectorWidth; x++)
                        {
                            int sourceIndex = baseIndex + y * arrWidth + x;
                            sortedElements[n++] = elements[sourceIndex];
                        }
                }
            return sortedElements;
        }

我仍然可以看到很多可以完成的优化,但是阅读你的问题我发现这是在加载时间完成的,所以不要对此大惊小怪。

编辑:固定代码

编辑2:测试设置(C#)

    int[] array = new int[]
    {
        11, 12, 13, 21, 22, 23, 51, 52, 53,
        14, 15, 16, 24, 25, 26, 54, 55, 56,
        17, 18, 19, 27, 28, 29, 57, 58, 59,
        31, 32, 33, 41, 42, 43, 61, 62, 63,
        34, 35, 36, 44, 45, 46, 64, 65, 66,
        37, 38, 39, 47, 48, 49, 67, 68, 69,
        71, 72, 73, 81, 82, 83, 91, 92, 93,
        74, 75, 76, 84, 85, 86, 94, 95, 96,
        77, 78, 79, 87, 88, 89, 97, 98, 99,
    };
    int[] sorted = sectorSort(array, 3, 3, 3, 3);
    for (int y = 0; y < 9; y++)
    {
        for (int x = 0; x < 9; x++)
            Console.Write(sorted[x + y * 9] + " | ");
        Console.WriteLine("\n");
    }

You're not going to get a better time complexity than this:
It creates a new array and copies each sector into it.

static T[] sectorSort<T>(T[] elements, int sectorWidth, int sectorHeight, int columns, int rows)
        {
            T[] sortedElements = new T[elements.Length];
            int n = 0;
            int arrWidth = sectorWidth * columns;
            for(int secY = 0; secY < rows; secY++)
                for (int secX = 0; secX < columns; secX++)
                {
                    int baseIndex = secY * arrWidth * sectorHeight + secX * sectorWidth;
                    for(int y = 0; y < sectorHeight; y++)
                        for (int x = 0; x < sectorWidth; x++)
                        {
                            int sourceIndex = baseIndex + y * arrWidth + x;
                            sortedElements[n++] = elements[sourceIndex];
                        }
                }
            return sortedElements;
        }

I can still see a lot of optimizations that can be done, however reading your question I see this is done in loading time so don't fuss too much about it.

EDIT: Fixed code

EDIT2: Test setup (C#)

    int[] array = new int[]
    {
        11, 12, 13, 21, 22, 23, 51, 52, 53,
        14, 15, 16, 24, 25, 26, 54, 55, 56,
        17, 18, 19, 27, 28, 29, 57, 58, 59,
        31, 32, 33, 41, 42, 43, 61, 62, 63,
        34, 35, 36, 44, 45, 46, 64, 65, 66,
        37, 38, 39, 47, 48, 49, 67, 68, 69,
        71, 72, 73, 81, 82, 83, 91, 92, 93,
        74, 75, 76, 84, 85, 86, 94, 95, 96,
        77, 78, 79, 87, 88, 89, 97, 98, 99,
    };
    int[] sorted = sectorSort(array, 3, 3, 3, 3);
    for (int y = 0; y < 9; y++)
    {
        for (int x = 0; x < 9; x++)
            Console.Write(sorted[x + y * 9] + " | ");
        Console.WriteLine("\n");
    }
焚却相思 2024-12-18 00:50:35

您可以采用直接的算法迭代所有扇区和其中的所有元素来重新排列它们。这将是 O(n*m),n=扇区数,m=每个扇区的元素数。但你必须重新排列整个数组。作为替代方案(如果内存很关键),您可以创建原始数组的基于扇区的视图,这将花费 O(n) 来创建视图,然后花费 O(m) 来读取单个扇区的值。

因此,在这两种情况下读取所有扇区都需要 O(n*m)。您期望有什么改进?

You could take a straight forward algorithm iterating all sectors and all elements therein to rearrange them. This would be O(n*m), n=number of sectors and m = number of elements per sector. But you would have to rearrange the whole array. As an alternative (if memory is critical) you could create a sector based view of the original array this would take O(n) for creating the view and then O(m) to read the values of a single sector.

So reading all sectors would require O(n*m) in both cases. What improvement do you expect?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文