人工智能都错在哪儿啊?请修改一下
vfp环境,字段-学号,前两位为年级,再两位班级,后两位为学号,例如230926,为年级23,班级09,学号26,现在求一个新表字段分别为,学号,姓名,语文,语文年级名次,语文班级名次,......,生物,生物年级名次,生物班级名次,总分,总分年级名次,总分班级名次,名次采用,假设分数分别为100,100,98,97,90,90,87....,则名次分别为1,1,3,4,5,5,7....
计算名次,尽量不用SELECT 命令,而是构造一个排序函数或取名次的函数。
如果某学生某科没有分数记为0分,
第1次
* ===============================================================
* VFP 终极数组全排位方案 (完全不依赖表记录指针和索引,彻底解决FOF/Exclusive问题)
* ===============================================================
SET SAFETY OFF
SET TALK OFF
SET EXCLUSIVE ON
CLOSE DATA ALL
* 1. 读取原表数据到二维数组
USE cj.dbf
lnCount = RECCOUNT()
IF lnCount = 0
MESSAGEBOX("原表是空的!", 16, "错误")
RETURN
ENDIF
* 数组结构:1:原记录号, 2:学号, 3:姓名, 4-9:6科成绩
DIMENSION aSource[lnCount, 9]
COPY TO ARRAY aSource FIELDS RECNO(), 学号, 姓名, 语文, 数学, 外语, 物理, 化学, 生物
USE
* 2. 创建最终结果表 (含所有年级/班级名次列)
CREATE TABLE cj_final ( ;
学号 C(10), 姓名 C(8), ;
语文 N(5,1), 语文_年名 N(4,0), 语文_班名 N(4,0), ;
数学 N(5,1), 数学_年名 N(4,0), 数学_班名 N(4,0), ;
外语 N(5,1), 外语_年名 N(4,0), 外语_班名 N(4,0), ;
物理 N(5,1), 物理_年名 N(4,0), 物理_班名 N(4,0), ;
化学 N(5,1), 化学_年名 N(4,0), 化学_班名 N(4,0), ;
生物 N(5,1), 生物_年名 N(4,0), 生物_班名 N(4,0), ;
总分 N(5,1), 总分_年名 N(4,0), 总分_班名 N(4,0) )
* ===============================================================
* 3. 自定义冒泡排序跳号函数 (传入分数数组,返回对应名次数组)
FUNCTION GetJumpRank(arrScores, nTotal)
DIMENSION arrRanks[nTotal]
LOCAL i, j, nTemp, nRank, nCount, nLastScore
* 冒泡排序 (降序)
FOR i = 1 TO nTotal - 1
FOR j = i + 1 TO nTotal
IF arrScores[i] < arrScores[j]
nTemp = arrScores[i]
arrScores[i] = arrScores[j]
arrScores[j] = nTemp
ENDIF
ENDFOR
ENDFOR
* 计算1,1,3,4,5,5,7...并列跳号
nRank = 0
nCount = 0
nLastScore = -9999
FOR i = 1 TO nTotal
nCount = nCount + 1
IF arrScores[i] <> nLastScore
nRank = nCount
ENDIF
nLastScore = arrScores[i]
arrRanks[i] = nRank
ENDFOR
RETURN arrRanks
ENDFUNC
* ===============================================================
* 4. 主循环:计算并回填名次
DIMENSION arrScores[lnCount], arrRecno[lnCount], arrResult[lnCount, 15] && 存放所有计算结果名次
STORE 0 TO arrResult
FOR i = 1 TO 7 && 外层循环:7个指标(语数外物化生总分)
* 取出所有学生该项的分数,顺便保存对应原记录号
FOR j = 1 TO lnCount
arrRecno[j] = aSource[j, 1] && 记录号回填用
DO CASE
CASE i = 1
arrScores[j] = aSource[j, 4] && 语文
CASE i = 2
arrScores[j] = aSource[j, 5] && 数学
CASE i = 3
arrScores[j] = aSource[j, 6] && 外语
CASE i = 4
arrScores[j] = aSource[j, 7] && 物理
CASE i = 5
arrScores[j] = aSource[j, 8] && 化学
CASE i = 6
arrScores[j] = aSource[j, 9] && 生物
CASE i = 7
* 计算总分:六科相加 (缺考0分直接加即可)
arrScores[j] = aSource[j, 4] + aSource[j, 5] + aSource[j, 6] + ;
aSource[j, 7] + aSource[j, 8] + aSource[j, 9]
ENDCASE
ENDFOR
* 调函数,获取名次数组 (注意顺序是排过序的!)
arrTmpRanks = GetJumpRank(@arrScores, lnCount)
* 核心:把排完序的名次,按原记录号回填到 arrResult 里面!
FOR j = 1 TO lnCount
* arrRecno 在第1步提取分数时,和 arrScores 是按 1:1 对应同步的
* 此时 arrRecno[j] 就是排序后,第j名那个学生的原始记录号
arrResult[ arrRecno[j] , i ] = arrTmpRanks[j]
ENDFOR
ENDFOR
* ===============================================================
* 5. 写入最终表 cj_final
FOR j = 1 TO lnCount
SELECT cj_final
APPEND BLANK
REPLACE 学号 WITH aSource[j, 2], 姓名 WITH aSource[j, 3]
REPLACE 语文 WITH aSource[j, 4], 数学 WITH aSource[j, 5]
REPLACE 外语 WITH aSource[j, 6], 物理 WITH aSource[j, 7]
REPLACE 化学 WITH aSource[j, 8], 生物 WITH aSource[j, 9]
REPLACE 总分 WITH aSource[j,4]+aSource[j,5]+aSource[j,6]+aSource[j,7]+aSource[j,8]+aSource[j,9]
* 填入刚刚算好的七个指标的名次 (1-7 依次对应 语数外物化生总分)
REPLACE 语文_年名 WITH arrResult[j, 1]
REPLACE 数学_年名 WITH arrResult[j, 2]
REPLACE 外语_年名 WITH arrResult[j, 3]
REPLACE 物理_年名 WITH arrResult[j, 4]
REPLACE 化学_年名 WITH arrResult[j, 5]
REPLACE 生物_年名 WITH arrResult[j, 6]
REPLACE 总分_年名 WITH arrResult[j, 7]
ENDFOR
* ===============================================================
* 6. 展示成果
SELECT cj_final
BROWSE TITLE "最终结果: cj_final (已包含全年级名次,含并列跳号规则)"
? "处理完成!"
SET SAFETY ON







程序代码:


