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

Ruby中动态提取数组最长公共前缀的实现问题

Solution: Dynamic Longest Common Prefix Grouping

Got it, let's fix this properly! Your current code hardcodes an 8-character prefix, which doesn't handle the dynamic requirement of finding the longest shared prefix (≥8 characters) for groups of two or more elements. Here's a step-by-step solution tailored to your examples:

Step 1: Helper Functions

First, we need utility functions to calculate common prefixes:

# Calculate the longest common prefix between two strings
def longest_common_prefix(a, b)
  idx = 0
  while idx < a.length && idx < b.length && a[idx] == b[idx]
    idx += 1
  end
  a[0...idx]
end

# Calculate the longest common prefix for an entire group of strings
# Returns nil if the prefix is shorter than 8 characters
def group_longest_common_prefix(strings)
  return nil if strings.empty?
  current_prefix = strings[0]
  strings[1..-1].each do |s|
    current_prefix = longest_common_prefix(current_prefix, s)
    break if current_prefix.length < 8 # No need to check further if prefix is too short
  end
  current_prefix.length >= 8 ? current_prefix : nil
end

Step 2: Process Each Subarray

Next, we'll write a function to process each subarray, grouping elements by their valid long common prefixes and replacing groups with their prefix:

def process_subarray(subarray)
  label = subarray[0]
  numbers = subarray[1..-1].dup
  result = []

  until numbers.empty?
    # Grab the first number and find all others that share a long enough prefix with it
    current_num = numbers.shift
    group = [current_num]
    
    # Collect all matching numbers (remove them from the original list as we go)
    numbers.each_with_index do |num, idx|
      lcp = longest_common_prefix(current_num, num)
      if lcp.length >= 8
        group << num
        numbers.delete_at(idx)
      end
    end

    # Get the longest valid prefix for the group, or keep the original number if no valid prefix
    group_prefix = group_longest_common_prefix(group)
    result << (group_prefix || current_num)
  end

  # Combine label with results, removing duplicate prefixes if any
  [label] + result.uniq
end

Step 3: Run the Solution

Apply the processing function to your input arrays:

Example 1

m = [ ["A", "97455589955", "97455589920", "97455589921"], ["B", "2348045101518", "2348090001559"] ]
n = m.map { |sub| process_subarray(sub) }
p n
# Output: [["A", "974555899"], ["B", "2348045101518", "2348090001559"]]

Example 2

m2 = [ ["A", "2491250873330", "249111222333", "2491250872214", "2491250872213"], ["B", "221709900000"], ["C", "6590247968", "6590247969", "6598540040", "65985400217"] ]
n2 = m2.map { |sub| process_subarray(sub) }
p n2
# Output: [["A", "2491250873330", "249111222333", "249125087221"], ["B", "221709900000"], ["C", "659024796", "65985400"]]

How It Works

  • For each subarray, we iterate through the numbers, grouping together any that share a common prefix of 8+ characters.
  • Each group is replaced by its longest valid common prefix (not just a fixed 8 characters).
  • Numbers that don't share a valid prefix with any other number are kept as-is.
  • Duplicate prefixes are removed to keep the result clean (like if multiple groups accidentally generate the same prefix).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:13:09