Board logo

标题: [其他] [已解决]批处理删除给定数字串的一部分使剩余数字升序或降序排列 [打印本页]

作者: 基拉freedom    时间: 2009-10-2 10:18     标题: [已解决]批处理删除给定数字串的一部分使剩余数字升序或降序排列

偶尔看到这一个问题
例子:
  1. 1 2 55 3 4 5 1 7 8 9
  2. 然后结果是
  3. 删去 55 1
  4. 或者直接给出排列好的数列 1 2 3 4 5 7 8 9
复制代码
如果用数直接比对以前的数 那效率一定很低 这里求代码的简约 高效
大家有什么好的方案
注:
数字不能换位子
例如 1 2 3 4 5 6 10 9
答案应为 1 2 3 4 5 6 9
而不是1 2 3 4 5 6 9 10
8L的说得对
基础的 那只要求以第一个数为基准 给出一种答案就可以了 但升序的数组不可以有遗留哦
也就是本来可以1 2 3 4 5 6 9的 不能少数字 变成 1 3 4 5 6 9或其他的
加深的:
找出删去数最少 也就是令这个升序数组最长的答案

[ 本帖最后由 基拉freedom 于 2009-10-2 20:41 编辑 ]
作者: terse    时间: 2009-10-2 11:58

就批处理而言 冒泡排还是快的
然后在循环里判断连续数否
作者: 基拉freedom    时间: 2009-10-2 12:03

但这样怎么实现呢
因为排序后位置都改变了 怎么能知道要删除去的是那个数呢?
作者: terse    时间: 2009-10-2 13:17

前面排序都一样 后面判断稍不同
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str=1 2 55 3 4 5 1 7 8 9"
  3. for %%i in (!str!) do (
  4.     if not defined .%%i (
  5.        set /a n+=1
  6.        set "_!n!=%%i"&set .%%i=a
  7.   ))
  8.          set /a m=n-1
  9.          for /l %%i in (1,1,!m!) do (
  10.          set /a e=%%i+1
  11.          for /l %%j in (!e!,1,!n!) do (
  12.          if !_%%i! gtr !_%%j! set/a _%%j=!_%%i!,_%%i=!_%%j!
  13.         )
  14.      )
  15.     for /l %%i in (1,1,!n!) do (
  16.     if !s1! equ !_%%i! (
  17.     set/a s1-=1
  18.     if defined ..!s1! (set var=!var! !_%%i!)else set var=!var! !s1! !_%%i!
  19.     set ..!_%%i!=.
  20.    )
  21.     set/a s1=_%%i+1
  22. )
  23. echo!var!
  24. pause
复制代码
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str=2 2 12 3 4 5 11 7 8 9"
  3. for %%i in (!str!) do (
  4.     if not defined .%%i (
  5.        set /a n+=1
  6.        set "_!n!=%%i"&set .%%i=a
  7.   ))
  8.          set /a m=n-1
  9.          for /l %%i in (1,1,!m!) do (
  10.          set /a e=%%i+1
  11.          for /l %%j in (!e!,1,!n!) do (
  12.          if !_%%i! gtr !_%%j! set/a _%%j=!_%%i!,_%%i=!_%%j!
  13.         )
  14.      )
  15.     for /l %%i in (1,1,!n!) do (
  16.     if not defined a1 (set/a a1=_%%i,m=1)else (
  17.     set/a "an=a1+m-1"
  18.     if !an! equ !_%%i! (
  19.     if !m! equ 2 (set var=!var! !a1! !an!) else set var=!var! !an!
  20.   ) else set/a a1=_%%i,m=1
  21. )
  22. set /a m+=1
  23. )
  24. echo!var!
  25. pause
复制代码

[ 本帖最后由 terse 于 2009-10-2 13:23 编辑 ]
作者: 基拉freedom    时间: 2009-10-2 13:57

