注册 登录
编程论坛 VB6论坛

如何求该代数式的值?

yuma 发布于 2022-09-17 10:00, 2912 次点击
已知条件:
num1>=1 且 num1<=25
num2>=1 且 num2<=25
num3>=1 且 num3<=25
num4>=1 且 num4<=25

如果该等式成立:

i = num1 + num2 * 25 + num3 * 25 * 25 + num4 * 25 * 25 * 25

如何求:num1、num2、num3、num4的值?

PS:这个等式把我绕晕了,求解。
22 回复
#2
风吹过b2022-09-17 10:40
你把 I 作为一个 25 进位的值看不就是了。

num4=int(i/(25*25*25))
num3=int((i-num4*25*25*25)/(25*25))
num2=int((i-num4*25*25*25-num3*25*25)/25)
num1=i-num4*25*25*25-num3*25*25-num2*25
num1 或者写成
num1=i mod 25
#3
yuma2022-09-17 12:24
楼上代码有错误!!!!!!

就是25进制的计算问题

当 i=25时,应当num1=25才正确,这里结果却为num2=1

当i=406900时,num1 num2 num3 num4 应当都等于25才对,这里结果也不正确。

我算了一天,也没算出问题出在哪。

演算程序如下:

程序代码:
Private Sub Form_Load()

'公式:i = num1 + num2 * 25 + num3 * 25 * 25 + num4 * 25 * 25 * 25

Dim i As Long
i = 25
num4 = Int(i / (25 * 25 * 25))
num3 = Int((i - num4 * 25 * 25 * 25) / (25 * 25))
num2 = Int((i - num4 * 25 * 25 * 25 - num3 * 25 * 25) / 25)
num1 = i - num4 * 25 * 25 * 25 - num3 * 25 * 25 - num2 * 25
'num1 或者写成
'
num1 = i Mod 25
Debug.Print num1 & " " & num2 & " " & num3 & " " & num4
End Sub


[此贴子已经被作者于2022-9-17 13:58编辑过]

#4
yuma2022-09-17 14:36
算法有问题

此题作废

重新设计算法。
#5
wmf20142022-09-17 20:45
这题先要从数学上下手。
从题意可知,25进制没有问题,但25进制的数是0-24,所以要用25进制解题则先要对式子进行展开:
由于所有数据是从1到25,所以可以理解为是25进制的各位数加1,
即num1=n1+1,num2=n2+1,num3=n3+1,num4=n4+1
由此可得出num1+num2*25+num3*25*25+num4*25*25*25=(n1+1)+(n2+1)*25+(n3+1)*25*25+(n4+1)*25*25*25
将后面的式子展开n1+n2*25+n3*25*25+n4*25*25*25+1+25+625+15625=n1+n2*25+n3*25*25+n4*25*25*25+16276
n1+n2*25+n3*25*25+n4*25*25*25才是真正的25进制数,所以你的最终i值必须先减去16276,最后再依据你的3楼算法得到n1至n4的值,再对n1到n4分别加1,就是num1到num4的值。
406900-16276=390624
390624 mod 25=24 n1
int(390624/25) mod 25=24 n2
...
#6
yuma2022-09-17 21:04
代码写出来后,当i的值为 1、25、26、390624、406900时,会发现结果总是会出问题,悲哀!

当i等于以上值时,只有部分结果是正确的。

[此贴子已经被作者于2022-9-17 21:20编辑过]

#7
风吹过b2022-09-18 12:15
2 楼算法中能算核心算法。
修正很简单的啊。要么计算前修正
要么计算后修正。

计算后修正:从 num1 判断起,如果 为 0 ,那么从前面一位借1位来,手动写一个借位减法就是了。

那个核心算法是我在 excel 里用公式简单验算了一下而以。

--------------------------------------------
0 + 0 * 25 + 0 * 25 * 25 + 0 * 25 * 25 *25 = 0
1 + 0 * 25 + 0 * 25 * 25 + 0 * 25 * 25 *25 = 1
25 + 0 * 25 + 0 * 25 * 25 + 0 * 25 * 25 *25 = 25
1 + 1 * 25 + 0 * 25 * 25 + 0 * 25 * 25 *25 = 26
24 + 24 * 25 + 24 * 25 * 25 + 24 * 25 * 25 *25 = 390624
25 + 25 * 25 + 25 * 25 * 25 + 25 * 25 * 25 *25 = 406900

程序代码:

Dim num1 As Long, num2 As Long
Dim num3 As Long, num4 As Long
Dim i As Long

