【问题标题】:myProgrammingLab Palindrome Challenge Using Recursion使用递归的 myProgrammingLab 回文挑战
【发布时间】:2021-12-10 11:49:33
【问题描述】:

我正在参加编程入门课程,并且通过 myProgrammingLab 将大量材料深入到我们的脑海中。我在递归的概念上遇到了一点麻烦……对我来说,它有点被击中或错过。这个特殊的问题让我很难过。当我提交我的代码时,它会提供给我

CTest1.cpp:在函数'bool isPalindrome(int*, int)'中: CTest1.cpp:9:错误:从“int”到“int*”的无效转换 CTest1.cpp:9: 错误: 初始化 'bool isPalindrome(int*, int)' 的参数 1" 作为建议,我可以向您保证,这不是很有帮助。哈哈

我认为我的主要问题是当我进行实际递归时。我知道有些不对劲,但是..如果你能指出我正确的方向,我将非常感激。

“数组回文”是一个数组,当它的元素被反转时,它保持不变(即,当向前或向后扫描时,数组的元素是相同的)

编写一个递归的、布尔值的函数 isPalindrome,它接受一个整数值数组和元素个数,并返回该数组是否为回文。

如果满足以下条件,则数组是回文数组:数组为空(0 个元素)或仅包含一个元素(因此反转时相同),或数组的第一个和最后一个元素相同,其余的数组(即倒数第二个元素)形成一个回文。

到目前为止我的代码:

bool isPalindrome(int arr[], int n)
{
    if (n == 0 || n == 1)
    {
        return true;
    }
    else if (arr[n-1] == isPalindrome(arr[((n-1) - n) +1 ], n))
    {
        return true;
    } 
    else 
    {
        return false;
    }
}

【问题讨论】:

  • arr[((n-1) - n) +1 ] 返回单个 int,而不是数组。你不能用它作为第一个参数调用isPalindrome
  • 一般if (arr[n-1] == isPalindrome(arr[((n-1) - n) +1 ], n)) 行没有什么意义,因为您试图将intbool 进行比较

标签: c++ arrays recursion


【解决方案1】:

isPalindrome 不接受 int 作为第一个参数。它只接受一个数组,通过这样做:arr[((n-1) - n) +1] 你正在给它一个int,而不是一个整数数组。这个((n-1) - n) +1 将评估为数组中的“位置”,例如:arr[0] 是第一个元素,您的情况是 int。

【讨论】:

    【解决方案2】:

    递归主要包含三个主要部分:

    • 一个停止条件(当您达到一个足够小的数组大小以保证回文(01)时),
    • 一个计算步骤(例如,比较数组的第一项和最后一项并确定继续是否有意义)和
    • 嵌套递归调用的数据子集选择(例如,大小为 n - 2 的数组,不包括第一个和最后一个字符,我们已经比较并发现“值得回文”)。

    代码中的三个组件:

    bool isPalindrome(int arr[], size_t n) {
      return n < 2 || (
             arr[0] == arr[n - 1] &&
             isPalindrome(arr + 1, n - 2));
    }
    

    当然你可能想稍微测试一下这个函数(别忘了在valgrind下运行它):

    #include <iostream>
    
    int main() {
      std::cout << isPalindrome((int[0]){}, 0) << std::endl;
      std::cout << isPalindrome((int[1]){1}, 1) << std::endl;
      std::cout << isPalindrome((int[2]){1, 1}, 2) << std::endl;
      std::cout << isPalindrome((int[2]){2, 1}, 2) << std::endl;
      std::cout << isPalindrome((int[2]){1, 2}, 2) << std::endl;
      std::cout << isPalindrome((int[3]){1, 2, 1}, 3) << std::endl;
      std::cout << isPalindrome((int[3]){2, 2, 2}, 3) << std::endl;
      std::cout << isPalindrome((int[3]){2, 2, 1}, 3) << std::endl;
      std::cout << isPalindrome((int[4]){1, 2, 1, 2}, 4) << std::endl;
      std::cout << isPalindrome((int[4]){1, 2, 2, 1}, 4) << std::endl;
      std::cout << isPalindrome((int[4]){1, 2, 3, 2}, 4) << std::endl;
      std::cout << isPalindrome((int[4]){2, 3, 2, 1}, 4) << std::endl;
      std::cout << isPalindrome((int[4]){1, 3, 3, 1}, 4) << std::endl;
    }
    

    作为旁注,这个^^^ 与数组的致命斗争表明不同的数据类型将是一个更好的选择。例如,std::stringstd::vector 可以更容易地进行初始化方式,应该通过引用传递,并且作为奖励,STL 容器会携带大小信息。此外,您可以在递归中将std::string_view 用于子字符串,将std::span 用于“子向量”,而无需在每个递归级别上一遍又一遍地复制容器。

    这是一个带有std::string_view 的示例和三个不同的实现(一个有递归,两个没有递归):

    #include <iostream>
    #include <string_view>
    
    bool isPalindrome1(const std::string_view s) {
      return s.size() < 2 || (
             s[0] == s[s.size() - 1] &&
             isPalindrome1(s.substr(1, s.size() - 2)));
    }
    
    bool isPalindrome2(const std::string_view s) {
      const size_t end = s.size() / 2;
      for (size_t i = 0; i < end; ++i)
        if (s[i] != s[s.size() - i - 1])
          return false;
      return true;
    }
    
    bool isPalindrome3(const std::string_view s) {
      auto b = s.begin();
      const auto end = b + s.size() / 2;
      auto e = s.rbegin();
      for (; b < end; ++b, ++e)
        if (*b != *e) return false;
      return true;
    }
    
    int main() {
      for (auto isPalindrome : {isPalindrome1,
                                isPalindrome2,
                                isPalindrome3}) {
        std::cout << isPalindrome("") << std::endl;
        std::cout << isPalindrome("a") << std::endl;
        std::cout << isPalindrome("ab") << std::endl;
        std::cout << isPalindrome("aa") << std::endl;
        std::cout << isPalindrome("abc") << std::endl;
        std::cout << isPalindrome("aba") << std::endl;
        std::cout << isPalindrome("baab") << std::endl;
        std::cout << isPalindrome("baba") << std::endl;
      }
    }
    

    【讨论】:

    • 我刚刚解决了这个问题,但感谢您的意见,这确实有助于让事情变得清晰;)
    • 很高兴它有帮助。我还添加了std::string_view 示例,更容易调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 2015-03-17
    相关资源
    最近更新 更多