| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1959 人关注过本帖
标题:24 点问题
只看楼主 加入收藏
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4940
专家分:30047
注 册:2008-10-15
收藏
得分:0 
经检查, 代码里变量写错了。
 (( 5 + 7 ) - 8 ) * 6 = 24
 (( 7 + 5 ) - 8 ) * 6 = 24
 8 * 6 / ( 7 - 5 ) = 24

这行:
            Call operation(r1(i), r2(j), r3)
写成
            Call operation(r1(j), r2(j), r3)
了,上午那个时候是没时间了,没怎么仔细检查。郁闷。

授人于鱼,不如授人于渔
早已停用QQ了
2015-06-17 13:43
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
5678可以了,“6、7、8、9”,“4、6、7、9”,“3、7、7、9”等又无解。6*8/(9-7)应该是可以整除的。

能编个毛线衣吗?
2015-06-17 15:26
lianyicq
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:26
帖 子:737
专家分:3488
注 册:2013-1-26
收藏
得分:0 
上次是将所有结果计算后列表,再查找24。这次是用递归全排列作大循环,大循环内再考虑3个运算符优先权算24。还是没考虑重复的情况。
程序代码:
Option Explicit

Private Sub Command1_Click()
  Dim arr(1 To 4) As Single
  Dim temp() As String
  Dim i As Integer
  List1.Clear
  temp = Split(Text1.Text, " ") '注1<得到4个操作数,赋值到arr中.
  For i = 0 To UBound(temp)
    arr(i + 1) = Val(temp(i))
  Next '>注1
  permutation arr, 1, 4

End Sub

Sub permutation(a() As Single, m As Integer, n As Integer)
  Dim i As Integer
  Dim temp As Integer
  Dim operator1 As Byte
  Dim operator2 As Byte
  Dim operator3 As Byte
  If m = n Then '注2:判断当前排列是否完成.
    For operator1 = 0 To 3 '注3<三重循环得到3个操作符的全排列.
      For operator2 = 0 To 3
        For operator3 = 0 To 3
          '注4:判断操作符的各种估先权组合得到地计算结果是否为24
          '5种操作符优先权顺序是: 1 2 3,1 3 2,2 1 3,2 3 1 ,3 2 1.(3 1 2 等同于1 3 2)
          If operate(operator3, operate(operator2, operate(operator1, a(1), a(2)), a(3)), a(4)) = 24 Then
            List1.AddItem "((" & a(1) & convert(operator1) & a(2) & ")" & convert(operator2) & a(3) & ")" & convert(operator3) & a(4)
          End If
        
          If operate(operator2, operate(operator1, a(1), a(2)), operate(operator3, a(3), a(4))) = 24 Then
            List1.AddItem "(" & a(1) & convert(operator1) & a(2) & ")" & convert(operator2) & "(" & a(3) & convert(operator3) & a(4) & ")"
          End If
        
          If operate(operator3, operate(operator1, a(1), operate(operator2, a(2), a(3))), a(4)) = 24 Then
            List1.AddItem "(" & a(1) & convert(operator1) & "(" & a(2) & convert(operator2) & a(3) & "))" & convert(operator3) & a(4)
          End If
        
          If operate(operator1, a(1), operate(operator3, operate(operator2, a(2), a(3)), a(4))) = 24 Then
            List1.AddItem a(1) & convert(operator1) & "((" & a(2) & convert(operator2) & a(3) & ")" & convert(operator3) & a(4) & ")"
          End If

          If operate(operator1, a(1), operate(operator2, a(2), operate(operator3, a(3), a(4)))) = 24 Then
            List1.AddItem a(1) & convert(operator1) & "(" & a(2) & convert(operator2) & "(" & a(3) & convert(operator3) & a(4) & "))"
          End If
        
        Next
      Next
    Next '>注3

    Exit Sub
  Else
    For i = m To n '注5<得到a()全排列
      swap a(m), a(i)
      permutation a(), m + 1, n
      swap a(m), a(i)
    Next '>注5
  End If
End Sub


Sub swap(a1 As Single, b1 As Single)
  Dim temp As Single
  temp = a1
  a1 = b1
  b1 = temp
End Sub
Function operate(i As Byte, x As Single, y As Single) As Single '按操作符索引号得到2个操作数的计算结果.注意顺序无误.
  Select Case i
   Case Is = 0
     operate = x + y
   Case Is = 1
     operate = x - y
   Case Is = 2
     operate = x * y
   Case Is = 3
     If y = 0 Then
       operate = 99.9
     Else
       operate = x / y
     End If
   End Select
End Function

Function convert(i As Byte) As String '按操作符索引转化为"+-*/"
  Select Case i
    Case Is = 0
      convert = "+"
    Case Is = 1
      convert = "-"
    Case Is = 2
      convert = "*"
    Case Is = 3
      convert = "/"
  End Select
End Function



如果把注3对应的内容删掉换成显示a(1)-a(4)就能看到遍历效果了.

[ 本帖最后由 lianyicq 于 2015-6-18 12:10 编辑 ]

大开眼界
2015-06-17 16:53
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4940
专家分:30047
注 册:2008-10-15
收藏
得分:0 
好吧,还是粗心造成的。
二个地方有问题。
1、这里判断与循环的顺序有问题
'第三个数与第四个数计算
Call operation(l3, l4, r2)
For i = 1 To 4
    For j = 1 To 4
        If r1(i).v >= 0 And r2(i).v >= 0 Then
            Call operation(r1(j), r2(j), r3)
            For m = 1 To 4
                If r3(m).v = 24 Then
                    s = s & r3(m).s & " = 24" & vbCrLf
                End If
            Next m
        End If
    Next j
Next i
改为:
'第三个数与第四个数计算
Call operation(l3, l4, r2)
For i = 1 To 4
    If r1(i).v > 0 Then
        For j = 1 To 4
            If r2(j).v >= 0 Then
                Call operation(r1(i), r2(j), r3)
                For m = 1 To 4
                    If r3(m).v = 24 Then
                        s = s & r3(m).s & " = 24" & vbCrLf
                    End If
                Next m
            End If
        Next j
    End If
Next i

2、'重新组合,不能使用 join 函数是因为有空行在
s = ""
For i = 1 To UBound(fj)
应该是:
'重新组合,不能使用 join 函数是因为有空行在
s = ""
For i = 0 To UBound(fj)
原来的代码把 第一个 结果给抛弃了。

-------------------------
 6 * 8 / ( 9 - 7 ) = 24
 6 / ( 9 - 7 ) * 8 = 24
 8 * 6 / ( 9 - 7 ) = 24
 8 / ( 9 - 7 ) * 6 = 24
-------------------------
 6 * ( 7 + 9 ) / 4 = 24
 6 * ( 9 + 7 ) / 4 = 24
 ( 7 + 9 ) * 6 / 4 = 24
 ( 7 + 9 ) / 4 * 6 = 24
 ( 9 + 7 ) * 6 / 4 = 24
 ( 9 + 7 ) / 4 * 6 = 24
--------------------------
 ( 9 - 7 / 7 ) * 3 = 24
 ( 9 - 7 / 7 ) * 3 = 24

授人于鱼,不如授人于渔
早已停用QQ了
2015-06-17 20:29
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4940
专家分:30047
注 册:2008-10-15
收藏
得分:0 
lianyicq 的代码 写的很精练,比我的 优化好多了,占用内存也比我的小。
建议 lianyicq 的代码写点注释进去,我看起来都有点吃力。看了好几遍,跟踪了才大体上搞清楚运行流程。

特别这一段:
    For i = m To n
      swap a(m), a(i)
      permutation a(), m + 1, n
      swap a(m), a(i)
    Next
比我傻傻的写 24 行 精练多了。

授人于鱼,不如授人于渔
早已停用QQ了
2015-06-17 20:48
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4940
专家分:30047
注 册:2008-10-15
收藏
得分:0 
发现重复数据,郁闷之极。
经过调试,程序流程有问题, 去重代码只征对 一组数据 起作用,而不是对 24组数据同时起作用,所以输入相同数据时,我的代码还是会出现相同的数据。

需要去重代码段,从 运算模块 移到 调用 模块里去。


----------------------------
新手多调试程序吧。只有调试程序,才知道 错误出在什么地方。

代码编写 只占整个工作的小部分,大头是算法规划,另一部分就是 调试。
我最开始,算法规划不行, 虽然结果大体上对了,但错误的结果无法排除,这就是算法规划的失误。
然后修改过了算法,代码 写起来,很简单,但组合起来,就是BUG到处都是,经过调试,才能知道如何去修改错误,去除BUG。

授人于鱼,不如授人于渔
早已停用QQ了
2015-06-17 21:02
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:0 
为风版主和lianyicq点赞!!!
正如风版主所说的,lianyicq版主的代码干练缜密,值得学习!只是我还没咋看懂,不知道你们怎么就处理了带括号的四则运算的
待我抽空想一个另类的穷举做这题(vb语法不太熟,估计还是要师兄援手完成了)。

能编个毛线衣吗?
2015-06-17 21:24
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4940
专家分:30047
注 册:2008-10-15
收藏
得分:0 
好吧,我来解释一下,核心运算调用代码是这个。
          If operate(operator3, operate(operator2, operate(operator1, a(1), a(2)), a(3)), a(4)) = 24 Then
            List1.AddItem "((" & a(1) & convert(operator1) & a(2) & ")" & convert(operator2) & a(3) & ")" & convert(operator3) & a(4)
          End If

operate(operator3, _                    '第三次调用
   operate(operator2, _                 '第二次调用
   operate(operator1, a(1), a(2)_       '第一次调用  从右到左,先计算 1 和 2     
   ), a(3) _        第二次调用的第二个参数:再计算 1和2  与 3
   ), a(4) )        第三镒调用的第二个参数:最后再 和 4 进行计算

授人于鱼,不如授人于渔
早已停用QQ了
2015-06-18 09:16
lianyicq
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:26
帖 子:737
专家分:3488
注 册:2013-1-26
收藏
得分:0 
回复 28楼 风吹过b
我脑子已经不够用不好使,才想到哪儿写哪儿,不过每一个没有把握的模块都要独立测试没问题了才加进去。
26楼代码也是同样方法做的。
确实应该添加一些注释,26楼的注释加上了。

大开眼界
2015-06-18 09:17
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4940
专家分:30047
注 册:2008-10-15
收藏
得分:0 
我英文不行。
2级才考 31 分。

授人于鱼,不如授人于渔
早已停用QQ了
2015-06-18 11:52
快速回复:24 点问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020730 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved