| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2983 人关注过本帖
标题:求:一个好像很简单的问题,愣是想不到一个很简单的算法?
只看楼主 加入收藏
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:703
专家分:2780
注 册:2018-3-13
收藏
得分:0 
以下是引用cssnet在2023-3-13 21:30:08的发言:

非常感谢sam_jiang和诸位网友的帮助!

玩大一点点,为这算法增加一点点通用性或难度:

假设:
A1...A18
皆为整型数值字段
求:
获取重复次数最多的一个字段值,及其重复次数。

看不出有多大不同,算法逻辑还一样。或者我对需求理解有误?小小改动一下就行,关键还是行转列那句
Create Cursor test (最高分 I, 次数 I ;
    ,a1 I,a2 I,a3 I,a4 I,a5 I,a6 I,a7 I,a8 I,a9 I ;
    ,a10 I,a11 I,a12 I,a13 I,a14 I,a15 I,a16 I,a17 I,a18 I ;
)
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8,a9 ;
    ,a10,a11,a12,a13,a14,a15,a16,a17,a18) Values ( ;
        1,2,3, 4,5,6, 7,8,9, 2,3,4, 5,6,7, 10,9,9)
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8,a9 ;
    ,a10,a11,a12,a13,a14,a15,a16,a17,a18) Values ( ;
        98,95,74, 92,65,92, 92,77,92 ;
        ,88,92,87, 18,15,14, 22,25,22)

Select test
Scan all
    Dimension aaa[1]
    Scatter to aaa FIELDS like a*
    Dimension aaa[Alen(aaa),1]
    Create Cursor temp (ax I)
    Append From array aaa
    Select top 1 ax, Count(*) from temp group by ax order by 2 desc into array aaa
    Use in temp
    Replace next 1 最高分 with aaa[1], 次数 with aaa[2] in test
EndScan
Browse

[此贴子已经被作者于2023-3-14 07:21编辑过]


这家伙很懒,啥也没留下
2023-03-14 07:20
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:350
专家分:330
注 册:2013-10-4
收藏
得分:0 
以下是引用csyx在2023-3-14 07:20:08的发言:
看不出有多大不同,算法逻辑还一样。


感谢csyx、吹版的关注!
其实,我突发奇想将数据类型改为整型值,重点在于挑战OCCURS()。
在此,我毫不掩饰对于OCCURS()的偏爱。
事关,此函数若用OCCURS()来实现,那么,代码哪怕放到几十年后阅读,仍然无需注释秒懂,因逻辑简单,一目了然。
然而,整型值无法直接OCCURS(),用str()转换,最大长度为11字节,效率上难免大打折扣!

当然,可能有其他奇技淫巧,能够缩减字节数。比方说:
N1=1314520520
C1=TRANSFORM(N1,"@0")
C1=right(C1,8)
这样能将长度变为8字节。

此外,还有更变态的,只可惜VFP似乎遇到0xFFFF的字符会越界出错:
N1=0xFFFFFFFF
NL = BitRshift(N1,16)
NR = BitAnd(N1, 0xFFFF)
CL = chr(NL)
CR = chr(NR)
当数值为0xFFFF(十进制值65535)时,我过不了chr()这一关,无法构造出内码值为0xFFFF的字符串来,这一点比较遗憾。
退而求其次,这么弄:
Nsrc=0xFFFFFFFF
N1 = BitRshift(Nsrc,24)
N2 = BitAnd(BitRshift(Nsrc,16), 0xFF)
N3 = BitAnd(BitRshift(Nsrc,8), 0xFF)
N4 = BitAnd(Nsrc, 0xFF)
N2C = chr(N1)+chr(N2)+chr(N3)+chr(N4)
现在,N2C就是四字节的由整型值内码构造出来的字符串了。

那么,OCCURS()或许仍是值得依赖的。


[此贴子已经被作者于2023-3-14 11:17编辑过]

2023-03-14 09:17
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43182
注 册:2014-5-20
收藏
得分:0 
回复 22楼 cssnet
VFP对整数的表达方式有内码和外码之分。
内码是32bit,转换用BINTOC()、CTOBIN(),数值范围-2147483648~2147483647 (内码0x0~0xFFFFFFFF)
外码通常以字符串方式表达,可精确到(+/-)16位数字。
2023-03-14 09:58
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:703
专家分:2780
注 册:2018-3-13
收藏
得分:0 
分组统计本来就是 SQL 的强项,且 SQL 语句就像说英语一样带有自说明性,通用且容易理解
我的习惯是遇到需要统计的时候尽量用 SQL 语句解决

这家伙很懒,啥也没留下
2023-03-14 10:14
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:350
专家分:330
注 册:2013-10-4
收藏
得分:0 
以下是引用吹水佬在2023-3-14 09:58:38的发言:
内码是32bit,转换用BINTOC()、CTOBIN(),数值范围-2147483648~2147483647 (内码0x0~0xFFFFFFFF)


对!就是bintoc()!我随手构造N1...N4,就是因为一时忘了这个函数(其实平常经常用到的),呵呵呵呵。

N1 = 1314520520
C1 = bintoc(N1, "4RS")

如此,C1 = 0h4E59FDC8,那么就可以像occu(子字符串, 大字符串)一样地occu(整型值内码字符串, 大字符串)啦!

2023-03-14 10:49
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43182
注 册:2014-5-20
收藏
得分:0 
以下是引用cssnet在2023-3-14 10:49:47的发言:
N1 = 1314520520
C1 = bintoc(N1, "4RS")

bintoc好像是针对有符号整数,试试:
N1 = 0x80000000
C1 = bintoc(N1, "4RS")
如果要处理无符号整数,就要转换一下:
C1 = bintoc(N1-2^32, "4RS")
2023-03-14 11:03
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:350
专家分:330
注 册:2013-10-4
收藏
得分:0 
以下是引用吹水佬在2023-3-14 11:03:28的发言:
bintoc好像是针对有符号整数


其实有符号或无符号,似乎不太关键,
事关,bintoc()和ctobin()配对,
无论中间过程的值在VFP内部如何处理,最终总能被ctobin()正确还原。
而且在此只是借用整型数的内码值,临时用作了字符串;
具体中间过程的实现细节,权当作透明,直接忽略即可。
事实上,倘若仔细验证过occu()函数运行起来准确无误的话,
直接C1=bintoc(N1)即可,也不必附加标志参数"4RS"。
2023-03-14 11:16
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10607
专家分:43182
注 册:2014-5-20
收藏
得分:0 
以下是引用cssnet在2023-3-14 11:16:28的发言:



其实有符号或无符号,似乎不太关键,

不到你“不太关键”,除非你处理的数据小于0x80000000,否则,直接 bintoc(0x80000000, "4RS") 是行不通的。
2023-03-14 11:23
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:786
专家分:1160
注 册:2021-10-13
收藏
得分:0 
你对occurs是不是有什么误解,这是个字符串函数。

借用楼上那位兄弟的数据用一下。

clea
Create Cursor test ( ;
    a1 I,a2 I,a3 I,a4 I,a5 I,a6 I,a7 I,a8 I,a9 I ;
    ,a10 I,a11 I,a12 I,a13 I,a14 I,a15 I,a16 I,a17 I,a18 I ,score I, count I;
)
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8,a9 ;
    ,a10,a11,a12,a13,a14,a15,a16,a17,a18) Values ( ;
        1,2,3, 4,5,6, 7,8,9, 2,3,4, 5,6,7, 10,9,9)
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8,a9 ;
    ,a10,a11,a12,a13,a14,a15,a16,a17,a18) Values ( ;
        98,95,74, 92,65,92, 92,77,92 ;
        ,88,92,87, 18,15,14, 22,25,22)
GO top
FOR i=1 TO RECCOUNT()
    SCATTER FIELDS a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18 TO array1
    ntimes=0
    FOR j=1 TO ALEN(array1)
        n=acount(@array1,array1(j))
        IF n>ntimes
            nvalue=array1(j)
        ENDIF
        ntimes=MAX(ntimes,n)
    ENDFOR
    REPLACE score WITH nvalue,count WITH ntimes
    SKIP
ENDFOR
BROWSE

FUNCTION acount
PARAMETERS carray,nnum
LOCAL i
ncount=0
FOR i=1 TO ALEN(carray)
    IF carray(i)=nnum
        ncount=ncount+1
    ENDIF
ENDFOR
RETURN ncount
ENDFUNC
2023-03-14 12:36
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:786
专家分:1160
注 册:2021-10-13
收藏
得分:0 
两段代码基本上可以通用:

clea
*!*    Create Cursor test ( ;
*!*        a1 I,a2 I,a3 I,a4 I,a5 I,a6 I,a7 I,a8 I,a9 I ;
*!*        ,a10 I,a11 I,a12 I,a13 I,a14 I,a15 I,a16 I,a17 I,a18 I ,score I, count I;
*!*    )
*!*    Insert into test (a1,a2,a3,a4,a5,a6,a7,a8,a9 ;
*!*        ,a10,a11,a12,a13,a14,a15,a16,a17,a18) Values ( ;
*!*            1,2,3, 4,5,6, 7,8,9, 2,3,4, 5,6,7, 10,9,9)
*!*    Insert into test (a1,a2,a3,a4,a5,a6,a7,a8,a9 ;
*!*        ,a10,a11,a12,a13,a14,a15,a16,a17,a18) Values ( ;
*!*            98,95,74, 92,65,92, 92,77,92 ;
*!*            ,88,92,87, 18,15,14, 22,25,22)
Create Cursor test ( ;
     a1 V(10),a2 V(10),a3 V(10),a4 V(10),a5 V(10),a6 V(10),a7 V(10),a8 V(10) ;
     ,rate Y,maxa V(10))
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8) values ( ;
    "七仙女","黄大仙","黄大仙","黄大仙","黄小仙","黄大仙","黄大仙","王母娘娘")
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8) values ( ;
    "七仙女","黄大仙","七仙女","黄大仙","七仙女","七仙女","黄小仙","王母娘娘")
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8) values ( ;
    "黄小仙","黄大仙","黄小仙","黄大仙","黄小仙","七仙女","黄小仙","王母娘娘")
Insert into test (a1,a2,a3,a4,a5,a6,a7,a8) values ( ;
    "王母娘娘","王母娘娘","黄大仙","黄大仙","黄小仙","王母娘娘","王母娘娘","王母娘娘")

GO top
FOR i=1 TO RECCOUNT()
        SCATTER FIELDS LIKE a* TO array1
    ntimes=0
    FOR j=1 TO ALEN(array1)
        n=acount(@array1,array1(j))
        IF n>ntimes
            nvalue=array1(j)
        ENDIF
        ntimes=MAX(ntimes,n)
    ENDFOR
*!*        REPLACE score WITH nvalue,count WITH ntimes
        REPLACE rate WITH ntimes/8,maxa WITH nvalue
    SKIP
ENDFOR
BROWSE

FUNCTION acount
PARAMETERS carray,evalue
LOCAL i
ncount=0
FOR i=1 TO ALEN(carray)
    IF carray(i)=evalue
        ncount=ncount+1
    ENDIF
ENDFOR
RETURN ncount
ENDFUNC
2023-03-14 13:01
快速回复:求:一个好像很简单的问题,愣是想不到一个很简单的算法?
数据加载中...
 
   



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

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