第二个不好 不满足 不能换数字的位置 只能删
第一个也一样不行
例如 改一下
set "str=1 2 55 3 4 5 6 7 8 10 9"
他的输出居然是
1 2 3 4 5 6 7 8 9 10
输入的10可是在9前面的.........还得再想想
作者: terse    时间: 2009-10-2 15:13

不是说排序的吗?
结果出来就是排好序的啊
作者: 基拉freedom    时间: 2009-10-2 15:15

是排序
但数字的位置不能变
只能删除其中的数字 让剩下的呈升序排列
我没说清楚 对不起了
作者: slore    时间: 2009-10-2 16:03

1 2 55 3 4 5 56 7 8 9

1>.删去55 56后
1 2 3 4 5 7 8 9有序

2>.删去1 2 3 4 5 7 8 9 后
55 56 有序

3>.删去3 4 5 7 8 9后
1 2 55 56有序
……

这个规则不够严谨的话。。。
作者: 基拉freedom    时间: 2009-10-2 16:09

恩 ls说的对
所以这里只要求给出一种就可以了
即以第一个数为基准
作者: terse    时间: 2009-10-2 16:22

可能是我理解不够
要是以第一个数为基准 那就直接在数组里找吧 排序也不要
让N + 1 递增 然后 标记
另数组 ”54 11 56 2 55 3 5 4 1 7 56 56 8 10“
最终结果是?

[ 本帖最后由 terse 于 2009-10-2 16:34 编辑 ]
作者: 基拉freedom    时间: 2009-10-2 16:38

54 56
其实题目可以加深 例如求删除最少的数 输出最长的
可惜我还没怎么想出来 哎
作者: bhsx    时间: 2009-10-2 16:47

  1. @echo off&setlocal enabledelayedexpansion
  2. for %%i in (1 1 2 55 3 4 5 1 7 8 9 10) do (
  3. set ...%%i=0000%%i
  4. set /a ...count%%i+=1
  5. set ...!...%%i:~-4!=%%i=!...count%%i!
  6. set ...%%i=
  7. )
  8. for /f "tokens=1,2,* delims==" %%i in ('set ...') do (
  9. for /l %%x in (1,1,%%k) do set /p =%%j <nul)
复制代码
不知道高不高效.......

[ 本帖最后由 bhsx 于 2009-10-2 16:48 编辑 ]
作者: 基拉freedom    时间: 2009-10-2 17:16

传说中 题目变成最简单的了
只需找出就好了
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set /p a=输入一串数字
  4. set n=1
  5. for %%i in (%a%) do (
  6. set _!n!=%%i
  7. set /a n=!n!+1
  8. )
  9. set x=0
  10. set max=%_1%
  11. set /p=%max% <nul
  12. for /l %%i in (2 1 !n!-1) do (
  13. set /a "x=_%%i-max"
  14. if !x! gtr 0 set /p=!_%%i! <nul & set max= &set max=!_%%i!
  15. )
  16. pause
复制代码
其实原意是要向8L那样的 然后举出最长的数列....那个才是最难得 哎
作者: terse    时间: 2009-10-2 17:32

输入 54 11 56 2 55 3 5 4 1 7 56 56 8 10
怎么结果:54  57
并不是你要的  54  56
作者: bhsx    时间: 2009-10-2 17:40

上面代码输入1 2 55 3 4 5 1 7 8 9
结果是 1 2  55

[ 本帖最后由 bhsx 于 2009-10-2 17:44 编辑 ]
作者: bhsx    时间: 2009-10-2 17:48

例如 1 2 3 4 5 6 10 9
答案应为 1 2 3 4 5 6 9
而不是1 2 3 4 5 6 9 10
8L的说得对
基础的 那只要求以第一个数为基准 给出一种答案就可以了 但升序的数组不可以有遗留哦
也就是本来可以1 2 3 4 5 6 9的 不能少数字 变成 1 3 4 5 6 9或其他的

1 2 3 4 5 6 10 也行??

