[关闭]
@smilence 2020-02-14T14:22:54.000000Z 字数 4221 阅读 981

Ruby Programming

入门编程与算法


0. BASICS

0.1 连续访问x到y, 重复做一件和访问的数字有关的事

  1. (x..y).each do |idx|
  2. # do something related to idx
  3. end

0.2 重复做一件和访问第几次无关的事n次

  1. n.times do
  2. # do something
  3. end

1. String

1.1 将string里的字符变换得到另一个string的问题

如果string里包含多个词,用空格隔开,见1.3. 如果不是, 则新建new_str, 用str.each_char 对老string进行遍历后把char挨个插入到new_str

  1. new_str = ""
  2. str.each_char do |char|
  3. new_str << char.upcase # uppercase each char
  4. end
  5. return new_str

1.2 sentence中包含多个词,用空格隔开,处理每个词

处理这样的string, 总是通过str.split(" ")把问题转换成array问题 (array of strings), 然后对array进行遍历 (arr.each/ arr.each_with_index / arr.map) 处理每个分隔开的word.

1.3 sentence中包含多个词,用空格隔开,转换成另一句sentence

通过str.split(" ")把问题转换成array问题 (array of strings), 然后把array按照2.1的方法变化成新array new_arr, 最后再用new_arr.join(" ")转回为string

  1. parts = str.split(" ")
  2. # 把parts按照题意转换成目标array
  3. new_parts = parts.map do |part|
  4. ...
  5. end
  6. return new_parts.join(" ")

e.g.1 Write a method yell_sentence that takes in a sentence string and returns a new sentence where every word is yelled.

  1. def yell_sentence(sent)
  2. parts = sent.split(" ") # 先转换成array问题
  3. # 把array每个元素变换得到另一个array
  4. new_parts = parts.map do |part|
  5. part.upcase + "!"
  6. end
  7. return new_parts.join(" ")
  8. end

e.g.2 Write a method o_words that takes in a sentence string and returns new sentence with the words that contain an "o"

  1. def o_words
  2. parts = sent.split(" ") # 先转换成array问题
  3. # 把array每个元素变换得到另一个array
  4. new_parts = parts.select do |part|
  5. # check if word contain an "o"
  6. part.include?("o")
  7. end
  8. return new_parts.join(" ")
  9. end

2. Array | Range

如果不要求in-place修改,我们总是可以把string当做Array来处理,通过str.chars

2.1 把给定的Array 变换成另一个Array 的问题

2.1.1 输入一个array, 每个元素变换得到新的长度相同的array的问题,用arr.map或者arr.map.with_index.

  1. # 把array每个元素乘以2得到新array
  2. new_arr = arr.map do |ele|
  3. ele * 2 # 由旧ele得到新ele
  4. end
  5. # 把array每个元素乘以index得到新array
  6. new_arr = arr.map.with_index do |ele, idx|
  7. ele * idx .. # 由旧ele和旧idx 得到新ele
  8. end

e.g. Write a method map_by_key that takes in an array of hashes and a key string. The method should returns a new array containing the values from each hash for the given key.

  1. # input: array of hashes
  2. # output: array of hash[key]
  3. # array => new_array
  4. def map_by_key(arr)
  5. return arr.map do |hash|
  6. hash[key] # each hash => each hash[key]
  7. end
  8. end

2.1.2 输入一个array, 得到其中满足特定条件的元素的array的问题,用arr.select

  1. # Write a method, filter_lengths(strings, length), that accepts an array of strings
  2. # and a length as args. The method should return an array containing the strings
  3. # that have at least the given length. The length argument should be optional; if no length
  4. # is passed in, then 5 should be used as the length.
  5. def filter_lengths(strings, length=5)
  6. strings.select { |str| str.length >= length }
  7. end

2.2 求array内元素的互相组合

2.2.1 求array内元素的所有组合

  1. arr.each do |ele1|
  2. arr.each do |ele2|
  3. # do something about ele1 and
  4. end
  5. end

2.2.2 求array内元素的不重复组合

  1. arr.each_with_index do |ele1, idx1|
  2. arr.each_with_index do |ele2, idx2|
  3. if idx2 > idx1
  4. # do something about ele1 and ele2

2.3 2D Array, 可以看做每个element为array的一维array来处理

  1. arr.each do |subarr|
  2. subarr.each do |ele|
  3. # do something about ele
  4. end
  5. end

2.4 Array的聚合类问题,输入输出是n => 1的结构

2.4.1 由一组元素得出一个非boolean的结果

给定一组元素,得出一个非boolean的结果(boolean见2.5),通常是array元素同样的类型, 用array.inject

e.g. Write a method matrix_addition_reloaded that accepts any number of matrices as arguments. The method should return a new matrix representing the sum of the arguments. Matrix addition can only be performed on matrices of similar dimensions, so if all of the given matrices do not have the same "height" and "width", then return nil.

  1. def matrix_addition_reloaded(*matrices)
  2. matrix = matrices.first
  3. height = matrix.length
  4. width = matrix[0].length
  5. empty_matrix = Array.new(height) { [0] * width }
  6. matrices.inject(empty_matrix) do |m1, m2|
  7. return nil if m2.length != height or m2[0].length != width
  8. matrix_addition(m1, m2)
  9. end
  10. end

2.4.2 对一组元素做一个判断(boolean) 的问题

给定一组元素, 对某个事实做true or false判断的问题,可以认为是inject的特殊情况, 用:

全都是 / 只存在 => array.all? or (0..num).all

  1. # Write a method, `only_vowels?(str)`, that accepts a string as an arg.
  2. # The method should return true if the string contains only vowels.
  3. # The method should return false otherwise.
  4. def only_vowels?(str)
  5. vowels = "aeiou"
  6. str.split("").all? { |char| vowels.include?(char) }
  7. end

有没有 / 至少有一个 => array.any? or (0..num).any

  1. # Write a method, adult_in_group?(people), that accepts an array containing people.
  2. # The method should return true if there is at least 1 person with an age of 18 or greater.
  3. # The method should return false otherwise.
  4. def adult_in_group?(people)
  5. people.any? { |person| person[:age] >= 18 }
  6. end

完全没有 / 除去某个就没有了 => array.none? or (0..num).none

Write a method, coprime?(num_1, num_2), that accepts two numbers as args.
The method should return true if the only common divisor between the two numbers is 1.
The method should return false otherwise. For example coprime?(25, 12) is true because
1 is the only number that divides both 25 and 12.

  1. def coprime?(num_1, num_2)
  2. (2..num_1).none? { |factor| num_1 % factor == 0 && num_2 % factor == 0}
  3. end
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注