【问题标题】:Reverse a string without using standard functions不使用标准函数反转字符串
【发布时间】:2012-08-06 22:55:48
【问题描述】:

我最近在一次采访中被问到这个问题。作为一个刚毕业的学生,​​并且只编程了大约 2 年(所有学校工作),我不知所措。我有一个模糊的想法,但我确定我失败了。这是我写的:

string Reverse(string word, string reversed)
{
    if(word.length() == 0)
    {
        return reversed;
    }
    else
    {
        string temp;
        reversed = word.substr(0,1) + reversed;
        temp = word.substr(1);
        Reverse(temp, reversed);
    }

    return reversed;
}

现在我到家了,我正在测试它,返回的只是输入中的第一个字母。我对递归的概念模糊熟悉,但我显然在这方面失败了。非常感谢任何帮助/指针/建议。谢谢。

编辑: 根据 Dennis Meng 的帖子,我做了以下更改:

string Reverse(string word, string reversed)
{
    if(word.length() == 0)
    {
        return reversed;
    }
    else
    {
        string temp;
        reversed = word.substr(0,1) + reversed;
        temp = word.substr(1);
        return Reverse(temp, reversed);
    }
}

现在,我得到了正确的返回值。非常感谢你。

【问题讨论】:

  • 有什么问题?他们是否要求您使用递归来解决它?
  • 为什么Reverse 函数需要两个参数
  • 如果我在面试中问这个问题,我一直在寻找的答案是涉及使用反向迭代器对构造一个新字符串。我不会给你一个完整的答案 - 你可以自己查一下。
  • @Marko:面试问题不必“难以回答”。面试不应该是一场竞赛,因为通常你需要一个好的候选人而不是冠军。
  • @SChepurin 非常如此 - 通常情况下,需要勤奋、更初级的完成者,而不是团队中另一个自负的明星开发者,有时预算会限制你的工作聘请。期望指导新的团队成员也没有错——但这在很大程度上取决于项目环境和有人来做这件事。你永远不想要的是一种责任,以后你会因为表现不佳而难以解雇。

标签: c++ string recursion reverse


【解决方案1】:

这里出了什么问题:

    else
    {
        string temp;
        reversed = word.substr(0,1) + reversed;
        temp = word.substr(1);
        Reverse(temp, reversed); // <-- Here's your problem
    }

    return reversed;
}

您知道调用应该返回正确的答案,那么为什么不直接返回呢?换句话说,如果你这样做了会怎样

    else
    {
        string temp;
        reversed = word.substr(0,1) + reversed;
        temp = word.substr(1);
        return Reverse(temp, reversed);
    }
}

相反?为什么你的代码只返回第一个字母的细节涉及按引用/按值传递;由于传递值的东西,你从来没有真正使用过递归调用中所做的事情。 (你刚刚打了电话,就把它返回的东西扔掉了。)

【讨论】:

  • 非常感谢!那个小小的改变就做到了。这种问题在面试中很常见吗?在我的课堂上,我的导师总是强调“不要重新发明轮子”。我想知道我是否被赋予了错误的心态。再次感谢!
  • 这是一个非常常见的面试问题,可以帮助您开始工作,确保您具备基础知识等。您的导师说您不应该重新发明轮子是对的,但很高兴知道如何轮子被发明出来了,无论如何,面试官更想知道你的思维过程而不是答案。
  • (另外,其他人说有更好的方法可以做到这一点是对的,但我会在面试问题中说这种方法非常好。)
  • 看到我的原始回复,即使没有得到正确的返回值,作为面试官你会怎么想?只是试图衡量潜在的回调。我觉得剩下的面试和考试都很顺利。刚刚被抓住了。
  • 好吧,我可能不是询问面试官会说什么的最佳人选,但如果我在面试你并看到这段代码,我会看到你至少有一个粗略的理解递归,指出有一个错误,并鼓励你修复它。一旦它被修复,那么我会看看你是否可以在没有累加器的情况下递归地做到这一点,最后看看你是否可以做迭代解决方案。
