在 ruby​​ 中解决 Hackerrank 的字谜解决方案

Posted

技术标签:

【中文标题】在 ruby​​ 中解决 Hackerrank 的字谜解决方案【英文标题】:Solving Hackerank's anagram solution in ruby 【发布时间】:2020-05-14 07:22:16 【问题描述】:
def anagram(s)
  counter = 0

  if s.length.even?
    splitter = s.chars.each_slice(s.length / 2).map(&:join)
    left = splitter[0]
    right = splitter[1]
    return 0 if right == left

    counter = left.length

    leftchar = left.split
    rightchar = right.split

    rightchar.each do |n|
      leftchar.each do |m|
        counter -= 1 while n == m
      end
    end
    counter
  else
    return -1
  end
end

您好,我正在尝试用 ruby​​ 解决 Hackerank 中的问题。该程序 是返回一个字符串中要更改的字符数,该字符串已被拆分以匹配另一个字符串。也就是说,如果这个词本身不是一个字谜。

到目前为止:

我首先检查字符串是否是第一个,然后再拆分 字符串一分为二,否则程序应该返回-1。 接下来,在拆分字符串后,我尝试检查是否可以 是出现在右字符串中的字符,而不出现在左字符串中。而且由于我的程序是返回字符数 需要更改,对于在左侧找到的每个字符 在右边,我从左边的长度减去一。

这就是我的逻辑。但我似乎错过了什么。有什么建议和提示我可以从中得到吗?谢谢。

【问题讨论】:

如果n==mcounter -= 1 while n == m 将永远循环。 (还有更多问题。) 其他问题:split 在空白处拆分。使用split("")chars 【参考方案1】:

执行此操作的众多方法之一如下。

def min_nbr_swaps(str)
  return -1 unless str.size.even?
  half = str.size/2
  str1 = str[0,half]
  str2 = str[half,half] 
  h = str2.each_char.with_object(Hash.new(0))  |c,h| h[c] += 1 
  str1.each_char.count do |c|
    case h[c]
    when 0
      true
    else
      h[c] -= 1
      false
    end
  end
end

min_nbr_swaps('aaabbb')   #=>  3
min_nbr_swaps('ab')       #=>  1
min_nbr_swaps('abc')      #=> -1
min_nbr_swaps('mnop')     #=>  2
min_nbr_swaps('xyyx')     #=>  0 
min_nbr_swaps('xaxbbbxx') #=>  1

步骤如下。

str = 'xaxbbbxx'

str.size.even?
  #=> 8.even? => true, so do not return -1
half = str.size/2
  #=> 4 
str1 = str[0,half]
  #=> "xaxb" 
str2 = str[half,half] 
  #=> "bbxx" 
h = str2.each_char.with_object(Hash.new(0))  |c,h| h[c] += 1 

这使用Hash::new 的形式,它接受一个称为默认值的参数。这意味着当 Ruby 的解析器将h[c] += 1 扩展为

h[c] = h[c] + 1

如果h 没有键c,则右侧的h[c] 返回h 的默认值0。比如h为空时,

h['x'] = h['x'] + 1 #=> 0 + 1 => 1
h['x'] = h['x'] + 1 #=> 1 + 1 => 2

h 在第一个表达式中没有键 'x',因此右侧的 h[c] 返回默认值 0,而 h 在第二个表达式中确实有该键,因此默认值值不适用。

继续,

enum = str1.each_char
  #=> #<Enumerator: "xaxb":each_char> 

我们现在使用Enumerable#count的方法来确定str1中需要修改的字符数。

enum.count do |c|
  case h[c]
  when 0
    true
  else
    h[c] -= 1
    false
  end
end
  #=> 4

传递给count的块的第一个元素是str1[0] #=&gt; 'x'

c = 'x'

作为h['x'] #=&gt; 2case 语句执行

h['x'] -= 1

并返回false,这意味着x 不需要更改。现在h #=&gt; "b"=&gt;2, "x"=&gt;1

接下来,为块变量赋值str1[1] #=&gt; 'a'

c = 'a'

作为h['a'] #=&gt; 0case 语句返回true,表示需要更改a。这里h[a] 返回默认值0,因为h 没有键ah 没有改变。

其余的计算类似,都返回falsecount 返回 1,因为该块仅返回 true 1 4 中的 4 字符。

【讨论】:

简洁的解决方案,但不确定h[c] 可以是nil 应用默认0

以上是关于在 ruby​​ 中解决 Hackerrank 的字谜解决方案的主要内容,如果未能解决你的问题,请参考以下文章

使用背包解决硬币变化。参考:另一个背包 Hackerrank CodeAgon

堆栈和优化——来自hackerrank的例子

HackerRank天气观测站5

hackerrank“制作字谜”挑战超时失败

python HackerRank“形成一个魔术广场”的python解决方案

没有指针的 C++ 分段错误 (HackerRank)