Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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 如何在表达式中分布元素?_Ruby_Algorithm_Distribution - Fatal编程技术网

Ruby 如何在表达式中分布元素?

Ruby 如何在表达式中分布元素?,ruby,algorithm,distribution,Ruby,Algorithm,Distribution,给出一个表达式: (A OR B) AND (C OR D) AND (X OR Y OR Z) 我需要分发和生成组合ACX,ACY,ACZ,ADX,ADY,ADZ,BCX,BCY,BCZ,BDX,BDY和BDZ。我们有一个用户界面,用户使用它来生成上述表达式。在后端,我们需要生成不同的组合,以便更容易地匹配一组元素,如ACX、ACY等 具有and的组的数量不是固定的,每个and组中的元素大小也不同 你对如何完成这项工作有什么想法?我试图用递归来编写它,看看其他人是否有更聪明的答案,或者是否存

给出一个表达式:

(A OR B) AND (C OR D) AND (X OR Y OR Z)
我需要分发和生成组合
ACX
ACY
ACZ
ADX
ADY
ADZ
BCX
BCY
BCZ
BDX
BDY
BDZ
。我们有一个用户界面,用户使用它来生成上述表达式。在后端,我们需要生成不同的组合,以便更容易地匹配一组元素,如ACX、ACY等

具有and的组的数量不是固定的,每个and组中的元素大小也不同


你对如何完成这项工作有什么想法?我试图用递归来编写它,看看其他人是否有更聪明的答案,或者是否存在库。

这不是完整的方法,但我将使用递归慢慢地实现这一点。给我点时间

a1 = ['A','B']
a2 = ['C','D'] 
a3 = ['X','Y','Z']

a1.product(a2).product(a3)
# => [[["A", "C"], "X"],
#     [["A", "C"], "Y"],
#     [["A", "C"], "Z"],
#     [["A", "D"], "X"],
#     [["A", "D"], "Y"],
#     [["A", "D"], "Z"],
#     [["B", "C"], "X"],
#     [["B", "C"], "Y"],
#     [["B", "C"], "Z"],
#     [["B", "D"], "X"],
#     [["B", "D"], "Y"],
#     [["B", "D"], "Z"]]
以下是完整的解决方案(我使用
数组
作为数据结构,以按照您的要求保留所有结果组合):

更简单的方法是:

a1.product(a2,a3).map(&:join)
# => ["ACX",
#     "ACY",
#     "ACZ",
#     "ADX",
#     "ADY",
#     "ADZ",
#     "BCX",
#     "BCY",
#     "BCZ",
#     "BDX",
#     "BDY",
#     "BDZ"]

这并不是完整的方法,但我将使用。给我点时间

a1 = ['A','B']
a2 = ['C','D'] 
a3 = ['X','Y','Z']

a1.product(a2).product(a3)
# => [[["A", "C"], "X"],
#     [["A", "C"], "Y"],
#     [["A", "C"], "Z"],
#     [["A", "D"], "X"],
#     [["A", "D"], "Y"],
#     [["A", "D"], "Z"],
#     [["B", "C"], "X"],
#     [["B", "C"], "Y"],
#     [["B", "C"], "Z"],
#     [["B", "D"], "X"],
#     [["B", "D"], "Y"],
#     [["B", "D"], "Z"]]
以下是完整的解决方案(我使用
数组
作为数据结构,以按照您的要求保留所有结果组合):

更简单的方法是:

a1.product(a2,a3).map(&:join)
# => ["ACX",
#     "ACY",
#     "ACZ",
#     "ADX",
#     "ADY",
#     "ADZ",
#     "BCX",
#     "BCY",
#     "BCZ",
#     "BDX",
#     "BDY",
#     "BDZ"]

如果你是说
作为逻辑连接词
,那么这是不可能的。

表达式
(A或B)和(C或D)以及(X或Y或Z)
具有特定的单个值。你不能进入它。

如果你指的是
作为逻辑连接词
,那么这是不可能的。
表达式
(A或B)和(C或D)以及(X或Y或Z)
具有特定的单个值。你无法进入它。

试试:

AB = %w[A B]
CD = %w[C D]
XYZ = %w[X Y Z]

AB.product(CD, XYZ).join(&:map)
返回如下数组:

[
  "ACX",
  "ACY",
  "ACZ",
  "ADX",
  "ADY",
  "ADZ",
  "BCX",
  "BCY",
  "BCZ",
  "BDX",
  "BDY",
  "BDZ"
]
Ruby的文档说:

------------------------------------------------------------------------------
  ary.product(other_ary, ...)                -> new_ary
  ary.product(other_ary, ...) { |p| block }  -> ary


------------------------------------------------------------------------------

Returns an array of all combinations of elements from all arrays. The length of
the returned array is the product of the length of self and the argument
arrays. If given a block, product will yield all combinations and
return self instead.

  [1,2,3].product([4,5])     #=> [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
  [1,2].product([1,2])       #=> [[1,1],[1,2],[2,1],[2,2]]
  [1,2].product([3,4],[5,6]) #=> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
                             #    [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
  [1,2].product()            #=> [[1],[2]]
  [1,2].product([])          #=> []
您的问题特别感兴趣的是第三个示例。

试试:

AB = %w[A B]
CD = %w[C D]
XYZ = %w[X Y Z]

AB.product(CD, XYZ).join(&:map)
返回如下数组:

[
  "ACX",
  "ACY",
  "ACZ",
  "ADX",
  "ADY",
  "ADZ",
  "BCX",
  "BCY",
  "BCZ",
  "BDX",
  "BDY",
  "BDZ"
]
Ruby的文档说:

------------------------------------------------------------------------------
  ary.product(other_ary, ...)                -> new_ary
  ary.product(other_ary, ...) { |p| block }  -> ary


