程序码要能让电脑读懂,一定会有一个转译过程。
编译
(Compiled language):将所有程序码通过编译器(compiler),编译成电脑看得懂的机器码,也就是0与1後,再一起执行。
.exe
档,mac的可执行档。C
,C++
等。直译
(Interpreted language)或称解译:程序码执行时,一行一行的由解译器(interpreter)转换成机器码,并且执行。
Ruby
,Python
,Javascript
。强弱型别语言最易之区分为,程序是否对资料型态自动转换的程度,较高者为弱型别,较弱者为强型别。
例如:
//JavaScript
Welcome to Node.js v14.15.5.
Type ".help" for more information.
> 123 + "456"
'123456'
//型别自动转换
反之:
#Ruby
2.7.3 :001 > 123 + "456"
TypeError (String can't be coerced into Integer)
#型别无法转换
#需更改如下
2.7.3 :002 > 123.to_s + "456"
=> "123456"
2.7.3 :003 > 123 + "456".to_i
=> 579
弱型别:型别处理感觉上较宽松,较容许资料隐性型别直接转换。优点在於执行较快,但若未注意型别,可能会得到错误的资料。
强型别:型别处理感觉上较严谨,较不容许资料隐性型别直接转换。优点在於资料型别区分清楚,但执行上较慢。
但不是绝对强型或绝对弱型,是比较级的。
动态型别语言
如之前程序码示范,於执行阶段,会藉由to_i
这类程序码,由解译器协助转换型别(於执行期检查型别),相对转换资料类别的方法(函式,功能)较多。
wiki
动态程序语言是高阶程序语言的一个类别,在电脑科学领域已被广泛应用。它是一类在执行时可以改变其结构的语言:例如新的函式、物件、甚至代码可以被引进,已有的函式可以被删除或是其他结构上的变化。动态语言目前非常具有活力。众所周知的ECMAScript(JavaScript)便是一个动态语言,除此之外如PHP、Ruby、Python等也都属於动态语言,而C、C++、Java等语言则不属於动态语言。
静态型别语言
则是在编译阶段检查型别。
并不是动态语言就一定是强型别,也不是静态语言就一定弱型别,wiki引言内的PHP即为动态弱型别语言,Ruby则是强型别动态型语言。依照这些特性,与昨日介绍的鸭子型别介绍,前日的Ruby设计风格,可以知道Ruby的优点是较自由、口语化、类别分类清楚、且有较多语法可针对资料类型直接做转换处理。
虽然不是刷题刷得多,一定找得到工作,但是知道的越多,要用时才不用找半天,今天继续分享能感觉到语法懂得多是好处的题型。
Leetcode258.Add Digits
题目连结:https://leetcode.com/problems/add-digits/
题目重点:需要重复处理资料至单个数字为止。
我自己会习惯整理到自己的开发工具内,例如:
# @param {Integer} num
# @return {Integer}
def add_digits(num)
end
puts add_digits(38) #=> 2
puts add_digits(0) #=> 0
但建议能习惯於直接在Leetcode上直接操作较好。
题目需要每个数字相加。
2.7.3 :005 > 3 + 8
=> 11
#大於10,要继续处理。
2.7.3 :006 > 1 + 1
=> 2
#将Integer拆成每个数字分开的状态
2.7.3 :032 > 38.to_s.split""
=> ["3", "8"] #喔,还要变成数字...
2.7.3 :034 > ["3", "8"].map {|str|str.to_i}
=> [3, 8]
#再将数字相加後判断是否大於2位数(所以是大於9)
2.7.3 :035 > [3, 8].sum
=> 11
#如果是重复处理,就再如第一条重复处理。
2.7.3 :037 > 11.to_s.split""
=> ["1", "1"]
2.7.3 :038 > ["1", "1"].map {|str|str.to_i}
=> [1, 1]
2.7.3 :039 > [1, 1].sum
=> 2
整理後如下。
def add_digits(num)
num = num.to_s.split""
num = num.map {|str| str.to_i}.sum
num > 9 ? add_digits(num) : num
end
但是如果认识digits
这个语法
def add_digits(num)
num = num.digits.sum
num > 9 ? add_digits(num) : num
end
2.7.3 :056 > 38.digits
=> [8, 3]
补充
#利用正整数的除9的余数 == 正整数每个数相加到最後这个原理
def add_digits(num)
num == 0 ? 0 : (num%9 == 0 ? 9 : num%9)
end
def
if num == 0
0
elsif num%9 == 0
9
else
num%9
end
个人还是喜欢用digits
,Integer.digits => 数字的数字们,真的很口语化。
再一题显示多了解语法的好处。
Leetcode283.Move Zeroes
题目连结:https://leetcode.com/problems/move-zeroes/
题目重点:要求不做一个新Array。
def move_zeroes(nums)
end
puts move_zeroes([0,1,0,3,12]) #=> [1,3,12,0,0]
puts move_zeroes([0]) #=> 0
这题是可以用快慢指针解法,我先换一个小一点的例子。
* #检查用的指针
[0, 1, 0, 1]
$ #标记用的指针
先检查第一个数值是0,那我先不动它,标记它是0。
* #检查指针
[0, 1, 0, 1]
$ #零在这里喔
检查第二个。
* #检查指针到第二个位置了
[0, 1, 0 ,1]
$
发现不是零,那要交换。
* #检查指针
[1, 0, 0 ,1]
$ #Array中,位置+1 就交换了,所以检查指针是零时标记指针不动,不是零时+1。
继续往前检查。
* #检查指针
[1, 0, 0 ,1]
$ #零在这里喔
是零,那检查指针往前。
* #检查指针
[1, 0, 0 ,1]
$ #零在这里喔
不是零,跟标记的零交换吧。
*
[1, 1, 0, 0]
$ #标记位置+1
检查指针跑完了,也排完了。
#原谅我打字累了,我直接整理吧
def move_zeroes(nums)
pointer_fast = 0
pointer_slow = 0
for pointer_fast in 0..(nums.size-1) do
if nums[pointer_fast] != 0
nums[pointer_fast], nums[pointer_slow] = nums[pointer_slow], nums[pointer_fast]
pointer_slow += 1
end
end
nums
end
换成map.with_index,也感觉没简单很多。
def move_zeroes(nums)
slow = 0
nums.map.with_index do |num, index|
if num != 0
nums[index], nums[slow], = nums[slow], nums[index]
slow += 1
end
end
end
试试口语化的Ruby语法吧
def move_zeroes(nums)
# 我要知道我有几个零
# 把数列中的零都去掉後
# 从阵列後面加回去
end
def move_zeroes(nums)
zero_count = nums.count(0)
nums.delete(0)
zero_count.times {nums.push(0)}
end
#简单易懂许多
这还不够简单,就试试大神分享的咒语吧!
def move_zeroes(nums)
#阵列呀,依照0是比较大的往後排吧!
end
def move_zeroes(nums)
nums.sort_by! { |num| num.zero? ? 1 : 0 }
end
我又开始不正经了
没有错,在一开始,除非刚好看过,怎麽可能知道利用sort_by
。
没有练习,只有看,可能看完一个class内所有方法时,前一个class的方法就都忘光了。
所以只有练习再练习,没看过的神奇语法,就去了解怎麽用。
多用几次,就会是自己的了。
首先sort_by
与sort_by!
的差异
2.7.3 :058 > str = ["abc", "ab", "a"]
=> ["abc", "ab", "a"]
2.7.3 :059 > str.sort_by {|s|s.length}
=> ["a", "ab", "abc"]
2.7.3 :060 > str
=> ["abc", "ab", "a"]
#可以发现,虽然有回传["a", "ab", "abc"],但str本身并无改变。
2.7.3 :061 > str.sort_by! {|s|s.length}
=> ["a", "ab", "abc"]
2.7.3 :062 > str
=> ["a", "ab", "abc"]
#多了!後str自身改变了。
再来将程序码改回用do...end
,以及不用三元运算子
[0,1,0,3,12].sort_by! do |num|
if num == 0
1
else
0
end
end
=> [1, 3, 12, 0, 0]
#依照如果0给1这个比较大的值,不是0的给与0这个比较小的值,依照给予的值来排列。
#即使是写
2.7.3 :071 > [0,1,0,3,12].sort_by! {|nun|nun.zero? ? 999:9}
=> [1, 3, 12, 0, 0]
#也是一样的意思,只是这样写会被念....
如果还是看不懂,没关系,那我们再多看看程序码。
2.7.3 :081 > [5, 2, 7, 8, 3, 1].sort
=> [1, 2, 3, 5, 7, 8]
#sort语法本身就是依照值的大小排
2.7.3 :082 > [5, 2, 7, 8, 3, 1].sort_by {|num| num}
=> [1, 2, 3, 5, 7, 8]
#sort_by,很直觉感觉就是可以依照我们指定的规则来排序,没有就是依照原本小到大的规则。
nums.sort_by! { |num| num.zero? ? 1 : 0 }
# if == 0 那就给你比较大的值 1,if != 0 那就给你比较小的值 0。
#即使改写如下,一样的意思,规则定好枚举方法,block内就会是你的许愿池
2.7.3 :084 > [0,1,0,3,12].sort_by! {|nun| nun != 0 ? 0 : 1}
=> [1, 3, 12, 0, 0]
1.Ruby是直译,动态类型,强型别语言。
2.Ruby真好玩,快来学!
明日开始对Ruby更好玩的部分block
做说明,一样会尽量以实作取代说明。
>>: [Day03] CH02:告诉我你是谁——变数的宣告
前面中场休息的 Project 今天暂且休一天,来介绍一下可以在 JavaScript 跟 Type...
float称为浮动元素,可以想像是加上这个元素的物体都会飘浮在空中 接下来示范一些用法来认识这个元素...
object---物件(东西)、概念,宇宙间任何具体的东西或抽象的事物 物件导向(object-or...
context的内容: sub_dual = [{'start':1, 'end':2, 'text...
大家好,我们的基因体时代是我之前一直在经营的部落格名称,假如对於生物资讯、合成生物学、基因体学、资料...