【问题标题】:Recursion with for loop never stops. Can't find my mistake使用 for 循环的递归永远不会停止。找不到我的错误
【发布时间】:2016-03-03 17:03:50
【问题描述】:

我正在为 Android 创建一个音乐播放器,并且我正在尝试实现一个计时器功能,您可以在其中设置持续时间,并且该应用会为您提供具有此持续时间的播放列表。我认为用递归来做这件事会很好。这是我的代码:

变量:

maxLength = [any value in seconds] ... Wanted duration for the ArrayList with songs
currentLength = 0 ... current Duration of the ArrayList
timerSongs = new ArrayList<Song>() ... the ArrayList with the playlist
allSongs ... ArrayList with all the songs I have on my device

这是被调用以将项目添加到 timerSongs 的 void

private void addSongs(int index, long maxLength){

    if (currentLength<=maxLength){
        timerSongs.add(allSongs.get(index));

        currentLength = currentLength
            + TimeUnit.MILLISECONDS.toSeconds(allSongs.get(index).getDuration());

        for (int i = 0; i < allSongs.size() && currentLength != maxLength; i++){
            Log.e("Index", String.valueOf(i));
            addSongs(i, maxLength);
        }
    } else {
        currentLength = currentLength
            - TimeUnit.MILLISECONDS.toSeconds(timerSongs.get(timerSongs.size()-1).getDuration());
        timerSongs.remove(timerSongs.size()-1);
    }
}

编辑:我想做的是:

  1. 让应用将歌曲添加到arrayList(timerSongs),直到太长

  2. 删除过长的歌曲

  3. 如果持续时间 (currentLength) 太长,请添加下一首歌曲并重试。如果是,请再次删除它

  4. 为接下来的所有歌曲执行第 3 步

  5. 如果持续时间仍然不正确,请设置一首新的最前一首歌曲,然后再次执行上述步骤

    等等……

我找不到错误...但是Log.e("Index", String.valueOf(i)); 总是给我相同的值:0。一段时间后,应用程序由于堆栈溢出而崩溃。所以似乎递归永远不会停止。有人在我的代码中看到错误吗?有什么问题?

提前致谢

【问题讨论】:

  • 为什么你认为这对递归很有用?
  • 我不知道你想做什么,但这几乎可以肯定不是这样做的方式......但因为我不知道你想做什么我不能确实为您指明了更好的方式。
  • 因为程序首先必须添加歌曲,然后返回并尝试所有组合以获得想要的结果。但我为什么这么认为并不重要。我需要帮助找出我的错误..
  • 问题是for循环从i=0开始进入递归,然后for循环从i=0开始进入递归,然后for循环从i=0开始进入递归...看到问题了吗?
  • @cricket_007 但如果条件 (currentLength

标签: java android for-loop recursion


【解决方案1】:

好吧,虽然我个人认为您使用递归的解决方案非常糟糕,但您应该更改这一行

for (int i = 0; i < allSongs.size() && currentLength != maxLength; i++){

for (int i = 0; i < allSongs.size() && currentLength <= maxLength; i++){

【讨论】:

  • currentLength &lt;= maxLength 已在 if 语句中处理,因此只需 i &lt; allSongs.size() 即可
【解决方案2】:

for 循环永远不会“++”,因为它等待 addSongs 方法完成执行。当 for 循环以 i == 0 运行时,将执行相同的方法,一次又一次地创建一个 for 循环,该循环始终以 0 作为 i 的基本 int。从逻辑上讲,这不会停止。尝试用这个替换 for 循环:

if(currentLength != maxLength){
  addSongs(index + 1, maxLength);
}

【讨论】:

  • 递归调用会在currentLength &gt; maxLength时停止,并打到else,递减currentLength,然后返回i++
【解决方案3】:

我解决了我的问题。

如果有人感兴趣,代码如下:

private void addSongs(int index, long maxLength){

        if (TimeUnit.MILLISECONDS.toSeconds(currentLength) <= maxLength){
            int i;
            for (i = 0; i < songList.size() && TimeUnit.MILLISECONDS.toSeconds(currentLength) != maxLength; i++){
                    timerSongs.add(songList.get(i));
                    currentLength = currentLength + songList.get(i).getDuration();
                    addSongs(i, maxLength);
            }
            if (i >= songList.size()){
                currentLength = currentLength - timerSongs.get(timerSongs.size()-1).getDuration();
                timerSongs.remove(timerSongs.size()-1);
            }
        } else {
            currentLength = currentLength - timerSongs.get(timerSongs.size()-1).getDuration();
            timerSongs.remove(timerSongs.size()-1);
        }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 2015-05-04
    • 2018-05-30
    相关资源
    最近更新 更多