C++递归查找字符串数组中的最小元素

C++递归查找字符串数组中的最小元素,c++,recursion,C++,Recursion,我需要使用递归找到数组中最小字符串的下标,如果数组没有要检查的元素,则返回-1。 这是我到目前为止提出的,但它不起作用 int leastElement(string a[], int n) { if(n == 1) return 0; if(a[0] > a[n]) a[0] = a[n]; return leastElement(a, n-1); } 您的递归深度将与n成比例,您可以在每个级别将数组一分为二: int l

我需要使用递归找到数组中最小字符串的下标,如果数组没有要检查的元素,则返回-1。 这是我到目前为止提出的,但它不起作用

int leastElement(string a[], int n)
{
    if(n == 1)
        return 0;



    if(a[0] > a[n])
        a[0] = a[n];

    return leastElement(a, n-1);
}

您的递归深度将与n成比例,您可以在每个级别将数组一分为二:

int leastElement(string a[], int n) {
       if (n <= 0)
          return -1;  // paranoid about empty array
       if (n == 1)
          return 0;
       const int left = leastElement(a, n/2);
       const int right = leastElement(a + n/2, n - n/2);
       if (left == -1) // paranoia again
          return right + n/2;
       if (right == -1)
          return left;
       return (a[left] < a[right + n/2]) ? left : right + n/2;
}

int main() {
  string a[] = {
    "ugl", "nvk", "akl", "ngl", "qal", "fgp", 
    "rjv", "kln", "ahf", "lak", "vjh",
    "sdf", "lak", "lmc", "lhf", "wer"
  };
  const int i = leastElement(a, 16);
  cout << i; // returns 8 "ahf"
  return 0;
}

递归的关键概念之一是下一个递归携带上一个递归的状态。例如,链表是递归的理想对象,因为下一个递归通常基于上一个链表链接

在这种情况下,数组需要一个起点和终点来定义数组。因此,您需要携带数组的开始索引和结束索引

int leastElement(int arr[], int start, int end) {
  if (start >= end -1) {
    return start;
  }
  else {
    int subLeastElement = leastElement (arr, start + 1, end);
    if (arr[start] <= arr[subLeastElement]) {
      return start;
    }
    else {
      return subLeastElement;
    }
  }
}

//This provides a simplified start point
int leastElement(int arr[], int n) {
    return leastElement(arr, 0, n);
}
此处的工作示例:


其思想是递归地访问列表中的每个字符串,然后随着递归的展开,使用当前最小值检查每个字符串

int leastElement(std::string a[], int n) {
    if(n == 0)
        return -1;

    int least = leastElement(a, n - 1);
    if (least > -1 && a[least] < a[n - 1]) {
        return least;
    }
    return n - 1;
}

这是通过递归获得字符串中最小字符的简单代码。

下面是一个演示程序,演示如何编写函数

#include <iostream>
#include <string>

int leastElement( const std::string a[], int n )
{
    if ( n <= 0 ) return - 1;

    int i = 1 + leastElement( a + 1, n - 1 );

    return i == 0 || !( a[i] < a[0] ) ? 0 : i;
}


int main()
{
    std::string a[] = { "C", "D", "A", "E" };

    int i = leastElement( a, sizeof( a ) / sizeof( *a ) );
    std::cout << i << ": " << a[i] << std::endl;

    return 0;
}
注意这个情况

!( a[i] < a[0] )

为什么不起作用?什么不起作用?更多信息pleaseStackoverflow不是家庭作业解决方案站点。字符串数组中最小的元素是什么?字典顺序?提示:在执行过程中,您没有保存下标,而是首先保存最小字符串。最明显的问题是,您没有处理数组has no elements case。如果n为0,则将递归到-1,依此类推,直到将int换行。小注释:如果有几个最小值,它将返回最后一个最小值。拆分为一半不会改变运行时,它只会混淆代码。事实上,它可能会降低执行速度,因为每一步都有过多的算术运算,可能会降低执行速度,但对于大型数组,它不会破坏堆栈帧。一点也不模糊-每一半中的最小部分是您要查找的字符串。最佳运行时间就是这个。你是对的,我误读了你的答案,认为你指的是时间复杂性。Op问的是字符串,但这很容易转移。你应该将[least+1]与[n-1]进行比较-请看@XiaotianPei answer.@icepack,这有何改进?这是不是因为没有比较至少+1而遗漏了什么?当然,这是最重要的部分。最小索引与子阵列相关,该子阵列的起始位置相对于原始阵列偏移了1。因此,为了将其与原始索引进行比较,需要对其进行调整appropriately@icepack,我想现在已经解决了,问题不在于+1,I==0的目的是什么?@icepack函数的递归调用可以返回-1。它被称为像int i=1+最小元素a+1,n-1;因此,1+-1将为0。此情况已包含在报税表中condition@icepack如果没有这个条件,整个条件看起来很混乱!a[0]#include <iostream> #include <string> int leastElement( const std::string a[], int n ) { if ( n <= 0 ) return - 1; int i = 1 + leastElement( a + 1, n - 1 ); return i == 0 || !( a[i] < a[0] ) ? 0 : i; } int main() { std::string a[] = { "C", "D", "A", "E" }; int i = leastElement( a, sizeof( a ) / sizeof( *a ) ); std::cout << i << ": " << a[i] << std::endl; return 0; }
2: A
!( a[i] < a[0] )
#include <iostream>
#include <string>

int leastElement( const std::string a[], int n )
{
    if ( n <= 0 ) return -1;
    if ( n == 1 ) return 0;

    int i = leastElement( a, n / 2 );
    int j = n / 2 + leastElement( a + n / 2, n - n / 2 );

    return !( a[j] < a[i] ) ? i : j;
}

int main()
{
    std::string a[] = { "C", "D", "A", "E" };

    int i = leastElement( a, sizeof( a ) / sizeof( *a ) );
    std::cout << i << ": " << a[i] << std::endl;
    return 0;
}
2: A