C ++ to Ruby:在字符串中查找子字符串

时间:2013-07-15 20:56:14

标签: c++ ruby

我学习了Rails,现在想扩展我对Ruby的了解。所以我在Ruby中做一些C ++练习。具体来说,我需要查找字符串中是否存在子字符串。如果是的话,我需要它来返回它的起始索引。如果它不存在则返回-1。我想出了一个与C ++非常相似的Ruby解决方案,并想知道Ruby中是否存在“更好”,更惯用的解决方案?

C ++

int find(char str[], char sub_str[])
{
  int str_length = strlen(str);
  int sub_str_length = strlen(sub_str);
  bool match = false;

  for(int i=0; i<str_length; i++)
  {
    if(str[i] == sub_str[0])
    {
      for(int j=1; j<sub_str_length; j++)
      {
        if(str[i+j] == sub_str[j])
          match = true;
        else
        {
          match = false;
          break;
        }
      }
      if(match)
        return i;
    }
  }
  return -1;
}

红宝石

def find_sub_str(str, sub_str)
  match = false
  for i in 0...str.length
    if str[i] == sub_str[0]
      for j in 1...sub_str.length
        if str[i+j] == sub_str[j]
          match = true
        else
          match = false
          break
        end
      end
      if match == true
        return i
      end
    end
  end
  return -1
end

3 个答案:

答案 0 :(得分:4)

您可以使用String的{​​{3}}方法。它在匹配失败时返回nil,这比返回-1更为惯用Ruby。

 "SubString".index("String") # -> 3
 "SubString".index("C++") # -> nil

如果您真的想要这种行为,可以将它包装在一个测试中,该测试返回-1为nil。

答案 1 :(得分:2)

  1. 不要在Ruby中使用for,它只调用each并且不引入范围。因此for i in 0...str.length变为(0...str.length).each do |i|

  2. 高阶函数是你的朋友!使用each_cons&amp; find_index使事情变得更加清晰(研究Enumerable,这是许多有用方法的基础):

    def find_sub_str(str, sub_str)
      str.chars.each_cons(sub_str.length).find_index do |s|
        s.join == sub_str
      end
    end
    
    find_sub_str('foobar', 'ob')  #=> 2
    
  3. 只需使用Ruby核心的index :)

    'foobar'.index('ob')  #=> 2
    
  4. #2&amp;当没有匹配时,#3返回nil,而不是-1。这是最好的,因为在Ruby中nil是假的。

答案 2 :(得分:0)

#how if we use this solution, it gets the job done in O(n)    

given_string = "Replace me with your code!"

chars_given_string = given.split('')

chars_of_substr = "ith".split('')

is_substr = false
ptr = 0

char_given.each do |i|
    if ( i == substr[ptr])
       ptr += 1
    else
       ptr = 0
    end
    is_substr = true if ptr == substr.length
    break if ptr == substr.length
end

puts is_substr