【问题标题】:Sum of List<Integer> recursivelyList<Integer> 的总和递归
【发布时间】:2012-02-14 03:50:30
【问题描述】:

各位程序员大家好。

我遇到了一个非常愚蠢的问题。我应该递归地对列表中的所有整数求和。我知道有一种更简单的方法可以做到这一点,实际上我也做了这个方法(见下面的课程)。但是这个赋值的意思是我必须把列表分成两半,然后在两半上递归计算总和,最后我只返回 half1 + half2。

问题是高级方法不返回所有值的总和。谁能帮帮我?

方法 sum 是简单的方法。 Summer(丹麦语总结)是更高级的方法。

package opgave1;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class BinærSøgning {
    public static void main(String[] args) {
        Random random = new Random();
        int tal = 3;

        List<Integer> liste = new ArrayList<Integer>();
        for (int i = 0; i < 10; i++)
            liste.add(random.nextInt(10));
        Collections.sort(liste);

        System.out.println(liste);
        //      System.out.println(binærSøgning(liste, 0, tal));
        System.out.println(summer(liste, 0));
    }

    public static int binærSøgning(List<Integer> liste, int start, int find) {
        if (liste.size() > 0) {
            int midt = liste.size() / 2;
            if (liste.get(midt) == find)
                return start + midt;
            else if (liste.size() > 1) {
                if (find < liste.get(midt))
                    return binærSøgning(liste.subList(0, midt), start, find);
                else
                    return binærSøgning(liste.subList(midt + 1, liste.size()), start + midt + 1, find);
            }
        }
        return -1;
    }

    public static int sum (List<Integer> list, int i)
    {
        if (i == list.size())
            return 0;
        else
            return list.get(i) + sum(list, i+1);
    }


    public static int summer(List<Integer> list, int start){
        int right = 0;
        int left = 0;

        if(start == list.size()){
            return 0;
        } else {

            int mid = list.size() / 2;
            if(start < mid){
                left += list.get(start) + summer(list.subList(0, mid), start+1);
            } else if(mid < list.size()){
                right += list.get(mid) + summer(list.subList(mid+1, list.size()), mid+1);
            }
        }
        return right + left;
    }


}

【问题讨论】:

  • 您应该尝试使用调试器或简单的打印语句来缩小错误来源。
  • +1 用于方法名称中的有趣字符! (binærSøgning) 并了解丹麦语中的 binarySearch
  • 当列表的大小是 2 的幂(等 64)时,您是否有问题,我认为当您除以 2 时会丢失一些元素

标签: java list recursion


【解决方案1】:

使用两个基本情况会更容易,如果您使用子列表,则不需要额外的“开始”参数。 (因为是作业,我就不详细填写了。)

public static int summer(List<Integer> list) {
   //base 1
   if (list.size() == 0) {

   }
   //base 2
   else if (list.size() == 1) {

   }
   else
   {
      //no need for if statements now!
      int left = summer(list.sublist(/* */))
      int right = summer(list.sublist(/* */))
      return left + right;
   }
}

【讨论】:

  • @ThomasTeilmann - 不客气。感谢您接受我的回答!
【解决方案2】:

您确定必须拆分列表吗?通常,当你得到这个家庭作业任务时,意思是这样的:

public static int sum(List<Integer> l,int start) {
if (start==l.size()) return 0;
return l.get(start)+sum(l,start+1);
}

【讨论】:

  • 我想我提到我必须双向进行:)
【解决方案3】:

当您在递归中发送 start+1 时,您会丢失列表的元素。

     left += list.get(start) + summer(list.subList(0, mid), start+1);

你应该发送

      left += list.get(0) + summer(list.subList(1, mid), 0);

      right += list.get(mid) + summer(list.subList(mid+1, list.size()), 0);

我认为不需要发送任何起始值。每个递归都应该用 0 代替 start。

【讨论】:

  • 我会尝试一下并发布我的结果:)
  • 我的方法似乎还有更多错误,因为它仍然返回错误的答案。无论如何谢谢:)
【解决方案4】:

我认为可以通过跟踪范围的第一个和最后一个索引以更简单的方式解决它,如下所示:

public static int sum(List<Integer> list, int i, int j) {
    if (i == j)
        return list.get(i);
    int half = (i + j) / 2;
    return sum(list, i, half) + sum(list, half + 1, j);
}

它是这样称呼的:

List<Integer> list = Arrays.asList(1, 2, 3);
System.out.println(sum(list, 0, list.size()-1));

它适用于非空列表。如果列表为空,您需要在调用sum 之前检查它。

【讨论】:

  • 是的,我只是在方法中添加了一个 if 语句,用于检查列表是否为空。工作得很好。 :) 谢谢你
【解决方案5】:

首先,如果您只需要使用递归,则不需要将列表减半。列表元素的总和是其第一个元素的总和 + 列表其余所有元素的总和。

第二,你的方法太复杂了。如果列表为空,则列表的元素之和为 0,唯一元素是它包含 1 个元素,如果它包含超过 1,则应用到两个子列表的方法的结果之和。你不要需要任何开始参数。

这应该让你开始。

编辑:既然奥斯卡洛佩兹给了你答案,但我觉得它太复杂了,这是我的:

public static int sum(List<Integer> list) {
    if (list.isEmpty()) {
        return 0;
    }
    else if (list.size() == 1) {
        return list.get(0);
    }
    else {
        int half = list.size() / 2;
        return sum(list.subList(0, half)) + sum(list.subList(half, list.size()));
    }
}

【讨论】:

  • 是的,我知道这太复杂了。正如我所说,我必须以简单( Sum() )和这种愚蠢的方式来完成这项任务。 ( 夏天() )。我认为这是一项愚蠢的任务,但无论如何,我必须为学校做。
  • 我的意思是可以按照要求使用递归,但更简单。如果您考虑一下我的回答所说的内容,则开始参数是无用的。
  • 如果你看看我的 sum(List list, int i) 方法,这不是你在第一篇文章中的意思吗?
  • 是的。这部分很好。不过,summer 方法太复杂了。它不需要 start 参数。想一想:一个列表的总和是它的两半的总和。
【解决方案6】:

我想知道获得“一半”列表的原因。
问题的解决方案是唯一的一个:

public int sum_list(List<Integer> list) {
    if (list == null || list.isEmpty()) {
        return 0;
    }
    return list.remove(0) + sum_list(list);
}

【讨论】:

    【解决方案7】:
    import java.util.*;
    
    public class SumListByRecursion {
    
        public static int sumByRec(List<Integer> list) {
    
    
            int size = list.size();
            if(size > 0) {
                return list.get(0) + sumByRec(list.subList(1, size));           
            }
            return 0;
        }
    
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            List<Integer> list = new ArrayList<Integer>();
    
            list.add(1);
            list.add(2);
            list.add(3);
            list.add(4);
    
            System.out.println("List:"+" "+list);
    
            int sum = sumByRec(list);
            System.out.println("Sum of the list:"+" "+sum);
        }
    
    }
    

    【讨论】:

    • add对你的回答做一些解释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 2023-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多