Как вы рекурсивно заменяете вхождения строки в массиве

Итак, рассмотрим класс A с двумя строковыми переменными "name" и "value"

класс B содержит переменную Set of 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"

Как мне это сделать?

2 ответа

Вы создаете 2 Hashmap, translated а также toTranslate,

Вы анализируете свой набор.

Для каждого A в вашем наборе вы смотрите на значение. Если значение содержит любое количество $element (начато $ знак), вы ищете это $element в ваших переведенных ключах Hashmap.

Если это там, вы заменяете вхождения $element по значению, найденному в вашей переведенной хэш-карте.

Вы делаете это для каждого другого $element Вы нашли в своем объекте.

Я упал $element Вы добавили свой объект А в translated hashmap (ключ = имя, значение = значение).

Иначе, вы добавляете его в свой toTranslate HashMap.

После того, как весь ваш сет проанализирован, у вас есть 2 хэш-карты.

Вы создаете цикл while: while toTranslate hashmap не пустой, вы берете каждое значение и пытаетесь перевести $element в нем те, кто в вашем translate HashMap.

Будьте осторожны, вы можете закончить бесконечным циклом. Хорошо бы убедиться, что каждый раз, когда вы включаете toTranslate hashmap, количество его элементов сокращено. Если нет, то вы в бесконечном цикле.

Я не думаю, что это должно быть рекурсивным. Я думаю, что только это будет работать:

bool madeReplacement;

делать:

bool madeReplacement = false

Для каждого члена набора X:

Для каждого другого члена набора Y:

Замените все экземпляры Y.name на Y.value в X.value. Если вы заменили что-либо, madeReplacement = true.

while (madeReplacement)


Пример:

$ 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 (выполняя тот же цикл над остальным набором). Это делает O(n^2) наихудшим случаем, поэтому ваше подозрение в правильности рекурсивного подхода может быть правильным;)

(Я не был уверен, что имена переменных гарантированно начинаются с $, поэтому я написал это, чтобы это не имело значения)

Другие вопросы по тегам