| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 653 人关注过本帖
标题:挑战DeepSeek!感觉上,TA写VFP代码没太大问题啊。
只看楼主 加入收藏
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:892
专家分:1376
注 册:2021-10-13
收藏
得分:0 
回复 10楼 cssnet
用deepseek确实可以做到事半功倍
2025-04-14 19:42
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:373
专家分:340
注 册:2013-10-4
收藏
得分:0 
问:
设“金银花”的配料表为“胆酸 珍珠母 栀子 水牛角 板蓝根 黄芩苷”,“板蓝根”的配料表为“麻黄 地龙 胆酸 栀子 五味子 黄芩苷 蝉蜕 金银花 ”,用VFP实现一个函数,计算两个输入参数(以空格作为分隔符的字符串)的匹配度。

答:
*-----注:DeepSeek给出的代码,个别行可能有误!------*
FUNCTION IngredientMatch
LPARAMETERS tcList1, tcList2
    * 函数功能:计算两个配料表的匹配度
    * 参数:tcList1 - 第一个配料表字符串(空格分隔)
    *       tcList2 - 第二个配料表字符串(空格分隔)
    * 返回值:匹配度百分比(0-100)
   
    * 分割字符串为数组
    LOCAL lnCount1, lnCount2, lnMatchCount, i, j
    LOCAL ARRAY laList1[1], laList2[1]
   
    * 分割第一个配料表
    lnCount1 = ALINES(laList1, STRTRAN(ALLTRIM(tcList1), "  ", " "))
    lnCount1 = ALINES(laList1, tcList1, " ")
   
    * 分割第二个配料表
    lnCount2 = ALINES(laList2, STRTRAN(ALLTRIM(tcList2), "  ", " ")
    lnCount2 = ALINES(laList2, tcList2, " ")
   
    * 计算匹配的配料数量
    lnMatchCount = 0
   
    * 检查laList1中的配料是否在laList2中
    FOR i = 1 TO lnCount1
        FOR j = 1 TO lnCount2
            IF UPPER(ALLTRIM(laList1[i])) == UPPER(ALLTRIM(laList2[j]))
                lnMatchCount = lnMatchCount + 1
                EXIT
            ENDIF
        ENDFOR
    ENDFOR
   
    * 计算匹配度百分比(基于两个列表的平均长度)
    LOCAL lnAvgLength, lnMatchPercent
    lnAvgLength = (lnCount1 + lnCount2) / 2
   
    IF lnAvgLength > 0
        lnMatchPercent = (lnMatchCount / lnAvgLength) * 100
    ELSE
        lnMatchPercent = 0
    ENDIF
   
    * 四舍五入到两位小数
    lnMatchPercent = ROUND(lnMatchPercent, 2)
   
    RETURN lnMatchPercent
ENDFUNC


2025-04-26 14:25
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:373
专家分:340
注 册:2013-10-4
收藏
得分:0 
问:
设配料表中的子配料,如“胆酸”,也由若干配料构成:“栀子 地龙 麻黄 前胡 枇杷叶”,“黄芩苷”的配料:“牛蒡子 胆酸 麻黄 紫苏”……,重构此函数,以类递归方式计算出更复杂的匹配度。

答:
<略>

问:
上面的函数以纯数组方式实现,无疑将问题复杂化了。现改用数据表Ingredient.dbf储存3000多种子配料信息,表结构为3个字段:name C (20),detail M,ID I。字段name是子配料名称,字段detail是以空格分隔的具体的子配料字符串,字段ID是整型数值。递归遍历此1000多种子配料表,若计算得到2个、3个、4个……或更多的子配料匹配度>=66.66%,则将其ID设为相同数值,即,将同一类的子配料,归为同一组。请重构函数,实现此算法。

答:
*----------注:deepSeek给出的代码有些复杂,我老人家此刻正在研读中……
*-- 主函数:配料匹配与分组
FUNCTION GroupIngredients
LPARAMETERS tnThreshold
    * 参数:tnThreshold - 分组匹配度阈值(51%)
    * 功能:递归分析配料表,将匹配度>=阈值的配料归为同一组
   
    LOCAL lnGroupID, lcSQL, lnCount
   
    * 初始化分组ID
    SELECT MAX(ID) FROM Ingredient INTO ARRAY laMaxID
    lnGroupID = IIF(ISNULL(laMaxID[1]), 1, laMaxID[1] + 1)
   
    * 创建临时表存储匹配结果
    CREATE CURSOR TempMatches (;
        Name1 C(20),;
        Name2 C(20),;
        MatchPercent N(5,2);
    )
   
    * 比较所有配料组合
    lcSQL = "SELECT A.Name AS Name1, B.Name AS Name2 ";
          + "FROM Ingredient A, Ingredient B ";
          + "WHERE A.Name < B.Name"  // 避免重复比较
   
    &lcSQL INTO CURSOR TempPairs
   
    SELECT TempPairs
    SCAN
        * 计算两个配料的匹配度
        lnMatch = CalculateMatch(TempPairs.Name1, TempPairs.Name2)
        
        * 存储匹配结果
        INSERT INTO TempMatches VALUES ;
            (TempPairs.Name1, TempPairs.Name2, lnMatch)
    ENDSCAN
   
    * 根据匹配结果分组
    SELECT * FROM TempMatches ;
        WHERE MatchPercent >= tnThreshold ;
        ORDER BY MatchPercent DESC ;
        INTO CURSOR TempValidMatches
   
    SELECT TempValidMatches
    SCAN
        * 查找两个配料的当前组ID
        LOCAL lnID1, lnID2
        SELECT ID FROM Ingredient WHERE Name = TempValidMatches.Name1 INTO ARRAY laID1
        SELECT ID FROM Ingredient WHERE Name = TempValidMatches.Name2 INTO ARRAY laID2
        
        lnID1 = IIF(_TALLY > 0, laID1[1], 0)
        lnID2 = IIF(_TALLY > 0, laID2[1], 0)
        
        * 分组逻辑
        DO CASE
        CASE lnID1 = 0 AND lnID2 = 0
            * 两个配料都未分组,赋予新组ID
            UPDATE Ingredient SET ID = lnGroupID ;
                WHERE Name = TempValidMatches.Name1 OR Name = TempValidMatches.Name2
            lnGroupID = lnGroupID + 1
            
        CASE lnID1 = 0
            * 配料1未分组,加入配料2的组
            UPDATE Ingredient SET ID = lnID2 WHERE Name = TempValidMatches.Name1
            
        CASE lnID2 = 0
            * 配料2未分组,加入配料1的组
            UPDATE Ingredient SET ID = lnID1 WHERE Name = TempValidMatches.Name2
            
        CASE lnID1 <> lnID2
            * 两个配料属于不同组,合并两组
            UPDATE Ingredient SET ID = lnID1 WHERE ID = lnID2
        ENDCASE
    ENDSCAN
   
    * 返回分组数量
    SELECT COUNT(DISTINCT ID) FROM Ingredient WHERE ID > 0 INTO ARRAY laGroupCount
    RETURN laGroupCount[1]
ENDFUNC

*-- 递归计算两个配料的匹配度
FUNCTION CalculateMatch
LPARAMETERS tcName1, tcName2, tnDepth
    * 参数:tcName1, tcName2 - 要比较的配料名称
    *       tnDepth - 当前递归深度
   
    * 初始化参数
    tnDepth = IIF(EMPTY(tnDepth), 1, tnDepth)
    IF tnDepth > 5  && 限制递归深度
        RETURN 0
    ENDIF
   
    * 获取配料详情
    LOCAL lcDetail1, lcDetail2
    SELECT detail FROM Ingredient WHERE Name = tcName1 INTO ARRAY laDetail1
    SELECT detail FROM Ingredient WHERE Name = tcName2 INTO ARRAY laDetail2
   
    lcDetail1 = IIF(_TALLY > 0, laDetail1[1], "")
    lcDetail2 = IIF(_TALLY > 0, laDetail2[1], "")
   
    * 如果都没有子配料,直接比较名称
    IF EMPTY(lcDetail1) AND EMPTY(lcDetail2)
        RETURN IIF(UPPER(tcName1) == UPPER(tcName2), 100, 0)
    ENDIF
   
    * 分割子配料
    LOCAL lnCount1, lnCount2, lnMatchCount, i, j
    LOCAL ARRAY laItems1[1], laItems2[1]
   
    lnCount1 = ALINES(laItems1, lcDetail1, " ")
    lnCount2 = ALINES(laItems2, lcDetail2, " ")
   
    * 计算直接匹配
    lnMatchCount = 0
    FOR i = 1 TO lnCount1
        FOR j = 1 TO lnCount2
            IF UPPER(ALLTRIM(laItems1[i])) == UPPER(ALLTRIM(laItems2[j]))
                lnMatchCount = lnMatchCount + 1
                EXIT
            ENDIF
        ENDFOR
    ENDFOR
   
    * 计算递归匹配
    LOCAL lnRecursiveMatch, lnTotalWeight
    lnRecursiveMatch = 0
    lnTotalWeight = 0
   
    FOR i = 1 TO lnCount1
        FOR j = 1 TO lnCount2
            * 跳过已直接匹配的
            IF UPPER(ALLTRIM(laItems1[i])) == UPPER(ALLTRIM(laItems2[j]))
                LOOP
            ENDIF
            
            * 计算子配料匹配度
            LOCAL lnSubMatch
            lnSubMatch = CalculateMatch(laItems1[i], laItems2[j], tnDepth + 1)
            
            * 加权累加
            IF lnSubMatch > 0
                lnRecursiveMatch = lnRecursiveMatch + lnSubMatch
                lnTotalWeight = lnTotalWeight + 1
            ENDIF
        ENDFOR
    ENDFOR
   
    * 计算总匹配度
    LOCAL lnTotalMatch, lnAvgLength
    lnAvgLength = (lnCount1 + lnCount2) / 2
   
    IF lnTotalWeight > 0
        lnRecursiveMatch = lnRecursiveMatch / lnTotalWeight  && 平均递归匹配度
    ENDIF
   
    lnTotalMatch = lnMatchCount + lnRecursiveMatch
   
    IF lnAvgLength > 0
        lnTotalMatch = (lnTotalMatch / lnAvgLength) * 100
    ELSE
        lnTotalMatch = 0
    ENDIF
   
    RETURN ROUND(lnTotalMatch, 2)
ENDFUNC

2025-04-26 14:29
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:373
专家分:340
注 册:2013-10-4
收藏
得分:0 
讲真,13#的算法比较复杂,我只是突发奇想设计了一个古怪题目,结果DeepSeek毫不费力将代码写出来了。

想要看懂这段代码,还真不是件容易的事情!再者,我手头也并没有数据表去测试DeepSeek实现的函数。

若挑战的不是DeepSeek,而是人,能秒提供一份更好的算法方案吗?
2025-04-26 16:41
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:892
专家分:1376
注 册:2021-10-13
收藏
得分:0 
Deepseek给的方案很正确,不难读懂,解释一下:
1,用aline得到每个配料表配料的数量;
2,对配料多的那个做一个for循环,对少的那个配料表做strtran,如果那个配料表变化了,说明有相同配料,记数;
3,直到循环结束,看看计数累计到多少?
4,用计数除以总配料数,就是匹配度,不是吗?
2025-04-27 21:19
快速回复:挑战DeepSeek!感觉上,TA写VFP代码没太大问题啊。
数据加载中...
 
   



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

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018846 second(s), 10 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved