0

所以考虑一个有两个字符串变量“name”和“value”的类A

B 类包含一个变量,它是 A 的集合

Set<A> allVariables 

是一个看起来像这样的集合

A.name="$var1"
A.value = "x+10>2"

A.name="$var2"
A.value="11+y%10==0"

A.name="$var3"
A.value="$var1 && $var2"

我需要做的是评估这些表达式。我为此使用 jexl。我需要遍历 Set 并用它们各自的值替换这些变量名。

在这种情况下,名称为 $var3 的对象需要替换为 "x+10>2 && 11+y%10==0"

我该怎么做呢?

4

2 回答 2

2

您创建 2 个 Hashmap,translated并且toTranslate.

你解析你的集合。

对于你的 Set 中的每个 A,你都会看值。如果 value 包含任意数量的$element(以$符号开头),则$element在翻译的 Hashmap 键中查找它。

如果它在那里,你用$element你翻译的哈希图中找到的值替换出现的值。

$element您对在 A 对象中找到的每个不同都执行此操作。

如果所有$element内容都已翻译,则将对象 A 添加到translated哈希图中(键 = 名称,值 = 值)。

否则,您将其添加到您的toTranslate哈希图中。

解析完所有 Set 后,您将获得 2 个哈希图。

您创建一个while循环:当toTranslatehashmap不为空时,您获取每个值,并尝试$element通过translatehashmap中的值转换其中的值。

请注意,您可能会以无限循环结束。要做的一件好事是确保每次在toTranslate哈希图上循环时,其元素的数量都会减少。如果不是,您将处于无限循环中。

于 2013-03-21T09:42:32.757 回答
0

我认为它不需要递归。我认为这会起作用:

布尔型替换;

做:

bool madeReplacement = false

对于集合的每个成员,X:

对于集合中的每个其他成员,Y:

用 X.value 中的 Y.value 替换 Y.name 的所有实例。如果你替换了任何东西,madeReplacement = true。

而(做了替换)


例子:

$var1 是值 1

$var2 是价值 $var1

$var3 是价值 $var2 + 2

$var3.value 包含 $var2,将 $var2 替换为 $var1 -> $var1 + 2

$var2.value 包含 $var1,将 $var1 替换为 1 -> 1

$var3.value 包含 $var1,将 $var1 替换为 1 -> 1 + 2

没有值包含任何其他名称,执行完成。


即使我们“评估无序”,我们最终还是得到了正确的答案。然而,这个算法在最坏的情况下可能是 O(n^3)(想象一下,如果你有 n 个变量在一个长链中相互引用,并且你在错误的一端开始替换)。解决此问题的一种方法是,当您的 X.value 包含 Y.name 时,首先递归地评估 Y.value(通过执行相同的 loop-over-the-rest-of-the-set)。这使它成为 O(n^2) 最坏的情况,因此您怀疑递归方法是合适的可能是正确的;)

(我不确定变量名是否保证以 $ 开头,所以我写了它,所以没关系)

于 2013-03-21T09:42:55.177 回答