ruby:比较两个单词并从中提取不常见的字母

yh2wf1be  于 2023-08-04  发布在  Ruby
关注(0)|答案(4)|浏览(91)

我必须创建一个程序,它需要用户输入两个单词,并从两个单词中提取唯一的字母。
两个词是“外推法”和“之间”
在移除公共字母表之后,结果应该是“extrpolatimg”,而不管馈送的单词的顺序。因为虽然外推法中有两个a,但只有一个被删除。
代码由我写到现在作为下

puts "Enter the first_word : "

word_1 = gets.chomp.downcase.split('', 0)

puts "Enter second word name: "

word_2 = gets.chomp.downcase.split('', 0)

p word_1

p word_2

differences = word_1- word_2

p differences

#input1 = among
#input2 = extrapolation

# output => ["m","g"]

字符串
代码会忽略第二个单词中第一个单词中没有的字母。
是否有任何内置的字符串方法来处理这个问题?
提前感谢您的帮助。

dba5bblo

dba5bblo1#

您可以使用sub来替换模式的第一次出现:(可以是单个字符)

'extrapolation'.sub('a', '_')
#=> "extr_polation"

字符串
你也可以通过传递一个空字符串作为替换来 * 删除 * 第一个出现的字符串:

'extrapolation'.sub('a', '')
#=> "extrpolation"


这可以在循环中用于从一个字符串替换另一个字符串中的所有字符:

input1 = 'among'
input2 = 'extrapolation'

result = input1

input2.each_char do |char|
  result = result.sub(char, '')
end

result
#=> "mg"


为了避免每次迭代都创建一个新字符串,您可以对字符串重复调用sub!,这将就地修改接收者。但是,由于这种修改,您必须对输入进行dup,以避免修改input1

result = input1.dup

input2.each_char do |char|
  result.sub!(char, '')
end

result
#=> "mg"


这可以通过使用with_object进一步重构,这对于在方法内部提供隐式返回值特别有用:

def word_diff(string1, string2)
  string2.each_char.with_object(string1.dup) do |char, string|
    string.sub!(char, '')
  end
end

diff1 = word_diff(input2, input1)
#=> "extrplatio"

diff2 = word_diff(input1, input2)
#=> "mg"

diff1 + diff2
#=> "extrplatiomg"


从性能方面来说,这种方法可能不适合(非常)大的字符串,因为它将对第二个字符串中的每个字符遍历第一个字符串一次(反之亦然)。

h9vpoimq

h9vpoimq2#

假设我们有两个词。

w1 = "extrapolation"
w2 = "among"

字符串

  • 步骤1:将这些字符串中的每一个转换为字符数组 *
a1 = w1.chars
  #=> ["e", "x", "t", "r", "a", "p", "o", "l", "a", "t", "i", "o", "n"]
a2 = w2.chars
  #=> ["a", "m", "o", "n", "g"]

  • 第2步:为每个数组创建一个散列,该散列给出数组中每个唯一字符的第一个示例的索引 *
def first_char_pos(a)
  a.each_with_index.with_object({}) do |(c,i),h|
    h[c] = i unless h.key?(c)
  end
end
h1 = first_char_pos(a1)
  #=> {"e"=>0, "x"=>1, "t"=>2, "r"=>3, "a"=>4,
  #    "p"=>5, "o"=>6, "l"=>7, "i"=>10, "n"=>12}
h2 = first_char_pos(a2)
  #=>{"a"=>0, "m"=>1, "o"=>2, "n"=>3, "g"=>4}

的字符串

  • 第三步:找出每个单词中要去掉的字母 *
letters_to_remove = a1 & a2
  #=> ["a", "o", "n"]

  • 第4步:确定每个单词中字母的索引以保留 *
def indices_to_keep(a, h, letters_to_remove)
  a.size.times.to_a - h.values_at(*letters_to_remove)
end
idx1 = indices_to_keep(a1, h1, letters_to_remove)
  #=>[0, 1, 2, 3, 5, 7, 8, 9, 10, 11]
idx2 = indices_to_keep(a2, h2, letters_to_remove)
  #=> [1, 4]
  • 第五步:按顺序识别每个单词中的字母 *
s1 = a1.values_at(*idx1)
  #=> ["e", "x", "t", "r", "p", "l", "a", "t", "i", "o"]
s2 = a2.values_at(*idx2)
  #=> ["m", "g"]

  • 第六步:形成所需的字符串 *
s1.join + s2.join
  #=> "extrplatiomg"


这与所需的字符串"extrpolatimg"不同。原因是我删除了每个要删除的字母的第一个示例,而所需的字符串是通过删除每个字符串的第一个"a"和每个字符串的最后一个"o"获得的。要么是OP在给出期望的结果时犯了错误,要么是我不理解确定哪个字母的示例要被删除的规则。
我没有提到大写字母可能出现的情况,因为我不知道适用于这种情况的规则。

5fjcxozz

5fjcxozz3#

对于手头的任务,你可以通过稍微改变你的方法来完成它。Ruby虽然很棒,但它允许我们使用chars方法将字符串转换为字符数组。所以,你可以用chars替换split('',0)。
这里的逻辑是首先创建第二个单词的字符的副本。然后,迭代第一个单词的字符。如果在第二个单词的副本中找到字符,则将其从第一个单词和第二个单词的副本中删除。这两个词中剩下的都是独特的字符。
让我们把它转换成代码:

puts "Enter the first word: "
word_1 = gets.chomp.downcase.chars

puts "Enter the second word: "
word_2 = gets.chomp.downcase.chars

copy_word_2 = word_2.dup # Create a copy of word_2 characters

word_1.each do |char|
  if copy_word_2.include?(char)
    word_1.delete_at(word_1.index(char))
    copy_word_2.delete_at(copy_word_2.index(char))
  end
end

differences = word_1 + copy_word_2 # Combine remaining unique characters from both words

puts "The unique characters are: "
p differences

字符串
在此代码中,我们使用delete_at方法删除数组中特定索引处的字符,并使用index方法查找字符第一次出现的索引。方法检查数组是否包含特定字符。

vohkndzv

vohkndzv4#

我会这样做:

puts 'Enter the first_word:'
chars1 = gets.chomp.downcase.chars

puts 'Enter second word name:'
chars2 = gets.chomp.downcase.chars

((chars1 - chars2) + (chars2 - chars1)).join

# with 'extrapolation' and 'amoug'
# => "extrpltimg"

# with 'amoug' and 'extrapolation'
# => "mgextrplti"

字符串

相关问题