โจทย์ข้อสองตามมา
ให้แปลง Numeric เป็น String ที่มี comma คั้นแต่ละ 3 digits หน้าจุดทศนิยม
ตัวอย่างเช่น
ให้ 19999999999.55 แปลงเป็น “19,999,999,999.55”
ให้ 19999995.99 แปลงเป็น “19,999,995.99”
โค้ดสำหรับ benchmark
require 'benchmark' ITERATION = 500 def measure(fls,&block) ITERATION.times { block.call } end fls = [] 400.times do fls << sprintf("%0.2f",rand() * (10**11)).to_f end br = Benchmark.bmbm do |b| b.report("Running #{ITERATION} iterations") do measure(fls) { fls.each do |t| # ใส่โค้ดเพื่อทดสอบตรงนี้ end } end end
กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น
ในที่สุดก็มา ขอลุยคนแรกเลยละกันครับ
พยายามจะเขียนในบรรทัดเดียวเลยออกมาประหลาด ๆ
ท่าทางเรื่องเวลาคงไม่ต้องพูดถึง ช้าแหงเลย >_<
reverse ตั้งสองที แถมยังใช้ scanด้วย
แอบแก้ให้ครับ มี bug นิดนึง
โอ้ ขอบคุณ sikachu ครับ ผมลืม .to_s ของอันที่สองไป คือตอนแรกผมไม่ได้อ่านว่า input มาเป็นตัวเลข >_< เลยแก้รอบนึง ใส่ .to_s แต่ดันลืมใส่ให้ตัวที่สองแฮะ ขอบคุณที่เตือนและแก้ให้ครับ
RESULT: 3.374971
ชอบตรง reverse :)
ขอให้เร็วด้วยเถิดดดด
ปล. ระวัง overflow นะครับ เลข float น่ะ :)
ผมว่าเร็วแหง อย่างน้อยก็ทำเวลาดีกว่าของผมชัวร์ๆ >_<
RESULT: 2.046558
เร็วได้ใจ !!
เร็วจริง ๆ ตามคาด (>_<)b
ใน regexp มันมี feature ที่เรียกว่า lookaround อยู่
เราสามารถนำ lookahead กับ lookbehind มาใช้ implement feature นี้ได้
แต่ปัญหาก็คือ เจ้า ruby 1.8 ไม่มี feature lookbehind (อยากให้มีก็ได้ แต่ต้องออกแรง patch หน่อย)
เริ่มด้วยการใช้ ruby 1.9 ก่อน
?<= คือ lookbehind
?= คือ lookahead
ความหมายของข้างบนคือ หาตำแหน่งที่มีเลขสามตัวอยู่ด้านขวา และมีเลขหนึ่งตัวอยู่ด้านซ้าย
จากนั้นก็แทนที่ด้วย comma
ส่วน ruby 1.8 เนื่องจากไม่มี lookbehind แต่เราก็สามารถ work around ได้แบบนี้
เนื่องจาก ตัวเลขที่อยู่ด้านซ้าย (ของตำแหน่งคอมมา) เราไม่สามารถใส่ lookbehind ได้
เราก็เลยใส่ตัวเลขจริงๆไปเลย ซึ่งจะเกิดปัญหาว่า regexp มัน consume ตัวเลขตัวนั้นไป
เราก็เลยต้องใช้ block + gsub เพื่อใส่ตัวเลขที่โดน consume กลับเข้ามาพร้อมกับเครื่องหมาย comma
Note: pattern ข้างบนไม่ support จำนวนเต็มที่ไม่มีจุดทศนิยม
เนียนสุดๆ
RESULT: 3.669626
ป.ล. ผมลองรัน benchmark เฉพาะโค้ดสำหรับ 1.8 ครับ
ผมพอจะรู้conceptพวก look behind/ahead จากตอนเรียน แต่ไม่เคยได้ใช้เลย ความรู้ใหม่เหมือนกันครับ ขอบคุณพี่ป๊อกครับ >_<
ลองใช้ look-ahead ดูบ้าง บน 1.8 ผมใช้ reverse ช่วย
มองกลับด้าน มีตัวเลขสามตัวทางซ้าย แล้ว look-ahead มีตัวเลขทางขวาอย่างน้อยหนึ่งตัว และไม่มีจุดอยู่ทางขวา
RESULT: 2.135641
เดินสายกลาง
เสียวแว๊บบบ เลย ๕๕๕๕
ขอโหวต style winner ให้อันนี้ละกัน 55+ RegEx เข้าใจไม่ยากเกินไป + ใช้ method reverse ดูง่าย
รีบโหวตจะได้หาข้อต่อไปมาเล่นต่อ
โหวดด้วยคนคร๊าบ