------------------------------------------------------------------------------

Returns an array of all combinations of elements from all arrays. The length of
the returned array is the product of the length of self and the argument
arrays. If given a block, product will yield all combinations and
return self instead.

  [1,2,3].product([4,5])     #=> [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
  [1,2].product([1,2])       #=> [[1,1],[1,2],[2,1],[2,2]]
  [1,2].product([3,4],[5,6]) #=> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
                             #    [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
  [1,2].product()            #=> [[1],[2]]
  [1,2].product([])          #=> []

您的问题特别感兴趣的是第三个示例。

您可以使用递归下降解析器在一般情况下处理此问题:

def expression(stream)
  ret = primary(stream);
  while stream.length > 0 && stream[0] != ")"
    token = stream.shift
    if token == "AND"
      ret = ret.product(primary(stream)).map(&:join)
    elsif token == "OR"
      ret += primary(stream);
    elsif token == "("
      raise "unexpected ("
    end
  end
  return ret
end

def primary(stream) 
  if stream[0] == "("
    stream.shift
    ret = expression(stream)
    raise ") expected" unless stream.shift == ")"
  elsif stream[0] == ")"
    raise "unexpected )"
  else
    ret = [ stream.shift ];
  end
  return ret
end

def parse(str)
  return expression(str.scan(/\)|\(|\w+/))
end

parse('(A OR B) AND (C OR D) AND (X OR Y OR Z)')

=> ["ACX", "ACY", "ACZ", "ADX", "ADY", "ADZ", 
    "BCX", "BCY", "BCZ", "BDX", "BDY", "BDZ"]

您可以使用递归下降解析器在一般情况下处理此问题:

def expression(stream)
  ret = primary(stream);
  while stream.length > 0 && stream[0] != ")"
    token = stream.shift
    if token == "AND"
      ret = ret.product(primary(stream)).map(&:join)
    elsif token == "OR"
      ret += primary(stream);
    elsif token == "("
      raise "unexpected ("
    end
  end
  return ret
end

def primary(stream) 
  if stream[0] == "("
    stream.shift
    ret = expression(stream)
    raise ") expected" unless stream.shift == ")"
  elsif stream[0] == ")"
    raise "unexpected )"
  else
    ret = [ stream.shift ];
  end
  return ret
end

def parse(str)
  return expression(str.scan(/\)|\(|\w+/))
end

parse('(A OR B) AND (C OR D) AND (X OR Y OR Z)')

=> ["ACX", "ACY", "ACZ", "ADX", "ADY", "ADZ", 
    "BCX", "BCY", "BCZ", "BDX", "BDY", "BDZ"]


你所说的
是什么意思?Ruby没有这样的表达式。你是说逻辑的
还是
?如果你是这个意思,那是不可能的。谢谢@sawa,我不是指任何语言的逻辑连接词——只是一种表示标准的格式。为了完整性接受@the Tin Man下面的答案。有关对解决方案的动态版本感兴趣的人员,请参阅。特别是代码块头,*rest=head.product(*rest)您所说的
以及
的可能重复?Ruby没有这样的表达式。你是说逻辑的
还是
?如果你是这个意思,那是不可能的。谢谢@sawa,我不是指任何语言的逻辑连接词——只是一种表示标准的格式。为了完整性接受@the Tin Man下面的答案。有关对解决方案的动态版本感兴趣的人员,请参阅。特别是代码块头,*rest=head.product(*rest)可能与Thank sawa重复,我不是指任何语言的逻辑连接词,只是表示标准的格式。什么的正式表示?Thank sawa,我不是指任何语言的逻辑连接词——只是一种表示标准的格式。什么的正式表示?非常感谢关于Array.product的提示,我是Ruby新手,所以我不知道。这无疑使解决方案变得优雅。关于您的解决方案,有一个问题-我们如何处理不同数量的阵列。您的示例显示了3个,但如果我们有5个或10个,例如?为了简单起见,我在示例中使用了这一个。您还可以使用-
a1.产品(a2、a3、a4等)
a.:)非常感谢关于Array.product的提示,我是Ruby新手,所以我不知道。这无疑使解决方案变得优雅。关于您的解决方案,有一个问题-我们如何处理不同数量的阵列。您的示例显示了3个,但如果我们有5个或10个,例如?为了简单起见,我在示例中使用了这一个。您还可以使用-
a1.产品(a2、a3、a4等)
a.:)天啊!您在此处复制了整个文档!!:)我只给了他链接。提供链接是个好主意,这也有助于OP了解其他方法。:)当链接断开时,只提供链接是毫无价值的。我提供了一个链接和相关的部分,这是我们应该做的。这个链接在过去由于各种原因而消失,最终又回来了。它比过去更加稳定,但是,根据大家的共识,我们不应该只使用链接,而应该引用即时内容。我喜欢走路。“
AB.product(CD,XYZ).join(&:map)
给出的是
“acxacyadzbadzbccybczbdxbdybdz”
。因此,将
AB.product(CD,XYZ).join(&:map)
更改为
AB.product(CD,XYZ).map(&:join)
。没有调查的人会一直支持你。非常奇怪:)谢谢你指出这一点。当我从IRB复制到我的编辑器formatting.OMG时,这两个被转换了!您在此处复制了整个文档!!:)我只给了他链接。提供链接是个好主意,这也有助于OP了解其他方法。:)当链接断开时,只提供链接是毫无价值的。我提供了一个链接和相关的部分,这是我们应该做的。这个链接在过去由于各种原因而消失,最终又回来了。它比过去更加稳定,但是,根据大家的共识,我们不应该只使用链接,而应该引用即时内容。我喜欢走路。“
AB.product(CD,XYZ).join(&:map)
正在给予
”ACX