ใน Ruby ฉันจะสร้างข้อความซ้ำหลายสายได้อย่างไร


138

วิธีที่ดีที่สุดในการสร้างสายยาวอย่างรวดเร็วในทับทิมคืออะไร? ใช้งานได้ แต่ช้ามาก:

str = ""
length = 100000
(1..length).each {|i| str += "0"}

ฉันได้สังเกตเห็นด้วยว่าการสร้างสตริงที่มีความยาวพอเหมาะแล้วต่อท้ายไปยังสตริงที่มีอยู่จนถึงความยาวที่ต้องการนั้นจะทำงานได้เร็วขึ้นมาก:

str = ""
incrementor = ""
length = 100000
(1..1000).each {|i| incrementor += "0"}
(1..100).each {|i| str += incrementor}

ข้อเสนอแนะอื่น ๆ ?


1
วิธีที่ดีที่สุดคือใช้ JRuby และใช้ StringBuffer Oooooh
Jonathan Feinberg

คำตอบ:


307
str = "0" * 999999

22
แท้จริงแล้วแปลกมากดูความแตกต่างและรูปลักษณ์ที่งดงามใน Python str = "0" * 999999
:;

1
ทำไมลำดับจึงสำคัญกับทับทิม เมื่อฉันจะ99999 * "0"ได้รับTypeError: String can't be coerced into Fixnum
Steven

16
@Steven จากมุมมองของรูบี้, "0" * 999999จะถือว่าเป็น"0".*(999999)ที่*เป็นวิธีการในส่วนStringชั้น วิธีการนั้นยอมรับตัวเลขเป็นอาร์กิวเมนต์ที่ถูกต้องเพื่อทำการจำลองแบบสตริง 999999.*("0")เมื่อคุณกลับแสดงออกที่เราได้รับ ตอนนี้เรากำลังพูดถึง*วิธีการในFixNumชั้นเรียนและวิธีการที่ปฏิเสธที่จะใช้สตริงเป็นข้อโต้แย้ง แน่นอนว่ามันสามารถทำได้ (เช่นทำให้ดีที่สุดโดยอัตโนมัติในการแปลงการโต้แย้งเป็น FixNum) แต่นักออกแบบภาษาตัดสินใจที่จะยอมรับแรงบันดาลใจของรูบี้ Perlish อย่างเต็มที่
FMc

11

อีกตัวเลือกที่ค่อนข้างรวดเร็วคือ

str = '%0999999d' % 0

แม้ว่าการเปรียบเทียบ

require 'benchmark'
Benchmark.bm(9)  do |x|
  x.report('format  :') { '%099999999d' % 0 }
  x.report('multiply:') { '0' * 99999999 }
end

แสดงว่าการคูณยังเร็วกว่า

               user     system      total        real
format  :  0.300000   0.080000   0.380000 (  0.405345)
multiply:  0.080000   0.080000   0.160000 (  0.172504)

ฉันชอบคำตอบนี้ แต่ฉันไม่สามารถทำให้มันทำงานอะไรได้นอกจาก '0' ฉันจะทำอย่างไรถ้าฉันต้องการ 100 r's?
พัฒนาของคุณ

2
มันจะไม่ทำงานกับสัญลักษณ์อื่น ๆ เพราะใช้ประโยชน์จากการใส่ตัวเลขในสตริงรูปแบบ ตัวเลขสามารถถูกเติมด้วย 0 ที่ด้านหน้าหรือด้านหลัง (สำหรับทศนิยม) โดยไม่มีการเปลี่ยนแปลงค่า r ไม่ทำงานเช่นนั้น
Andrew
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.