[ 本帖最后由 bhsx 于 2009-10-2 17:53 编辑 ]
作者: Seter    时间: 2009-10-2 18:41

同样的题目我用C做过,使用DP算法完美解决...我去温习下看看能不能做...
作者: Seter    时间: 2009-10-2 20:21

  1. @setlocal enabledelayedexpansion&set/pk=&set i=1
  2. @for %%i in (%k%) do @set/ai+=1&set m=0&set r=&(@for /l %%j in (1,1,!i!) do @if !e%%j! lss %%i if !m! lss !l%%j! set m=!l%%j!&set r=!r%%j!)&set r!i!=!r! %%i&set/a l!i!=m+1&set e!i!=%%i
  3. @echo!r%i%!&pause
复制代码
253B[最近疯狂于文本缩减]

[ 本帖最后由 Seter 于 2009-10-2 20:45 编辑 ]
作者: Seter    时间: 2009-10-2 20:42

嘿嘿,多谢基拉大大...考验你手工分段的时候到了!
作者: 基拉freedom    时间: 2009-10-2 20:55


分割好了
还要慢慢理解
代码有点不太完美 不过也差不多了
很是感谢 这个问题是偶尔从书中找到的 只要叫我们自己找找
测试了一下
23 12 14 15 16 17 18 19 4564 213 456 123 456 789 56 231
12 14 15 16 17 18 19 213 231
最长的数列其实应为
12 14 15 16 17 18 19 123(或213) 456 789
作者: 基拉freedom    时间: 2009-10-2 21:23

思路看懂了
看来代码必须多研究才可以
再次说声谢谢 你的代码是找此数列中大小相近(我也说不大清楚)的数列吧 很不错的思路
分割好的:
  1. @echo off&setlocal enabledelayedexpansion
  2. set/p k=请输入数字:
  3. set i=1
  4. for %%i in (%k%) do (
  5. set /a i+=1
  6. set m=0
  7. set "r="
  8. for /l %%j in (1,1,!i!) do (
  9. if !e%%j! lss %%i if !m! lss !l%%j! set m=!l%%j!&set "r=!r%%j!"
  10. )
  11. set "r!i!=!r! %%i"
  12. set/a "l!i!=m+1"
  13. set e!i!=%%i
  14. )
  15. @echo !r%i%!
  16. pause
复制代码

[ 本帖最后由 基拉freedom 于 2009-10-2 21:24 编辑 ]
作者: slore    时间: 2009-10-2 23:23

貌似都不全。。。
1 5 2 6 3

应该得:
1 2 3
1 5 6

有得全解的思路,懒的写了。。。bat操作数组不好,不方便。
作者: Seter    时间: 2009-10-3 07:58

原帖由 slore 于 2009-10-2 23:23 发表
貌似都不全。。。
1 5 2 6 3

应该得:
1 2 3
1 5 6

有得全解的思路,懒的写了。。。bat操作数组不好,不方便。

只求单解嘛,否则太麻烦...批中用不了数据结构的,
作者: Seter    时间: 2009-10-3 08:00

SORRY,我的代码有问题!
输入数据的最后那个数字不一定要使用...

[ 本帖最后由 Seter 于 2009-10-3 08:28 编辑 ]
作者: Seter    时间: 2009-10-3 08:15

其实思路很简单
假设数据为a(1),a(2),a(3),...a(k)
到a(i)的最长长度为MaxLen(i)
  1. MaxLen(1)=1
  2. MaxLen(i)=Max{MaxLen(1),MaxLen(2),...MaxLen(i-1)}+1
  3. MaxLen(1)至MaxLen(i-1)中,若a(j)>a(i),则不计入,即MaxLen(j)暂时为0
复制代码

要知道最后的字符串加个变量就OK了(我加r1,r2,r3...的)

