如何解决此递归代码的执行?

时间:2019-04-20 04:47:44

标签: java recursion

在这个基本的数组问题中,我需要使用递归将数组的上一个索引的总和或值添加到当前索引值中。

例如,==20116== Memcheck, a memory error detector ==20116== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==20116== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==20116== Command: ./main ==20116== --20116-- Valgrind options: --20116-- -v --20116-- Contents of /proc/version: --20116-- Linux version 4.14.65-gentoo (root@KILLINGMACHINE) (gcc version 7.3.0 (Gentoo 7.3.0-r3 p1.4)) #1 SMP Mon Apr 15 05:45:45 -00 2019 --20116-- --20116-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-avx-avx2-bmi --20116-- Page sizes: currently 4096, max supported 4096 --20116-- Valgrind library directory: /usr/lib64/valgrind --20116-- Reading syms from /home/rofl/test_program/main --20116-- ELF section outside all mapped regions --20116-- Reading syms from /lib64/ld-2.28.so --20116-- ELF section outside all mapped regions --20116-- Reading syms from /usr/lib64/valgrind/memcheck-amd64-linux --20116-- ELF section outside all mapped regions --20116-- Scheduler: using generic scheduler lock implementation. --20116-- Reading suppressions file: /usr/lib64/valgrind/default.supp ==20116== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-20116-by-rofl-on-??? ==20116== embedded gdbserver: writing to /tmp/vgdb-pipe-to-vgdb-from-20116-by-rofl-on-??? ==20116== embedded gdbserver: shared mem /tmp/vgdb-pipe-shared-mem-vgdb-20116-by-rofl-on-??? ==20116== ==20116== TO CONTROL THIS PROCESS USING vgdb (which you probably ==20116== don't want to do, unless you know exactly what you're doing, ==20116== or are doing some strange experiment): ==20116== /usr/lib64/valgrind/../../bin/vgdb --pid=20116 ...command... ==20116== ==20116== TO DEBUG THIS PROCESS USING GDB: start GDB like this ==20116== /path/to/gdb ./main ==20116== and then give GDB the following command ==20116== target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=20116 ==20116== --pid is optional if only one valgrind process is running ==20116== --20116-- Reading syms from /usr/lib64/valgrind/vgpreload_core-amd64-linux.so --20116-- ELF section outside all mapped regions --20116-- Reading syms from /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so --20116-- ELF section outside all mapped regions --20116-- Reading syms from /usr/lib64/gcc/x86_64-pc-linux-gnu/8.2.0/libstdc++.so.6.0.25 --20116-- Reading syms from /lib64/libm-2.28.so --20116-- ELF section outside all mapped regions --20116-- Reading syms from /usr/lib64/gcc/x86_64-pc-linux-gnu/8.2.0/libgcc_s.so.1 --20116-- Reading syms from /lib64/libc-2.28.so --20116-- ELF section outside all mapped regions ==20116== Conditional jump or move depends on uninitialised value(s) ==20116== at 0x49A65EA: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:874) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== ==20116== Use of uninitialised value of size 8 ==20116== at 0x49A60BE: int std::__int_to_char<char, unsigned long>(char*, unsigned long, char const*, std::_Ios_Fmtflags, bool) (locale_facets.tcc:803) ==20116== by 0x49A6613: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:876) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== ==20116== Conditional jump or move depends on uninitialised value(s) ==20116== at 0x49A60CB: int std::__int_to_char<char, unsigned long>(char*, unsigned long, char const*, std::_Ios_Fmtflags, bool) (locale_facets.tcc:806) ==20116== by 0x49A6613: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:876) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== ==20116== Conditional jump or move depends on uninitialised value(s) ==20116== at 0x49A6646: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:896) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== 0 ==20116== ==20116== HEAP SUMMARY: ==20116== in use at exit: 0 bytes in 0 blocks ==20116== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==20116== ==20116== All heap blocks were freed -- no leaks are possible ==20116== ==20116== Use --track-origins=yes to see where uninitialised values come from ==20116== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0) ==20116== ==20116== 1 errors in context 1 of 4: ==20116== Conditional jump or move depends on uninitialised value(s) ==20116== at 0x49A6646: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:896) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== ==20116== ==20116== 1 errors in context 2 of 4: ==20116== Conditional jump or move depends on uninitialised value(s) ==20116== at 0x49A60CB: int std::__int_to_char<char, unsigned long>(char*, unsigned long, char const*, std::_Ios_Fmtflags, bool) (locale_facets.tcc:806) ==20116== by 0x49A6613: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:876) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== ==20116== ==20116== 1 errors in context 3 of 4: ==20116== Use of uninitialised value of size 8 ==20116== at 0x49A60BE: int std::__int_to_char<char, unsigned long>(char*, unsigned long, char const*, std::_Ios_Fmtflags, bool) (locale_facets.tcc:803) ==20116== by 0x49A6613: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:876) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== ==20116== ==20116== 1 errors in context 4 of 4: ==20116== Conditional jump or move depends on uninitialised value(s) ==20116== at 0x49A65EA: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:874) ==20116== by 0x49B3671: put (locale_facets.h:2371) ==20116== by 0x49B3671: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73) ==20116== by 0x1091B2: ??? (in /home/rofl/test_program/main) ==20116== by 0x503D45A: ??? (in /lib64/libc-2.28.so) ==20116== by 0x51E7407: ??? ==20116== by 0x1FFF0001F7: ??? ==20116== by 0x1051E7407: ??? ==20116== by 0x109184: ??? (in /home/rofl/test_program/main) ==20116== ==20116== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0) 变为{5,3,1,2}

