You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

直方图代码解析与简化需求:理解Ruby直方图代码并求简洁实现方案

Hey there! Let's break down your histogram code step by step, then look at a cleaner implementation that does exactly the same thing.

How Your Original Code Works

Let's walk through each part to understand its logic:

  1. The histogram method:

    • It takes an array, a start/stop range, and a width parameter (chart).
    • Counts elements in the array that fall between start and stop (inclusive) using array.count { |array| array >= start && array <= stop }—quick note: naming the block variable array shadows the method's input parameter, which is confusing and could lead to bugs if you ever modify this code.
    • Converts the count to a string and right-justifies it to the specified chart width with rjust.
  2. Variable setup:

    • You initialize an empty array, plus control variables for the first interval (start=1, stop=10), formatting widths (range=1, found=3, chart=2), etc.
  3. Populating the data array:

    • You generate 200 random numbers between 1-100 and push them into the array. However, you call sort! every time you add a number—this is inefficient, since sorting 200 times does the same job as sorting once after all numbers are added, just with extra work.
  4. Generating the histogram output:

    • First, you print a header row to label the columns.
    • Then you print the first interval (1-10) with its count.
    • Next, you loop through every element in the sorted array:
      • When you hit an element larger than the current stop, you start a new interval (add 10 to both start and stop), print the new interval's label and count, then a *.
      • For elements within the current interval, you just print a *.
    • This works because the array is sorted, so all elements in one interval will print as *s before you hit the next interval's values.

Cleaner, More Efficient Implementation

Here's a refactored version that matches your original code's functionality perfectly, but with better readability, fewer quirks, and better performance:

# Helper to count elements in a range (no variable shadowing!)
def count_in_range(array, start, stop)
  array.count { |elem| elem.between?(start, stop) }
end

# Initialize variables with clear, descriptive names
sample_size = 200
max_value = 100
interval_size = 10
count_display_width = 2
label_alignment_width = 3

# Generate all random numbers first, then sort ONCE (way more efficient)
data = Array.new(sample_size) { rand(1..max_value) }.sort

# Print formatted header
puts " Range #Found Chart"
puts " ------- ------ ------------------------------"
puts

# Iterate directly over each 10-number interval
(1..max_value).step(interval_size) do |start|
  stop = start + interval_size - 1
  element_count = count_in_range(data, start, stop)
  
  # Format the range label to match your original output alignment
  range_label = "#{start.to_s.rjust(label_alignment_width)} - #{stop.to_s.rjust(label_alignment_width)}"
  
  # Print the full row: range | count | stars
  puts "#{range_label} |#{element_count.to_s.rjust(count_display_width)}| #{'*' * element_count}"
end

What Makes This Better?

  • No variable shadowing: The helper uses elem instead of reusing array for the block variable, eliminating confusion.
  • Faster performance: We sort the array once after generating all numbers, not after every single push—this cuts down on unnecessary computation.
  • Self-documenting code: Variable names like sample_size and interval_size make it clear what each value does, unlike vague original names like range or found.
  • Straightforward interval logic: Instead of looping through every element to trigger new intervals, we explicitly iterate over each 10-number range with step. This is easier to read and debug.
  • Simpler star generation: We create the star string directly from the count ('*' * element_count) instead of looping through every element to print individual *s.

Does This Match Your Original Output?

Absolutely! It generates the exact same histogram: 200 random 1-100 numbers, grouped into 10-number intervals, with right-aligned counts and a * for each element in the interval.

内容的提问来源于stack exchange,提问作者MIkeSmith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:52:32