[ 本帖最后由 Seter 于 2009-10-3 08:17 编辑 ]
作者: Seter    时间: 2009-10-3 08:27

  1. @echo off&setlocal enabledelayedexpansion&set/pk=&set i=1
  2. (for %%i in (%k%) do set/ai+=1&set m=0&set r=&(for /l %%j in (1,1,!i!) do if !e%%j! lss %%i if !m! lss !l%%j! set m=!l%%j!&set r=!r%%j!)&set r!i!=!r! %%i&set/al!i!=m+1&set e!i!=%%i)&set m=!l1!&set r=!r1!&for /l %%i in (2,1,!i!) do if !m! lss !l%%i! set m=!l%%i!&set r=!r%%i!
  3. echo%r%&pause
复制代码
348B....
作者: Seter    时间: 2009-10-3 08:39

来个小水
基拉大大不会是大学生吧...
刚找到这题了,不过不是批的,是浙江大学的网络ACM的一道题,Longest Ordered Subsequence(http://acm.zju.edu.cn/ 网上第2136题)
咳咳...大学生水平也不过如此...
作者: 基拉freedom    时间: 2009-10-3 18:37

回27楼的.......我才高中 只是对这种算法好奇而已
我还得多学习多学习
作者: Seter    时间: 2009-10-3 18:57

回28楼的,高中也比我大啊....这个东西我一开始也做不出来,后来看了本DP(动态规划)的书就豁然开朗了...
  1. MaxLen(k)的值,就是在a(k)左边,重点数值小于a(k),且长度最大的那个上升子序列的长度再加1.因为a(k)左边任何终点小于a(k)的子序列,加上a(k)后就能形成一个更长的子序列
复制代码

作者: 基拉freedom    时间: 2009-10-3 19:07


我再想想
DP没学过 算法接触很少 现在连个回溯都搞不清楚 惭愧啊 惭愧
作者: 基拉freedom    时间: 2009-10-3 19:50

裁开的代码
中间觉得多余的地方改了改 不知道有没有改错:
  1. @echo off&setlocal enabledelayedexpansion
  2. set/pk=
  3. set i=1
  4. for %%i in (%k%) do (
  5. set/a i+=1
  6. set m=0
  7. set r=
  8. for /l %%j in (2,1,!i!-1) do (
  9. if !e%%j! lss %%i if !m! lss !l%%j! set m=!l%%j!&set r=!r%%j!
  10. )
  11. set r!i!=!r! %%i
  12. set/a l!i!=m+1
  13. set e!i!=%%i
  14. )
  15. set m=!l1!
  16. set r=!r1!
  17. for /l %%i in (2,1,!i!) do if !m! lss !l%%i! set m=!l%%i!&set r=!r%%i!
  18. echo%r%
  19. pause
复制代码

作者: Seter    时间: 2009-10-4 07:30

  1. @echo off&setlocal enabledelayedexpansion
  2. set/pk=
  3. set i=1
  4. for %%i in (%k%) do (
  5. set/ai+=1
  6. set m=0
  7. set r=
  8. for /l %%j in (1,1,!i!) do (
  9. if !e%%j! lss %%i (
  10. if !m! lss !l%%j! (
  11. set m=!l%%j!
  12. set r=!r%%j!
  13. )
  14. )
  15. )
  16. set r!i!=!r! %%i
  17. set/al!i!=m+1
  18. set e!i!=%%i
  19. )
  20. set m=!l1!
  21. set r=!r1!
  22. for /l %%i in (2,1,!i!) do (
  23. if !m! lss !l%%i! (
  24. set m=!l%%i!
  25. set r=!r%%i!
  26. )
  27. )
  28. echo%r%
  29. pause
复制代码
你改的是第二个for,1,1,!i!改成2,1,!i!-1了吧
i-1可以明白,但为什么要从2循环起呢?
作者: 基拉freedom    时间: 2009-10-4 09:01

因为
l1和r1的值为空 比较后 赋的值的也是空
不知道这样理解有没有错
作者: Seter    时间: 2009-10-4 09:07

回楼上,本来set/ai+=1放下面的,但忘记改了...所以没注意到...




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2