你会如何改进这个算法?

问题

通过我在网上找到的一些编程面试挑战,我不得不编写一个算法来反转 const char * 并返回一个指向新 char * 的指针。我想我有它,但为了让它正常工作,我不得不做一些奇怪的事情——基本上必须自己考虑空终止字符。不知何故,我觉得这是错误的,但我很难过,我想知道是否有人可以帮助我:

char * reverse(const char * str)
{
  int length = strlen(str);
  char * reversed_string = new char[length+1];

  for(int i = 0; i < length; ++i)
  {
    reversed_string[i] = str[(length-1) - i];
  }
  //need to null terminate the string
  reversed_string[length] = '\0';

  return reversed_string;

}

int main(int argc, char * argv[])
{

  char * rev_str = reverse("Testing");

  cout << "Your string reversed is this: " << rev_str << endl;

  delete rev_str;
  rev_str = 0;

  return 0;
}

解决方案

  • 上面的 for 循环有错字。检查循环变量 i 应该是 <= 而不是 <,否则对于奇数个元素将失败。for(int i = 0; i <= 长度/2; ++i)

  • char * reverse(const char * str)
    {
      if (!str)
        return NULL;
    
      int length = strlen(str);
      char * reversed_string = new char[length+1];
    
      for(int i = 0; i < length/2; ++i)
      {
        reversed_string[i] = str[(length-1) - i];
        reversed_string[(length-1) - i] = str[i];
      }
      //need to null terminate the string
      reversed_string[length] = '\0';
    
      return reversed_string;
    
    }

    一半的时间,但复杂性相同(注意可能会因一个错误而关闭)

    如果传递了一个空指针,那么到目前为止提交的所有strlen()答案都将失败——它们中的大多数会跳转到立即调用一个可能的空指针——这可能会导致你的进程出现段错误。

    许多答案都对性能着迷,以至于他们错过了问题的关键问题之一: reverse a const char *,即您需要制作反向副本,而不是就地反向。如果需要副本,您会发现很难将迭代次数减半!

    不需要临时变量的方法

    int length = strlen(string);
    for(int i = 0; i < length/2; i++) {
      string[i] ^= string[length - i] ^= string[i] ^= string[length - i];
    }

    字符串反转到位,没有临时变量。

    static inline void
    byteswap (char *a, char *b)
    {
      *a = *a^*b;
      *b = *a^*b;
      *a = *a^*b;
    }
    
    void
    reverse (char *string)
    {
      char *end = string + strlen(string) - 1;
    
      while (string < end) {
        byteswap(string++, end--);
      }
    }

    它不会更有效,但是您可以通过将每个字母推入堆栈,然后将它们弹出到新分配的缓冲区中来展示数据结构的知识。

    这将需要两次通过和一个临时堆栈,但我可能会更相信自己第一次就能做到这一点,然后不会像上面那样犯一个错误。

    char* stringReverse(const char* sInput)
    {
        std::size_t nLen = strlen(sInput);
        std::stack<char> charStack;
        for(std::size_t i = 0; i < nLen; ++i)
        {
            charStack.push(sInput[i]);
        }
        char * result = new char[nLen + 1];
        std::size_t counter = 0;
        while (!charStack.empty())
        {
            result[counter++] = charStack.top();
            charStack.pop();
        }
        result[counter] = '\0';
        return result;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值