【问题标题】:Understanding arrays and pointers in recursive functions理解递归函数中的数组和指针
【发布时间】:2015-02-19 04:38:30
【问题描述】:

我必须编写一个递归函数来检查两个相同大小的给定数组是否具有相同的元素,但它们的顺序可能不同。

我认为最优雅的解决方案是对两个数组进行排序,然后比较每个元素,但我不知道如何在一个递归函数中对两个数组进行排序。

所以我有另一个想法,使用线性搜索,获取array1的最后一个元素并在array2中搜索它,如果它在那里,使用shiftback函数,移动该元素前面的所有元素(在array2中)并返回true,如果没有找到返回 false。这将经历所有级别的递归。

但它不起作用,我在调试器中看到,在满足递归停止条件很久之后,数组突然变成了 1 个元素。

根据我的阅读,不将数组作为指针传递是不明智的,但它可以解决这个问题吗?到底是怎么做到的?

这是代码,有据可查:

注意:我不能使用库函数。

#include <iostream>
using namespace std;

bool sameelem(int A1[], int A2[], int len);
void shiftback(int a[], int len, int i);
bool lsearchandshift(int a[], int len, int key);

void main()
{
    int arr[7] = { 1, -2, 3, 4, -1, 6, -7 };
    int arr2[7] = { 1, -2, 3, 3, -1, 6, -7 };

    cout << sameelem(arr, arr2, 7);
}

bool sameelem(int A1[], int A2[], int len){
    ///pick an element from arr1, if it appears in arr2 cut both out using shiftback
    ///if it doesn't appear rerturn false, false should go thorugh all levels till the end
    //end: if true check last two elements, if false return false

    if (size==0)return true;
    else{
        sameelem(Arr1, Arr2, len - 1);
        return (lsearchandshift(Arr2, size, Arr1[size - 1]));//if the last element from Arr1 is in Arr2 this will be true
    }
}


//linear search function, will return 0 if key isn't found, otherwise will 'kill' that element using shiftback function and return 1
bool lsearchandshift(int a[], int len, int key){
    int i;
    bool found = false;

    for (i = 0; i < len && found==false; i++)//if found will turn true and stop searching
    {
        if (a[i] == key){
            found = true;

            shiftback(a, len, i);
        }
    }
    return found;
}

//array shifting backward function
//len has to be logical size, array's physical size has to be larger than entered logical size
void shiftback(int a[], int len, int i){
//i is the index which will be moved one place forward to i+1 along with all the other elements
    int j;
    for (j = i; j < len; j++)
    {
        a[j] = a[j+1];
    }
    //return a[len-1];
}

【问题讨论】:

  • @ravi 但如果数组是:A[3]={2,3,3}B[3]={3,2,2}?这种方法会错误地认为它们是相同的。我不能在一个递归函数中做到这一点
  • 当然排序数组比依赖线性搜索更可取...为什么不使用 std::sort 对数组进行排序,然后将它们传递给递归函数以检查它们是否是相等...这将是一件容易的事。
  • 你想从 A 中删除一个元素,在 B 中搜索,如果找到,然后从 B 中删除,然后在新缩短的数组上再次调用该函数,对吗?
  • @ravi 我自己做的,不依赖库函数。
  • @Beta 差不多,我只想从数组 B 中删除元素,并通过递归线性遍历 A 的元素。

标签: c++ arrays pointers recursion


【解决方案1】:

将此作为参考:-

bool isSame(int *p, int *q, int n)
{
    if( n == -1 )
        return true;
    if ( *p != *q )
        return false;
    else
        isSame(++p, ++q, --n);
}

int main()
{
    int arr1[] = {1,2,3,2,4,5};
    int arr2[] = {2,1,5,2,3,4};

    //check if two arrays have different number of elements...
    //If yes then just jump past 4-5 lines...

    std::sort(arr1, arr1 + sizeof(arr1)/sizeof(arr1[0]));  <<< You can build your own
    std::sort(arr2, arr2 + sizeof(arr2)/sizeof(arr2[0]));  <<< sort.

    if( isSame(arr1, arr2, 6) )
        cout << "Arrays are same" << endl;
    else
        cout << "Arrays are different" << endl;
}

在这些算法中,首先对数组进行排序几乎总是比在未排序的数组上工作要好。另一个好处是,当您看到不匹配时,您将停止进一步前进。

【讨论】:

    【解决方案2】:

    唯一调用自己的函数是haveSameElems

    bool haveSameElems(int Arr1[], int Arr2[], int size)
    {
      ///pick an element from arr1, if it appears in arr2 cut both out using shiftback
      ///if it doesn't appear rerturn false, false should go thorugh all levels till the end
      //end: if true check last two elements, if false return false
      if (size==0)return true;
      else{
        haveSameElems(Arr1, Arr2, size - 1);
        return (lsearchandshift(Arr2, size, Arr1[size - 1]));//if the last element from Arr1 is \
    in Arr2 this will be true
      }
    }
    

    注意不使用递归调用的返回值。所以递归调用可能会返回false,而调用函数永远不会知道它。

    您可以轻松解决此问题:

    if(!haveSameElems(Arr1, Arr2, size - 1))
      return(false);
    

    还有很大的改进空间——在这段代码和你编写它的方法上——但这足以让你感动。

    【讨论】:

    • 啊,是的,我错过了一种通过所有级别的递归返回 false 的方法。感谢您指出了这一点。虽然如果数组相同但排序不同,它看起来不起作用......回到绘图板。
    • @kuhaku:是的,因为您不清楚size 实际代表什么。正如我所说,还有很多事情要做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 2011-01-08
    • 2015-02-12
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多