中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --
联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟
中国DOS联盟论坛
现在时间是 2026-08-10 13:03
47,811 主题排行 / 349,897 发帖 / 今日 0 篇 / 48,255 会员排行
DOS批处理 & 脚本技术(批处理室) » 关于去最大值去最小值,中间值求平均数的脚本
可打印版本  3,120 / 12
第1楼 maya0su 发表于 2006-05-24 13:26
中级用户 发帖 131 积分 241
关于去最大值去最小值,中间值求平均数的脚本
如题:
比如有一组数值,是否可以用批处理或者VBS脚本,去除其中的最大最小值,然后其余的数值求平均值?
第2楼 3742668 发表于 2006-05-25 21:28
荣誉版主 发帖 718 积分 2,013
当然可以,如果用JS的话,它带有一个排序函数:sort,用来解决是很简单的,如果用VBS,也有多种方法,最理想的莫过于利用创建断开的数据集对象来操作,可以像操作数据库一样来编辑那些数据,还能保存为各种格式的文件,不过,在中国DOS联盟,我还是给你个命令行下的批处理版吧:
第3楼 willsort 发表于 2006-05-25 22:57
元老会员 发帖 1,512 积分 4,432
Re 3742668:

很不错的方案。

只是似乎intMax的初值似应取-2147483648,或者intMax和intMin都取%1初值也是可以的。

另外,:EditNum使用了全局变量%Num%,虽然这是一个很巧妙的技巧,但它不符合局部模块不应访问全局变量的习惯,通用性被降低了,通常我们是在判断最小值和最大值的循环中求得变量和的,同时可以进行一些溢出错误处理。
第4楼 3742668 发表于 2006-05-25 23:14
荣誉版主 发帖 718 积分 2,013
对于intMax的初值开始是考虑过,不过考虑到%random%只能产生1-32767之间的数,所以就选择的是1,至于intMin用2147483647是因为觉得32767的范围似乎太小了一点,再说正整数的比较是比较常见的。
至于访问%Num%全局变量的问题,如果是用VBS或者其他的话,可能不会出现这种情况,只不过实在懒得去多写一个for来从%*获得算式,因为我认为在批处理中并不存在什么局部变量,统统都是全局变量。
第5楼 willsort 发表于 2006-05-25 23:24
元老会员 发帖 1,512 积分 4,432
Re 3742668:

你的代码不应该只能适应你的测试数据,我们无法假定测试数据必然是正整数,所以初值的修改还是必要的。

2147483647是个与环境相关的数,我们在设计算法时应避免使用,否则如果在64位的系统中可能会出现问题。

批处理中是存在局部变量的,至少在CMD中,我们可以使用setlocal来限定变量的作用域和生存周期。

如果将你的:EditNum移植到其他程序中或者直接调用它,则很可能出现问题。

求和和求个数可以在判断最小值和最大值的for循环一体实现,并不很麻烦。

[ Last edited by willsort on 2006-5-25 at 23:27 ]
第6楼 maya0su 发表于 2006-06-02 22:54
中级用户 发帖 131 积分 241
我的意思是,能不能打开后,程序等待输入数字,这些数字可能是N个,然后去大去小,最后的求平均值!
第7楼 willsort 发表于 2006-06-03 19:33
元老会员 发帖 1,512 积分 4,432
Re maya0su:

有了 3742668 兄的代码在前,编写等待输入求平均数的代码应该不是很难,根据你的要求作了相应的修改。

第8楼 maya0su 发表于 2006-07-24 14:09
中级用户 发帖 131 积分 241
又有一个新的问题出现了
我想利用另一个批处理调用此程序,从而实现循环
@echo off
:loop
cls
call itbat.bat


set /p start=是否继续?(是Y 否N)
if "%start%"=="y" goto :loop
if "%start%"=="n" goto :end

:end
exit

在实现循环的过程出现了一个现象就是
上次计算后的结果,也就是那个平均值会出现下一次的输入数中
同时也参与下一次的运算!
请问有办法解决吗?

[ Last edited by maya0su on 2006-7-24 at 14:11 ]
第9楼 namejm 发表于 2006-07-24 17:25
荣誉版主 发帖 1,737 积分 5,226 来自 成都
  问题出在call :Average %return%这一句。如果在循环调用的时候能清空%return%的值就好办了。
第10楼 zh159 发表于 2006-07-24 18:30
金牌会员 发帖 1,467 积分 3,687
直接在“call itbat.bat”后加入“set return=”不就行了么
第11楼 namejm 发表于 2006-07-24 22:09
荣誉版主 发帖 1,737 积分 5,226 来自 成都
  呵呵,楼上的,我也曾有过这样的冲动,可是,你试验过了吗?发言要慎重哦。
第12楼 zh159 发表于 2006-07-25 00:39
金牌会员 发帖 1,467 积分 3,687
Originally posted by namejm at 2006-7-24 22:09:
  呵呵,楼上的,我也曾有过这样的冲动,可是,你试验过了吗?发言要慎重哦。

改一下willsort版主的:
:: Average.cmd - Eval average of a batch of numbers
:: Will Sort - 2006-06-03 - CMD@WinXP
@echo off
set return=
call :GetNum
echo 要处理的数据为:%return%
call :Average %return%
echo 去除最大值和最小值的平均数为 %return%
goto :eof

:GetNum
if "%_n%"=="" setlocal
set _n=-
set /p _n=请输入一个整数(直接回车结束输入):
if "%_n%"=="-" endlocal&set return=%return%&goto :eof
set /a _i=_n
if "%_i%" NEQ "%_n%" (echo 无效的输入数据:%_n%
) else set return=%return% %_i%
goto GetNum

:Average
setlocal EnableDelayedExpansion
if "%3"=="" set return=N/A&goto :eof
set /a iMax=%1,iMin=%1
for %%i in (%*) do (
if %%i GTR !iMax! set /a iMax=%%i
if %%i LSS !iMin! set /a iMin=%%i
set /a iTotal+=%%i
set /a iCount+=1
)
set /a return=(iTotal-iMax-iMin) / (iCount-2)
endlocal&set return=%return%&goto :eof
set return=

OK

或者maya0su的:
@echo off
:loop
cls
set return=
call itbat.bat
set return=


set /p start=是否继续?(是Y 否N)
if "%start%"=="y" goto :loop
if "%start%"=="n" goto :end

:end
exit

也OK

[ Last edited by zxcv on 2006-7-25 at 00:41 ]
第13楼 namejm 发表于 2006-07-25 12:50
荣誉版主 发帖 1,737 积分 5,226 来自 成都
  原来是要加两处,zxcv的代码不错。看来自己得对 call 标号 参数 的格式多加揣摩才是。
[ 联系联盟系统管理团队 - 中国DOS联盟 - 标准版 ]
Sponsored by ifanr Inc | © 2001–2023