Итак, я нашел гораздо более простое решение моей проблемы. Обратите внимание, что то, что ActiveCell вы используете, важно.
Вот решение текущего вопроса:
Sub Greaterthan()
Dim REF As Integer
Dim DEF As Integer
On Error Resume Next
REF = ActiveCell.Offset(, 3).Value
DEF = Application.Index(Sheets("Sheet1").Range("A1:A100"),
Application.Match(Sheets("Sheet2").Range(ActiveCell.Address),
Sheets("Sheet1").Range("B5:B1000"), 0))
Number = 3
x = "Yes"
y = "No"
If (REF - DEF) > Number Then
ActiveCell.Offset(, 3).Value = x
Else
ActiveCell.Offset(, 3).Value = y
End If
End Sub
Первая мысль. Вы можете определить длину n
строки в O (log2 (n))
.
Z *
, где Z
представляет k
вопросительных знаков, начиная с 0, затем с 1, а затем удваивая количество вопросительных знаков при каждой проверке до тех пор, пока не будет найдено совпадение. n
должно быть между k / 2
и k
k
таким же образом, как двоичный поиск делает. Знание точной длины может помочь выполнить своего рода разделение и императив в пространственной области.
ОБНОВЛЕНИЕ
Если вам известна длина, вы можете использовать тот же шаблон для правильного определения местоположения символа. .
Пример:
..X. ..XX (spaces added for readability) + symbol may be X - symbol is not X X symbol is X *X* => MATCH ++++ ++++ *X* ???? => MATCH ++++ ++++ *X*?? ???? => NO MATCH --++ ++++ ??X? ???? => MATCH --X+ ++++ ??XX ???? => NO MATCH --X- ++++ ??X? *X*?? => NO MATCH --X- --++ ??X? ??X? => MATCH --X- --X+ ??X? ??XX => MATCH --X- --XX
Для длины строки n
и размера алфавита m
потребуется около O (log2 (n))
, чтобы найти длину строки, примерно O (n • log2 (n))
, чтобы правильно разместить n
символов, и O (m)
, чтобы найти использованные символы - суммирование всех вместе дает O (n • log2 (n) + m)
.
Я мог представить, что можно ускорить это, объединив несколько шагов - возможно, проверить используемые символы при определении длины строки или одновременном обнаружении двух (или даже больше?) символов в первой и второй половине строки. Это потребует изолированной повторной проверки объединенных шагов, если проверка не удалась, чтобы определить, какая проверка не удалась. Но пока объединенная проверка будет успешной, вы получите информацию по обоим.
Что касается "разделяй и властвуй", не забудьте отслеживать значения, которых, как вы знаете, нет. Также я бы не стал использовать a, b, c
, но с порядком частоты. Такая марковская цепочка может сделать его еще быстрее.
Следует остерегаться того, что вы не можете предполагать, что данный литерал всегда будет соответствовать одному и тому же месту во входных данных. Это будет представлять особый интерес при удалении подстановочных знаков в конце.
c a b a
--------
* a * match
* b*a* woops!
Why not convert your DOS style wildcard string into a regular expression? e.g.:
?a*
becomes:
.a.*
Then just perform a simple regular expression match comparing that to your test string.
Если определенное количество? работает, вы также можете проверить "?", "??", "???" и т. д., чтобы получить длину строки, но я сомневаюсь, что это сильно поможет, поскольку вы также можете проверить правильность длины всего за одну дополнительную проверку без каких-либо подстановочных знаков после каждого раунда.
Я думаю, что метод разделения с проверкой набора символов до почти оптимального, есть некоторые дополнительные детали, например, если вы сопоставили * a * b *
, вы должны проверить * ab *
впоследствии, чтобы узнать, есть ли - это буквы между ними, и, конечно, как указано выше, отметьте * ab
и «ab» после этого, чтобы узнать, закончили ли вы с правой стороны или полностью.