【解决方案2】:
string Reverse(string word, string reversed) 
{
    ...
    Reverse(temp, reversed);

首先,您应该通过 const 引用传递 word,并通过引用传递 reversed。当您调用递归函数时,您正在制作每个字符串的副本,因此最外面的函数看不到它们所做的任何事情。另一种选择是将递归函数的结果分配给reversed,但是你仍然到处都有大量的字符串副本。所以:通过引用传递变量。

第二:有更简单的方法来反转字符串:

 string Reverse(string word) //caller should _not_ see my changes, so I pass by value
 {
     for(int i=0; i<word.size()/2; ++i) { //for each letter in the first half
         int otherindex = word.size()-1-i; //find the letter on the other half
         char t = word[i];  //and swap them
         word[i] = word[otherindex];
         word[otherindex] = t;
     }
     return word; //return the result
 }

【讨论】:

    【解决方案3】:

    我不确定你为什么在这里使用递归。真的没必要:

    string Reverse(string word)
    {
        string reversed = "";
    
        if(word.length() == 0)
        {
            return reversed;
        } 
    
        for (int i = word.length()-1; i>=0; i--){
            reversed = reversed+word[i];
        }
    
        return reversed;
    }
    

    【讨论】:

    • "sizeof(word)" -- nonononononoNO!
    • @ewok sizeof(word) 不返回字符串的长度,而是返回std::string 类的大小,这不是你想要的。你需要使用word.size()
    • 你为什么会被reversed传递?
    • OP 最初是用它作为累加器。
    • 是的,但在这一点上,我只是将其归结为回答者进行复制/粘贴而不是修剪所有内容。
    【解决方案4】:

    字符串只不过是一个字符数组。通常在这种情况下,您应该使用一个字符数组来解释算法。这是一个更好的方法。

    void reverse(char* str, int len)
    {
        for (int i = 0, j = len -1 ; i < len / 2; ++i, --j) {
             // Swap the values as i and j.
             int temp = str[i];
             str[i] = str[j];
             str[j] = temp;
        }
    }
    

    如果在 Java 中提出同样的问题,您必须确保将字符串转换为 char[] 数组,然后将其反转,然后形成一个字符串。这有助于保持创建的对象数量最少。至少,您应该使用 StringBuilder。

    【讨论】:

    • C++ 中不需要 StringBuilder;字符串是可变的。而且由于它们实现了operator [],因此您可以有效地使用这个相同的算法,除了您不再需要传递len 因为字符串已经知道它。 :P
    【解决方案5】:

    这是另一种解决方案(类似于已经发布的解决方案)。 但是现在我发现这个解决方案不适合你,因为它使用了 std 的东西。

    std::string reverse(std::string const& character_queue_) {
        using namespace std;
        string result;
        if(!character_queue_.empty()) {
            vector<char> character_stack;
            std::copy(character_queue_.begin(),character_queue_.end(),std::back_inserter(character_stack));
            while(!character_stack.empty()) {
               result.push_back(character_stack.back());
               character_stack.pop_back();
            }
        }
        return result;
    }
    

    【讨论】:

      【解决方案6】:

      只是为了建议一种更好的递归处理方式:

      在 C++ 中使用递归进行字符串反转:

      #include <iostream>
      #include <string>
      using namespace std;
      
      string reverseStringRecursively(string str){
          if (str.length() == 1) {
              return str;
          }else{
              return reverseStringRecursively(str.substr(1,str.length())) + str.at(0);
          }
      }
      
      int main()
      {
          string str;
          cout<<"Enter the string to reverse : ";
          cin>>str;
      
          cout<<"The reversed string is : "<<reverseStringRecursively(str);
          return 0;
      }
      

      【讨论】:

      • 谷歌“施莱米尔画家的算法”。 :P
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-03
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      相关资源
      最近更新 更多