Java 将列表顺序返回到旧索引

Java 将列表顺序返回到旧索引,java,list,Java,List,我有一个int数组来存储列表的旧索引,我用它来恢复列表中的数据顺序 int[] oldindex = function(); 数组的工作方式:index-n处的oldindex数组的值包含操作前index-n处的数据所在的索引位置 例如,oldindex[0]在索引0处包含当前数据的旧索引 我尝试过切换数据以恢复订单。例如,通过创建一个临时变量来存储索引n中的数据,然后将索引n中的数据替换为索引k中的数据,并将索引k中的数据替换为临时变量中的数据。我可能做错了,也可能没有,但恢复数据顺序不起作

我有一个int数组来存储列表的旧索引,我用它来恢复列表中的数据顺序

int[] oldindex = function();
数组的工作方式:index-n处的oldindex数组的值包含操作前index-n处的数据所在的索引位置

例如,oldindex[0]在索引0处包含当前数据的旧索引

我尝试过切换数据以恢复订单。例如,通过创建一个临时变量来存储索引n中的数据,然后将索引n中的数据替换为索引k中的数据,并将索引k中的数据替换为临时变量中的数据。我可能做错了,也可能没有,但恢复数据顺序不起作用

for(int i = 0; i < data.size();i++) {
  String temp = data.get(i);
  data.set(i, data.get(oldindex[i]));
  data.set(oldindex[i], temp);
}
for(int i=0;i
在返回数据之前,使用临时列表复制和重新排序数据确实有效,但对于大数据来说,这会占用太多内存


有没有更有效的替代方法呢?

您在某个位置“p”拾取一个元素,并将其放置在新的、正确的点旧索引[p]处。但是,您不想覆盖该位置上的元素,因此需要将其复制到临时变量中。现在您需要找到该元素的正确位置,oldindex[oldindex[p]]。将其存储在那里,但首先将该位置的元素保存到临时变量中。继续操作,找到元素的正确位置并保存元素,然后将其覆盖到临时变量中,直到返回到起始位置“p”。此时,您可以将临时变量存储到列表中的“p”位置,而不用担心覆盖它,因为您已经将该元素移动到了正确的位置。在这一点上,您已经实现了列表中所有元素的正确排序,这些元素从索引“p”开始形成一个完整的排列循环。现在,您需要获取未包含在该置换循环中的下一个元素,并从该元素开始构建一个新的置换循环,等等。但是,您需要跟踪哪些元素已经在正确的位置,哪些元素没有。所以,您仍然需要一个与列表O(n)的大小成比例的临时空间,它可以是布尔数组。但我仍然建议您不要担心引用所占用的空间。

您在某个位置“p”拾取一个元素,并将其放置在新的、正确的spot oldindex[p]处。但是,您不想覆盖该位置上的元素,因此需要将其复制到临时变量中。现在您需要找到该元素的正确位置,oldindex[oldindex[p]]。将其存储在那里,但首先将该位置的元素保存到临时变量中。继续操作,找到元素的正确位置并保存元素,然后将其覆盖到临时变量中,直到返回到起始位置“p”。此时,您可以将临时变量存储到列表中的“p”位置,而不用担心覆盖它,因为您已经将该元素移动到了正确的位置。在这一点上,您已经实现了列表中所有元素的正确排序,这些元素从索引“p”开始形成一个完整的排列循环。现在,您需要获取未包含在该置换循环中的下一个元素,并从该元素开始构建一个新的置换循环,等等。但是,您需要跟踪哪些元素已经在正确的位置,哪些元素没有。所以,您仍然需要一个与列表O(n)的大小成比例的临时空间,它可以是布尔数组。但我仍然建议不要担心引用占用的空间。

非常简单(幼稚)的实现:

    private static void order(String[] values, int[] old) {
        assert values.length == old.length;
        for (int i = 0; i < values.length; i++) {
            var nextv = values[old[i]];
            var nexti = old[old[i]];
            while (nexti != old[nexti]) {
                var tempv = values[nexti];
                var tempi = old[nexti];
                values[nexti] = nextv;
                old[nexti] = nexti;
                nextv = tempv;
                nexti = tempi;
            }
        }
    }
非常简单(幼稚)的实现:

    private static void order(String[] values, int[] old) {
        assert values.length == old.length;
        for (int i = 0; i < values.length; i++) {
            var nextv = values[old[i]];
            var nexti = old[old[i]];
            while (nexti != old[nexti]) {
                var tempv = values[nexti];
                var tempi = old[nexti];
                values[nexti] = nextv;
                old[nexti] = nexti;
                nextv = tempv;
                nexti = tempi;
            }
        }
    }

我在手机上很抱歉,请给我一点时间,让我将其粘贴为我笔记本电脑上的代码。在这里粘贴数据将不起作用(无法读取代码,基于文本)-除非您还调整保存的索引(如对索引进行排序,并以同样的方式更改值位置))我在手机上很抱歉给我一点时间,让我把它作为我笔记本电脑上的代码粘贴到这里。在这里粘贴数据不起作用(无法读取代码,基于文本)-除非你也调整保存的索引((像对索引排序一样,改变值位置))很抱歉,但是你介意添加一些工作示例代码吗?这可能需要我花费一些时间/天来理解和测试它,但如果您可以添加工作示例代码,不仅对我来说,而且对其他人来说,这将使理解更快、更容易。注意:如果元素位置已经纠正,旧索引列表可用于存储信息,如果该列表可以重复使用,对不起,您介意添加一些工作示例代码吗?这可能需要我花费一些时间/天来理解和测试它,但是如果您可以添加工作示例代码,不仅对我来说,而且对其他人来说,这将使理解更快、更容易。注意:如果元素位置已经纠正,如果该列表可以在测试代码“d”中重复使用,则可以使用旧索引列表来存储信息当前在数据[0]处,但以前在数据[1]处,如果我在问题中的字词有误并使您感到困惑,您可以随意将其编辑为我代码的结果<代码>[b,d,c,a,e]
-“d”位于其先前位置,
数据[1]
!那么,怎么了?啊,我的糟糕,对不起,我修复了我的测试代码,它工作了,我在旧索引中犯了一个错误,它现在工作了!感谢虽然答案在数组中,但我也可以对列表应用相同的解决方案。注意:
oldindex
array正在由此更改!是的,在测试代码中,“d”当前在数据[0]处,但以前在数据[1]处,如果我在问题中的单词上出错,并使您感到困惑,请随意编辑它,使其成为我代码的结果<代码>[b、d、c、a、e]-“d”处于其初始位置