i = Val(Text1.Text)
'If i <= 0 Then Exit Sub       '确保输入为正数

num4 = Int(i / (25 * 25 * 25))
num3 = Int((i - num4 * 25 * 25 * 25) / (25 * 25))
num2 = Int((i - num4 * 25 * 25 * 25 - num3 * 25 * 25) / 25)
num1 = i - num4 * 25 * 25 * 25 - num3 * 25 * 25 - num2 * 25
'num1 或者写成
'
num1 = i Mod 25

If num1 = 0 Then   '如果=0,判断一下能不能借位
    If num2 > 0 Or num3 > 0 Or num4 > 0 Then
        num1 = 25               '能借位,进行借位处理
        num2 = num2 - 1
    End If
End If
If num2 < 1 Then        '如果=0 或 -1,需要借位
    If num3 > 0 Or num4 > 0 Then    '能借位,进行借位处理
        num2 = 25 + num2
        num3 = num3 - 1
    End If
End If
If num3 < 1 Then        '同上
    If num4 > 0 Then
        num3 = 25 + num3
        num4 = num4 - 1
    End If
End If

Label1.Caption = num1
Label2.Caption = num2
Label3.Caption = num3
Label4.Caption = num4

Label5.Caption = num1 & " + " & num2 & " * 25 + " & num3 & " * 25 * 25 + " & num4 & " * 25 * 25 *25 = " & i
Debug.Print Label5.Caption







[此贴子已经被作者于2022-9-18 12:17编辑过]

#8
风吹过b2022-09-18 12:18
去掉 确保为正数代码后,
输入负数时,会导致 num4 出现负数,并且是一定。

24 + 24 * 25 + 24 * 25 * 25 + -1 * 25 * 25 *25 = -1
25 + 23 * 25 + 24 * 25 * 25 + -1 * 25 * 25 *25 = -25

当输入 值超过 406900 时,会导致 num4 超过 25 。这个也应该在 输入时检测一下。


[此贴子已经被作者于2022-9-18 12:40编辑过]

#9
风吹过b2022-09-18 12:41
计算机里,一般是后修正,参考 BCD码 及对应的 指令 用法。
#10
yuma2022-09-18 13:03
回复 7楼 风吹过b
感谢B哥无私提供的代码。

此代码我是用来输出 WB 编码的所有组合的。

1-25分别对应A-Y的。

从i= 1 to 406900遍历下去,就是所有 WB 编码,准备用来做个字典用的。

所以i的值是不会取负数的。

使用此算法,遇到进位的问题,总是理不清头绪,得不到正确的结果。

后来想到了取余,但是那只是将十进制计算为25进制数。和项目期望的值不符。

走了很多弯路,都准备放弃了。

这代码提供的,我觉得又可以继续我的项目了

在此表示感谢。

[此贴子已经被作者于2022-9-18 13:35编辑过]

#11
yuma2022-09-18 13:06
将int去掉,将 “/”号 换成 “\”号,代码更简洁。
#12
wmf20142022-09-18 16:22
?难道我会错意了。根据条件,num1到num4每位最小值为1,i值不可能小于16276的。当然不是恒定4位25进制数,也能做,下面代码可直接返回楼主所需的五笔字符串。
Function wbchar(n As Long) As String
  Dim i As Long, j As Long, k As Long, a As String
  If n > 406900 Or n < 1 Then Exit Function
  j = 16276
  k = 4
  If n < 16276 Then j = 651: k = 3
  If n < 651 Then j = 26: k = 2
  If n < 26 Then j = 1: k = 1
  n = n - j
  For i = 1 To k
    a = Chr((n Mod 25) + 65) & a
    n = Int(n / 25)
  Next
  wbchar = a
End Function
调用方法:
msgbox wbchar(1)  弹出“A”
msgbox wbchar(25)  弹出“Y”
msgbox wbchar(26)  弹出“AA”
msgbox wbchar(390624)  弹出“XXXX”
msgbox wbchar(406900)  弹出“YYYY”
这题按照楼主想要的结果还可以直接对"A-Z"做四次全排列,分别是“25排1”“25排2”“25排3”“25排4”

该函数在excel vba中调试成功。




[此贴子已经被作者于2022-9-18 16:31编辑过]

#13
yuma2022-09-18 16:32
回复 12楼 wmf2014
我用的是这个,你这个代码比较难理解。

