有没有用聪明的办法VBA
或一个公式来找到一个“K”和“m”变量kx+m string
?
有几种方案为KX + M串怎么看待,例如:
312*x+12
12+x*2
-4-x
等等。 我敢肯定,我可以在Excel中编写非常复杂的公式解决这个问题,但我想,也许有人已经解决了这一点,类似的问题。 这是我最好的拍摄,到目前为止,但它不能处理所有的情况,但(当有在KX + M串两个减号,如:
=TRIM(IF(NOT(ISERROR(SEARCH("~+";F5))); IF(SEARCH("~+";F5)>SEARCH("~*";F5);RIGHT(F5;LEN(F5)-SEARCH("~+";F5));LEFT(F5;SEARCH("~+";F5)-1)); IF(NOT(ISERROR(SEARCH("~-";F5))); IF(SEARCH("~-";F5)>SEARCH("~*";F5);RIGHT(F5;LEN(F5)-SEARCH("~-";F5)+1);LEFT(F5;SEARCH("~*";F5)-1));"")))
我敢肯定,这将帮助你:)
将这个功能的模块:
Function FindKXPlusM(ByVal str As String) As String
Dim K As String, M As String
Dim regex As Object, matches As Object, sm As Object
'' remove unwanted spaces from input string (if any)
str = Replace(str, " ", "")
'' create an instance of RegEx object.
'' I'm using late binding here, but you can use early binding too.
Set regex = CreateObject("VBScript.RegExp")
regex.IgnoreCase = True
regex.Global = True
'' test for kx+m or xk+m types
regex.Pattern = "^(-?\d*)\*?x([\+-]?\d+)?$|^x\*(-?\d+)([\+-]?\d+)?$"
Set matches = regex.Execute(str)
If matches.Count >= 1 Then
Set sm = matches(0).SubMatches
K = sm(0)
M = sm(1)
If K = "" Then K = sm(2)
If M = "" Then M = sm(3)
If K = "-" Or K = "+" Or K = "" Then K = K & "1"
If M = "" Then M = "0"
Else
'' test for m+kx or m+xk types
regex.Pattern = "^(-?\d+)[\+-]x\*([\+-]?\d+)$|^(-?\d+)([\+-]\d*)\*?x$"
Set matches = regex.Execute(str)
If matches.Count >= 1 Then
Set sm = matches(0).SubMatches
M = sm(0)
K = sm(1)
If M = "" Then M = sm(2)
If K = "" Then K = sm(3)
If K = "-" Or K = "+" Or K = "" Then K = K & "1"
If M = "" Then M = "0"
End If
End If
K = Replace(K, "+", "")
M = Replace(M, "+", "")
'' the values found are in K & M.
'' I output here in this format only for showing sample.
FindKXPlusM = " K = " & K & " M = " & M
End Function
然后,你可以从宏观例如像这样称呼它:
Sub Test()
Debug.Print FindKXPlusM("x*312+12")
End Sub
或者使用它像一个公式。 例如,通过把这个小区中的:
=FindKXPlusM(B1)
我喜欢第二种方式(较少的工作:P)
我有不同的值测试它和这里的是我所得到的截图:
希望这可以帮助 :)
而不是解析打扰运行一个简单的LINEST
在VBA。
更换StrFunc
需要
Sub Extract()
Dim strFunc As String
Dim X(1 To 2) As Variant
Dim Y(1 To 2) As Variant
Dim C As Variant
X(1) = 0
X(2) = 100
strFunc = "312*x+12"
'strFunc = "12+x*2 "
'strFunc = "-4-X"
Y(1) = Evaluate(Replace(LCase$(strFunc), "x", X(1)))
Y(2) = Evaluate(Replace(LCase$(strFunc), "x", X(2)))
C = Application.WorksheetFunction.LinEst(Y, X)
MsgBox "K is " & C(1) & vbNewLine & "M is " & C(2)
End Sub
它比它看起来更为复杂。 甲KX + M可具有最多7个运营商和1操作的分钟如果我没有错。 而在这种情况下就变得非常复杂,以获得“K”和“M”值。 - 亚洲时报Siddharth溃败33分钟前
在duffymo的邮政大楼在我的评论
该快照示出了不同的组合那“KX + M”可以具有
而且正如前面所说,这是非常复杂的,以达到你想要的东西。 这是我愚蠢的尝试目前只提取“K”。 这个代码是没有办法以任何方式优雅 :(我也没有测试用不同的场景的代码,因此它可能会失败,等等。但是它可以让你对如何处理这个问题一个公平的想法,你将有更多的调整它得到你想要的确切结果。
CODE(我在此代码测试了7种可能的组合。它为这7个,但可能/会失败替他人)
Option Explicit
Sub Sample()
Dim StrCheck As String
Dim posStar As Long, posBrk As Long, pos As Long, i As Long
Dim strK As String, strM As String
Dim MyArray(6) As String
MyArray(0) = "-k*(-x)+(-m)*(-2)"
MyArray(1) = "-k*x+(-m)*(-2)"
MyArray(2) = "-k(x)+(-m)*(-2)"
MyArray(3) = "-k(x)+(-m)(-2)"
MyArray(4) = "-kx+m"
MyArray(5) = "kx+m"
MyArray(6) = "k(x)+m"
For i = 0 To 6
StrCheck = MyArray(i)
Select Case Left(Trim(StrCheck), 1)
Case "+", "-"
posBrk = InStr(2, StrCheck, "(")
posStar = InStr(2, StrCheck, "*")
If posBrk > posStar Then '<~~ "-k*(-x)+(-m)*(-2)"
pos = InStr(2, StrCheck, "*")
If pos <> 0 Then
strK = Mid(StrCheck, 1, pos - 1)
Else
strK = Mid(StrCheck, 1, posBrk - 1)
End If
ElseIf posBrk < posStar Then '<~~ "-k(-x)+(-m)*(-2)"
pos = InStr(2, StrCheck, "(")
strK = Mid(StrCheck, 1, pos - 1)
Else '<~~ "-kx+m"
'~~> In such a case I am assuming that you will never use
'~~> a >=2 letter variable
strK = Mid(StrCheck, 1, 2)
End If
Case Else
posBrk = InStr(1, StrCheck, "(")
posStar = InStr(1, StrCheck, "*")
If posBrk > posStar Then '<~~ "k*(-x)+(-m)*(-2)"
pos = InStr(1, StrCheck, "*")
If pos <> 0 Then
strK = Mid(StrCheck, 1, pos - 2)
Else
strK = Mid(StrCheck, 1, posBrk - 1)
End If
ElseIf posBrk < posStar Then '<~~ "k(-x)+(-m)*(-2)"
pos = InStr(1, StrCheck, "(")
strK = Mid(StrCheck, 1, pos - 2)
Else '<~~ "kx+m"
'~~> In such a case I am assuming that you will never use
'~~> a >=2 letter variable
strK = Mid(StrCheck, 1, 1)
End If
End Select
Debug.Print "Found " & strK & " in " & MyArray(i)
Next i
End Sub
快照
这不是很多,但我希望这可以让你在正确的道路......
我会使用一个正则表达式来搜索一个或多个数字; 后 “* X” 为m和后 “+” 对于k。
你的例子显示了整数值。 如果有什么的斜率和截距是浮点数? 签名值? 它更复杂得多,你的榜样建议。
我认为,最普遍的解决方案是写一个词法分析器/分析器用一个简单的语法来为您处理。 我不知道什么对你的VB或.NET的报价。 ANTLR会在Java的土地一个解决方案; 有一个ANTLR.NET。
我不知道这一切的努力给你买。 你会与提取的内容吗? 我认为这将会是一样便于用户在数字型细胞填补k和m,并计算y = m*x + k
从这些而不是插入一个字符串,并提取它们。
如果你的目标很简单,就是评价一个字符串,也许eval()
是你的答案:
如何将一个字符串公式为“实际”的公式