Just to be clear, by delimiters I mean mathematical delimiters - parentheses, braces, and brackets. Also this post will be discussing code from a java class
I wrote to be used as a library. You can check the repo here. Alright, with that out of the way, let's go!
Part 1 - Auto-complete
Introduction
几个月前,我需要自动完成分隔符在我的程序之一中起作用。我从来没有真正考虑过该怎么做,因为这实际上并不是刚刚发生的事情。我的意思是说,您是否曾经手动一步步思考如何匹配一个大括号您还没有关闭程序?不,你只是本能地知道。你的大脑非常擅长检测和匹配模式.Butaprogramdoesn'thave本能.So,what'sthealgorithmbehindthispattern匹配?Howdoesthebraindoit,一步步?
Before I start the explanation, I highly recommend you check out the code on github and follow along! Feel free to import the class
if you ever need it in the future :)
The Algorithm
好吧,只需检查打开分隔符的数量(即(,{和[) in an expression和put that number of closing delimiters at the end! So if you were given log(sin(2^(5你只是放3 closing parentheses in the end,right?
没那么快。 如果表达式是日志(sin(2 ^(5)? 您现在不能放置3个分隔符,您必须放置2,因为1是已经关闭。 因此,我们不能只计算开头定界符的外观,还必须1)计算结束定界符的数量,2)抓住2之间的差异然后3)相应地追加。
一切都很好,但是我们还没有完成。 混合定界符呢? 像这样log [sin(2 ^ {。 现在我们终于可以讨论好玩部分,一步一步地说明您的大脑如何(可能)做到这一点。
简而言之,您的大脑只扫描表情向后reallyfast.Ifitseesanopeningdelimiter,it立即appendsthecorrespondingclosingdelimitertotheexpression.Nowaddtheaboveparagraphaboutcheckingthenumberofappearancetothemixandnomatterwhatexpressionyoufeedin,it'llalwaysoutputaperfectlymatchedoutputexpression.
您可以在一个开关检查每个单位表达式的语句(即日志,罪,cos,(,{,)....) like so in 爪哇--
// Inside the Switch statement
case "(":
++openingParentheses;
if (openingParentheses > closingParentheses) {
resultstr.append(")");
closingParentheses++;
}
break;
现在您只需要把整个开关中的陈述反向迭代器环!
Here it is in action!
note that although the frontend shows only parentheses, the backend uses different delimiters for different functions, so it still uses the exact same algorithm
Part 2 - Function associated with given closing delimiter
Introduction
完成自动完成功能后,我需要确切知道哪个函数与哪个定界符相关联。 假设您得到此表达式log10 [sin(23 ^ {56 * cos(loge [2])})]并告诉您找出哪个功能倒数第二个括号属于。 在这种情况下,属于cos。 但是其背后的算法是什么?
The Algorithm
一种gain, I recommend opening the source code if you haven't already
再一次,我们反向迭代表达式,这次我们还需要一个用户指数并且表达式必须是数组,以分隔每个单位表达式。 表达方式log10 [sin(23 ^ {56 * cos(loge [2])})],如果变成了串 数组, it'd be-
{"log10", "[", "sin", "(", "23", "^", "{", "56", "*", "cos", "(", "loge", "[", "2", "]", ")", "}", ")", "]"}
这次,我们从给定索引开始反向迭代,但跳过索引本身。 因此,倒数第二个括号在这个数组中是15。 因此,我们将开始从反向迭代14。
现在,反向迭代必须继续直到打开分隔符的次数为比。。。更棒(不等于)分隔符的出现次数。 循环停止的瞬间,wallah !,您神奇地获得了相应功能的索引,在这种情况下,cos。
好吧,这不是魔术,但您知道我的意思。
如果我们想用括号来实现这一点(()。 我们会这样做的;
while (openParentheses <= closeParentheses) {
switch (expression[i]) {
case ")":
closeParentheses++;
break;
case "(":
openParentheses++;
break;
}
i--;
}
所结果的一世 一世s the 一世ndex of the funct一世on.
Here it is in action!
notice that whenever I remove a closing delimiter using backspace, the program is able to tell which function region I just entered
Conclusion
而已! 那就是你的大脑做到的(可能)。 一开始我发现它真的很吸引人,当我弄清楚算法时,感觉真的很棒。 我想我会和大家分享!
Once again, if you need to use it in any of your java
programs, I personally used it in Android
dev stuff, you can just grab the .jar
file from the repo!