程序代码:
Function GetStr(Num)
Select Case Num
Case 1: GetStr = "A"
Case 2: GetStr = "B"
Case 3: GetStr = "C"
Case 4: GetStr = "D"
Case 5: GetStr = "E"
Case 6: GetStr = "F"
Case 7: GetStr = "G"
Case 8: GetStr = "H"
Case 9: GetStr = "I"
Case 10: GetStr = "J"
Case 11: GetStr = "K"
Case 12: GetStr = "L"
Case 13: GetStr = "M"
Case 14: GetStr = "N"
Case 15: GetStr = "O"
Case 16: GetStr = "P"
Case 17: GetStr = "Q"
Case 18: GetStr = "R"
Case 19: GetStr = "S"
Case 20: GetStr = "T"
Case 21: GetStr = "U"
Case 22: GetStr = "V"
Case 23: GetStr = "W"
Case 24: GetStr = "X"
Case 25: GetStr = "Y"
End Select
End Function
#14
yuma2022-09-18 22:43


[此贴子已经被作者于2022-9-18 22:52编辑过]

#15
风吹过b2022-09-18 23:16
wmf2014 的代码,按你要求的变量改了下。应该能看懂了。
程序代码:
Dim num1 As Long, num2 As Long
Dim num3 As Long, num4 As Long
Dim i As Long, j As Long, k As Long

i = Val(Text1.Text)

  If i > 406900 Or i < 1 Then Exit Sub  '超范围
  j = 16276             '默认减值 1+1*25+1*25*25+1*25*25*25
  k = 4                                 '默认有4个值
  If i < 16276 Then j = 651: k = 3  '如果小于 1+1*25+1*25*25+1*25*25*25,只有3个值
  If i < 651 Then j = 26: k = 2     '如果小于 1+1*25+1*25*25,只有2个值
  If i < 26 Then j = 1: k = 1       '如果小于 1+1*25 ,只有1个值
  i = i - j
  
  'wmf2014 写成了循环,因你要求单变量输出,只能改为4组命令
  
  num1 = i Mod 25 + 1     '取最低位
  i = i \ 25              '移位
  If k > 1 Then           '如果还有更多的位
    num2 = i Mod 25 + 1     '同上取最低位,移位
    i = i \ 25
  End If
  If k > 2 Then
    num3 = i Mod 25 + 1
    i = i \ 25
  End If
  If k > 3 Then
    num4 = i Mod 25 + 1
    i = i \ 25
  End If

Label1.Caption = num1
Label2.Caption = num2
Label3.Caption = num3
Label4.Caption = num4

Label5.Caption = num1 & " + " & num2 & " * 25 + " & num3 & " * 25 * 25 + " & num4 & " * 25 * 25 * 25 "
#16
风吹过b2022-09-18 23:19
GetStr
你可以定义为一个数组吗?
然后根据下标直接取数,不更快吗?
wmf2014 的代码是直接使用 chr 函数生成字符,不需要再查表,这也是一个办法。

#17
yuma2022-09-19 00:38
回复 15楼 风吹过b
她这种还要减去16276,猛一看莫名奇妙。B的算法OK,更符合题目要求。
#18
yuma2022-09-19 00:49
chr(65) - chr(89) 就是 A -Y

代码中 1-25 是 A-Y

那么

Debug.Print chr(num1+64) & chr(num2+64) & chr(num3+64) & chr(num4+64)

是不是比wmf2014还要简单。

这里也要考虑一下值为0和1的情况。


---------------------------------------
现在看来,方法有好几种
可以出好几种代码
最终结果都是一样的。

[此贴子已经被作者于2022-9-19 00:57编辑过]

#19
风吹过b2022-09-19 09:47
dim GetStr(25) as string
GetStr(0)=""
for i=1 to 25
GetStr(i)=chr(64+i)
next i

---------------
调用时
debug.print getstr(num1) & getstr(num2) & getstr(num3) & getstr(num4)
不用管0,因为0会直接是空串,所以0 不影响。

#20
yuma2022-09-19 20:09
这样也可以的
#21
yuma2022-09-30 18:04
回复 19楼 风吹过b
B哥,函数简单到没朋友。

Function GetStr(Num)
If Num <> 0 Then GetStr = Chr(64 + Num)
End Function
#22
风吹过b2022-09-30 18:20
以下是引用yuma在2022-9-30 18:04:23的发言:

B哥,函数简单到没朋友。

Function GetStr(Num)
If Num <> 0 Then GetStr = Chr(64 + Num)
End Function


前面提了这种方法。
然后,我提的是针对他那个 多分支选择的问题。
#23
yuma2022-09-30 18:51
1