【问题标题】:Convert a range of lists to sub list and store them in an list of type linkedlist将一系列列表转换为子列表并将它们存储在链表类型的列表中
【发布时间】:2015-10-17 03:00:15
【问题描述】:

我已经有一个包含值的列表类型 Integer,如果一个元素范围的总和满足特定值,我想从索引零开始顺序测试,然后将此范围复制到列表中并将其存储在链接列表中.然后再次按顺序测试,但现在从上一个范围的下一个索引开始,所以如果上一个范围是索引 0 到索引 9,那么从索引 10 开始,重复该过程直到最后一个索引。

List<Integer> arrayB = new LinkedList<Integer>(); //this is the array with values in it

List<LinkedList> p = new LinkedList<LinkedList>();// this is the array of arrays  

List<Integer> arrayA = new LinkedList<Integer>();// this is the range or the sub list of arrayB

public void function(int n)// suppose that n = 6 and arrayB have these value {1,2,3,1,1,1,1,2}
{
    int count = 0;

    for (int w : arrayB)
    {
        count = w + count;
        arrayA.add(w);
        if(count == n)
        {
            count = 0;
            p.add((LinkedList) arrayA);
            arrayA.clear();
        }
    }
}

但是,当我在 arrayA 中调用 clear 方法时,此代码会失败,因此无论使用何种数据结构,是否有任何替代代码可以使用此逻辑?

【问题讨论】:

  • 这是一个非常长的第一句话。你在“如果一个范围的总和......”失去了我们。
  • 你更早失去了我。关于何时开始调用 LinkedList 和数组数组。在 Java 中,数组具有与列表不同的类型。如果您将“列表”称为“数组”,反之亦然,结果将是我们找出“数组”是指 Java 数组还是 Java List
  • @ergonaut 我已经编辑了帖子,如果您看到代码,它是一个元素范围的总和,例如 arrayB 中的元素具有元素 {1,2,3,1,1,1 ,1,2} 所以前 3 个元素的总和是 6,满足条件(count == n),所以范围是索引 0 到索引 2。
  • @StephenC 我已经根据通用集合而不是数组编辑了这个问题,但是这个问题并不限制在任何替代代码中使用数组来回答
  • “元素范围”是什么意思?数学意义上的范围?子列表?还有什么?

标签: java arrays data-structures linked-list


【解决方案1】:

我对问题的理解如下: 存在一个数组,如果它们满足某些条件,您希望从中提取一定范围的值。在这种情况下,标准是范围评估为某个总和。完成此操作后,您希望重复该过程,直到原始数据结构中的所有值都用完为止。 我将假设您的原始数据结构是一个整数数组,并且您生成的数据结构是一个整数数组的链表。

一种方法可能是保留一个跟踪原始数组当前索引的全局计数器,如下所示:

int[] originalArray = {//list of numbers separated by commas};
LinkedList<Integer[]> resultingList = new LinkedList<>();
int currentIndex = 0;

public static void function(int totalSum) {
    int currentSum = 0;
    int initialIndex = currentIndex;
    while((currentSum != totalSum) && (currentIndex < (originalArray.length - 1))) {
        if(currentSum + initialArray[currentIndex] <= totalSum) {
            currentSum += initialArray[currentIndex];
            currentIndex++;
        } 
        else {
            break;
        }
    }
    if(currentSum = totalSum) {
        int[] arrayToAdd = new int[currentIndex - initialIndex - 1];
        for(int i = 0; i < currentIndex - initialIndex; i++) {
            arrayToAdd[i] = originalArray[initialIndex + i];
        }
        resultingList.add(arrayToAdd);
    }
}

【讨论】:

  • 实际上前面代码的问题是我删除了数组 p 的元素指向的 arrayA 对象的引用,所以解决方案只是再次初始化数组而不是调用方法 clear
  • 好的,你明白了!
【解决方案2】:

每次将子列表添加到 p 时,您都使用相同的列表引用 arrayA,p 中的每个列表元素都指向同一个 arrayA。所以当你调用 arrayA.clear();您清除 p 中的所有列表元素。

要纠正这个问题,您需要在向 arrayA 添加子列表时创建一个新的列表对象:

public static void function(int n)// suppose that n = 6 and arrayB have these value {1,2,3,1,1,1,1,2}
{
    int count = 0;

    LinkedList<Integer> subList = new LinkedList<>();
    for (int w : arrayB) {
        count = w + count;
        subList.add(w);
        if (count == n) {
            count = 0;
            p.add((LinkedList) subList); // p is adding a new list reference every time
            subList = new LinkedList<>(); // create a new list object, subList points to a new list object
        }
    }
}

【讨论】:

  • 这就是我希望它工作得很好的答案,我只需要更改一行代码谢谢。
【解决方案3】:

问题在于,当您将链表添加到最终存储 p 中时,您假设链表的元素已放入其中。只引用了一个指针,所以当你在下一行清除它时,所有元素都消失了。

p.add((LinkedList) arrayA);
arrayA.clear();

一个技巧是将arrayA 的作用域移到函数内部。这是因为它是临时的,并且只是一个子列表,所以它不应该在实例级别。它可以通过做一个重复使用

arrayA = new LinkedList<Integer>();

这样做时,您并没有丢失旧列表,因为 p 保留了对它的引用。

另一个提示是使用有意义的名称来命名您的列表。

originalIntList、groupedIntList、singleGroupIntList 帮助读者了解除了说明 Java 对象明显方面的注释之外,他们还能做什么。

【讨论】:

  • 是的,这是代码的问题,下次我会考虑为代码编写有意义的名称时,修复真的很简单
猜你喜欢
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
相关资源
最近更新 更多