Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby Kattis电话列表,超出时间限制_Ruby_Algorithm - Fatal编程技术网

Ruby Kattis电话列表,超出时间限制

Ruby Kattis电话列表,超出时间限制,ruby,algorithm,Ruby,Algorithm,问题描述: 我的解决方案: # get phone list and return true if list consistent or false if not def consistent?(phone_list) index = 0 last_phone = phone_list.last phone_list.each do |phone| index += 1 unless last_phone == phone return true if p

问题描述:

我的解决方案:

# get phone list and return true if list consistent or false if not
def consistent?(phone_list)
  index = 0
  last_phone = phone_list.last
  phone_list.each do |phone|
    index += 1
    unless last_phone == phone
      return true if phone.length == last_phone.length
      return false if phone_list.drop(index).find { |ph| ph.start_with? phone }
    end
  end
  true
end
# read file and parse settings
input = File.open('phone.in', &:read).split("\n")
# input = STDIN.read.split("\n")
settings = input.slice!(0, 2).map(&:to_i)

error_t = 'Testcase numbers need to be in range 1 to 40.'
error_n = 'Phone numbers need to be in range 1 to 10000.'
error_p = 'Phonenumber is longer than 10 digits or less then 1.'
error_u = 'Phonenumbers set is not uniq'

STDERR.puts(error_t) if settings[0] < 1 || settings[0] > 40

# iterate throw input and agregate results to output
settings[0].times do
  STDERR.puts(error_n) if settings[1] < 1 || settings[1] > 10_000
  phone_set = input.slice!(0, settings[1])
  STDERR.puts(error_u) unless phone_set.uniq.length == phone_set.length
  result = consistent?(phone_set.sort_by do |phone|
    STDERR.puts(error_p) if phone.length > 10 || phone.empty?
    phone.length
  end)
  puts result ? 'YES' : 'NO'
  settings[1] = input.slice!(0).to_i
end
#获取电话列表,如果列表一致,则返回true;如果列表不一致,则返回false
def一致?(电话列表)
索引=0
last_phone=电话列表。last
电话列表。每个人都有电话|
指数+=1
除非最后一部电话==电话
如果phone.length==last_phone.length,则返回true
如果phone_list.drop(index),则返回false。使用?phone}查找{| ph | ph.start_
结束
结束
真的
结束
#读取文件和解析设置
input=File.open('phone.in',&:read).split(“\n”)
#输入=STDIN.read.split(“\n”)
设置=input.slice!(0,2).映射(&:to_i)
错误\u t='测试用例号需要在1到40之间。'
错误\u n='电话号码必须在1到10000之间。'
错误p='电话号码大于10位或小于1'
错误_='电话号码集不是uniq'
设置[0]<1 | |设置[0]>40时的标准输入(错误)
#迭代抛出输入并将结果放弃输出
设置[0]。时间是多少
如果设置[1]<1 | |设置[1]>10 | 000,则标准输出(错误)
phone_set=input.slice!(0,设置[1])
除非phone\u set.uniq.length==phone\u set.length,否则标准输入(错误)
结果=一致?(电话设置。按do排序|电话|
如果phone.length>10 | | phone.empty,则输入(错误p)?
电话长度
(完)
结果如何?”是:'否'
设置[1]=input.slice!(0)至
结束

我用。我被卡住了。如果您能帮助我改进算法,我将不胜感激。

瓶颈不是Ruby,而是算法。TLE的原因是因为以下代码

return false if phone_list.drop(index).find { |ph| ph.start_with? phone }
假设电话号码长度为O(L),电话号码为N,则之前代码的时间复杂度为O(NL),算法的总体复杂度为O(N^2L),当N为10000时,大型测试将失败


您应该尝试一些字符串数据结构,对于这个问题,这是一个很好的选择


首先对电话号码进行长度递减排序,然后逐个插入号码,如果某个号码没有创建新的树节点,则表示找到前缀,并返回false,否则返回true。它将复杂度降低到O(NlogN+NL)。根据问题L最多为10,它应该符合问题中的时间限制。

您可以按如下方式确定无法访问的数字

TO_DELETE = " ()-"

def unreachables(phone_list)
  phone_list.permutation(2).each_with_object([]) do |(f,s),arr|
    fd, sd = f.delete(TO_DELETE), s.delete(TO_DELETE)
    arr << f if fd[0,sd.size] == sd
  end
end

phone_list = ["213-749-6317", "(911) 749-6317", "12 37 63 21", "123", "911"]
unreachables phone_list
  #=> ["(911) 749-6317", "12 37 63 21"] 
enum1 = phone_list.permutation(2)
  #=> #<Enumerator: ["213-749-6317", "(911) 749-6317", "12 37 63 21", "123", "911"]
  #   :permutation(2)>
继续

enum2 = enum1.each_with_object([])
  #=> #<Enumerator: #<Enumerator: ["213-749-6317", "(911) 749-6317", "12 37 63 21",
  #   "123", "911"]:permutation(2)>:each_with_object([])> 
在最后一步中,
enum2
的第一个元素被传递到块并分配给块变量(通过并行或多重分配)是

因此,区块计算是可行的

fd = f.delete(TO_DELETE)
  #=> "2137496317" 
sd = s.delete(TO_DELETE)
  #=> "9117496317"
arr << f if fd[0,sd.size] == sd
  # arr << f if fd[0,10] == "9117496317"
  # arr << f if "2137496317" == "9117496317"
  # arr << f if false
  #=> nil
arr
  #=> []
fd=f.delete(删除)
#=> "2137496317" 
sd=s.delete(要删除)
#=> "9117496317"

啊,我不懒惰。在我花了2天时间完成这项任务后,我去寻求帮助。我认为这个网站是为这样的情况而创建的。这个网站是为那些可以自己写问题的用户而创建的,而不是为那些只链接到一个问题甚至不用自己解释的用户而创建的。谢谢你的帮助!我将尝试更改我的算法。
enum2.to_a
  #=> [[["213-749-6317", "(911) 749-6317"], []],
  #    [["213-749-6317", "12 37 63 21"], []],
  #    [["213-749-6317", "123"], []],
  #    ...
  #    [["911", "123"], []]] 

enum2.each do |(f,s),arr|
  fd, sd = f.delete(TO_DELETE), s.delete(TO_DELETE)
  arr << f if fd[0,sd.size] == sd
end
  #=> ["(911) 749-6317", "12 37 63 21"]    
(f,s),arr = enum2.next
  #=> [["213-749-6317", "(911) 749-6317"], []] 
f
  #=> "213-749-6317" 
s  
  #=> "(911) 749-6317" 
arr
  #=> [] 
fd = f.delete(TO_DELETE)
  #=> "2137496317" 
sd = s.delete(TO_DELETE)
  #=> "9117496317"
arr << f if fd[0,sd.size] == sd
  # arr << f if fd[0,10] == "9117496317"
  # arr << f if "2137496317" == "9117496317"
  # arr << f if false
  #=> nil
arr
  #=> []