由于第0个索引是第一个索引,因此它保持原样。

我认为我的代码是正确的,但根据我的空运行,指令指针未在流动,并且return语句(针对基本条件)未执行。由于我的代码是Java语言,因此在添加try-catch之后我得到了预期的输出。但是添加try-catch并不是解决方案。

{5,8,9,11}

4 个答案:

答案 0 :(得分:2)

static int[] addr(int a[],int i,int n)
{
    if (i==0)
        addr(a,i+1,n); // buggy
    if (i==n-1)
    {
        a[i] = a[i]+a[i-1];
        return a;
    }

    // code executed after if (i==0) block returns
    a[i] = a[i] + a[i-1];
    addr(a,i+1,n);
    return a;
}

由于return a;块内没有if (i==0),因此将执行随后的代码块。由于i的值为0,因此a[i-1]等效于a[-1],这将导致抛出ArrayOutOfBoundsException

您可以通过以下方式解决此问题:

  1. return a;块内添加if (i==0)

  2. 具有主函数以i = 1调用此递归函数。这样,​​您可以删除if (i==0)块。


由于Java数组是pass-by-reference,因此实际上您不需要返回该数组。

class kr1
{
    public static void main(String[] args) {
        int a[]= {5,1,3,9,5};
        addr (a,0,a.length);
        for (int i:a)
            System.out.print (i +" ");
    }

    static void addr(int a[],int i,int n)
    {
        if (i==0)
            addr(a,i+1,n);
            return;
        if (i==n-1)
        {
            a[i] = a[i]+a[i-1];
            return;
        }
        a[i] = a[i] + a[i-1];
        addr(a,i+1,n);
    }
   }

这将使代码更具可读性。

答案 1 :(得分:0)

static int[] addr(int a[],int i,int n)
{
    if (i==0)
        return addr(a,i+1,n);
    if (i==n-1)
    {
        a[i] = a[i]+a[i-1];
        return a ; //this return statement is not executing
    }
    //this below part is executing even if i has reached to n-1
    a[i] = a[i] + a[i-1];
   return addr(a,i+1,n);
}

在递归调用函数时,应该返回函数调用的值,而您没有这样做。因此,我刚刚在召回功能中添加了一个功能,并且它起作用了。另外,检查您的算法,如果数组的长度为1,则算法失败,您可以添加简单的检查以确保当数组大小为1或零时,返回数组并且不对数组进行任何操作。干杯。

答案 2 :(得分:0)

这是您的代码重构:

public class Main {
    public static void main(String[] args) {
        int[] a = {5,3,1,2};

        addr(a, 0);

        for (int i : a) {
            System.out.print(i + " ");
        }
    }

    static int[] addr(int[] a, int i) {

        if(i == a.length) {
            return a;
        }

        if(i != 0) {
            a[i] += a[i - 1];
        }

        return addr(a, i + 1);
    }

}

我只是将索引传递给下一个递归方法调用中要更改的下一个元素。由于我拥有i-1索引元素中所有先前元素的总和,因此我将其添加。

我认为您的方法不需要返回对数组的引用,因为当您将数组传递给方法时,您将能够直接对其进行修改,并且更改将是该方法的明显缺陷。

答案 3 :(得分:0)

只需更改代码的这一部分

if (i==0)
    addr(a,i+1,n);

对此

if (i==0){
     addr(a,i+1,n);
     return a;
}