@smilence
2020-02-28T02:23:31.000000Z
字数 5806
阅读 1295
Ruby SDE-Foundations
Collection 包括
String,Array,Hash
String没有对应的函数,那么除非有in-place处理的要求,总是可以用str.chars或者str.split("")把String的问题转化成Array的问题
e.g.def caesar_cipher(message, n)alphabet = ("a".."z").to_anew_message = ""new_chars = message.chars.map do |char|old_index = alphabet.index(char)new_char = (old_index != nil ? alphabet[(old_index + n)%26] : char)new_charendreturn new_chars.join("")end
sentence中包含多个词,用空格隔开,处理每个词
处理这样的string, 总是通过str.split(" ")把问题转换成array问题 (array of strings), 然后对array进行遍历 (arr.each/ arr.each_with_index / arr.map) 处理每个分隔开的word.
通过str.split(" ")把问题转换成array问题 (array of strings), 然后把array用array.map变换成新array new_arr, 最后再用new_arr.join(" ")转回为string
words = str.split(" ")# 把parts按照题意转换成目标arraynew_words = words.map do |part|new_word = ...new_wordendreturn new_Words.join(" ")
n => 1的结构boolean的结果给定一组元素,得出一个非boolean的结果(boolean见2.2),通常是array元素同样的类型, 用array.inject 由acc和ele得到new_acc再结算
e.g. Write a method
matrix_addition_reloadedthat 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.
def matrix_addition_reloaded(*matrices)return matrices.inject() do |acc, m|return nil if acc.length != m.length || acc[0].length != m[0].lengthmatrix_addition(acc, m)endend
boolean) 的问题给定一组元素, 对某个事实做true or false判断的问题,可以认为是inject的特殊情况, 用:
全都是 / 只存在 => array.all? or (0..num).all
# Write a method, `only_vowels?(str)`, that accepts a string as an arg.# The method should return true if the string contains only vowels.# The method should return false otherwise.def only_vowels?(str)vowels = "aeiou"str.split("").all? { |char| vowels.include?(char) }end
def is_sorted(arr)(0...arr.length - 1).all? { |i| arr[i] <= arr[i + 1] }end
有没有 / 至少有一个 => array.any? or (0..num).any
# Write a method, adult_in_group?(people), that accepts an array containing people.# The method should return true if there is at least 1 person with an age of 18 or greater.# The method should return false otherwise.def adult_in_group?(people)people.any? { |person| person[:age] >= 18 }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 examplecoprime?(25, 12)is true because 1 is the only number that divides both 25 and 12.
def coprime?(num_1, num_2)(2..num_1).none? { |factor| num_1 % factor == 0 && num_2 % factor == 0}end
对于需要比较或者交换前后元素的情况,用
(0...arr.length-1)配合arr[idx]比直接用arr.each.with_index更好, 因为有时候我们需要去掉头尾的部分. 如果头尾具有特殊性,则对头尾和中间元素 ((1...arr.length-1))分开处理.
def peak_finder(arr)peaks = []return [] if arr.length == 0if arr.length > 0 && arr[0] > arr[1]peaks << arr[0]end(1...arr.length-1).each do |idx|if arr[idx] > arr[idx-1] && arr[idx] > arr[idx+1]peaks << arr[idx]endendif arr.length > 0 && arr[-1] > arr[-2]peaks << arr[-1]endreturn peaksend
arr[idx] != arr[idx+1]时清算之前段,并且reset这个变量。注意变量的初始值应该把每段的第1个元素考虑在内,即count = 1。idx == nums.length-1
e.g. # p compress_str("aaabbc") # => "3a2bc"def compress_str(str)return str if str.empty?count = 1new_str = ""(0...str.length).each do |idx|if idx != str.length - 1 && str[idx] == str[idx+1]count += 1elsenew_str += count == 1 ? str[idx] : count.to_s + str[idx]count = 1endendreturn new_strend
# 674. Longest Continuous Increasing Subsequencedef find_length_of_lcis(nums)return 0 if nums.empty?max_count, count = 1, 1(0...nums.length).each do |idx|# 可以认为越界元素一定不会满足条件if idx != nums.length-1 && nums[idx] < nums[idx+1]count += 1elsemax_count = count if count > max_countcount = 1endendreturn max_countend
可以用一个变量completed = false, 然后用completed这个boolean变量去记录每一轮的情况,直到completed为true
completed = falseuntil completedcompleted = true # 默认这一轮completed为true(0...arr.length).each do |idx|# 处理每一个arr[idx]if condition 满足一定条件下# 修改arr[idx]completed = falseendendendreturn arr
e.g. bubble sortdef bubble_sort(array)sorted = falseuntil sortedsorted = true(0...array.length - 1).each do |i|if array[i] > array[i + 1]array[i], array[i + 1] = array[i + 1], array[i]sorted = falseendendendreturn arrayend
用array.select,block里输出需要满足的条件。如果只需要元素的数量,则可以用arr.count
这类问题适合单独用一个函数实现(因为找到后可能需要立即退出查找),用变量idx = 0或idx = arr.length-1, 用while循环找到,即返回.
def hipsterfy(word)vowels = "aeiou"i = word.length - 1while i >= 0if vowels.include?(word[i])return word[0...i] + word[i+1..-1]endi -= 1endwordend
例如找因子, 找公因子, 找质数, 这类问题等同于在collection中查找的问题。
(1..num).each来逐个检查
def is_prime?(num) # 实际上是查找因子return false if num <= 1(2..num).each do |n|return false if num % n == 0endreturn trueend
while result <= num和i += 1来逐个检查
def perfect_square?(num)i = 1square = nilwhile square <= numsquare = i * ireturn true if square == numi += 1endreturn falseend
def power_of_two?(num)return true if num == 1result = 1while result <= numresult = result * 2return true if result == numendreturn falseend
通常这类问题都不能用select因为我们并不知道元素所处的范围
从idx = 0开始,
查找第n个元素,用一个count = 0来记录元素的数量,until count == n
查找前n个元素,用一个array = []来记录所有元素,until array.length == n
在循环内,idx递增,每次找到都记录给count或者array
def nth_prime(n)count = 0num = 1until count == nnum += 1if is_prime?(num)count += 1endendnumend
检查一个Collection是否对称,或者对一个Collection进行反转,用头尾i = 0, j = arr.length - 1两个marker,以及while i < j相向而行。然后每次都对arr[i]和arr[j]进行比较或者交换。
e.g.def palindrome?(string)i, j = 0, string.length - 1while i < jreturn false if string[i] != string[j]i += 1j -= 1endreturn trueend
arr.each_with_index do |ele1, idx1|arr.each_with_index do |ele2, idx2|if idx2 > idx1# do something about ele1 and ele2
e.g.def substrings(string)subs = [](0...string.length).each do |start_idx|(0...string.length).each do |end_idx|subs << string[start_idx..end_idx] if start_idx <= end_idxendendsubsend
例如是否unique,是否duplicate,两个collection元素是否相同,一般可以新建一个Hash.new作为counter,然后对collection进行循环的同时,检查 counter内已有的记录,并且记录新的元素。
def unique_chars?(string)hash = Hash.new(0)string.each_char do |char|return false if hash.has_key?(char)hash[char] += 1endtrueend