[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
看到题目我起劲了, 回一个楼主, 关于 "非B", 对集合是补运算吧, 而 "非" 是逻辑运算

TOP

回复 4楼 的帖子

提到了 "列举集合中的每一个数", 这样是不能高效的, 建议思路是, 将每个集合当成若干个子集来处理, 每个子集都有一个下限和一个上限, 求运算时, 依序对两个操作数 集合 的两个子集 的 4 个上下限进行比较, 依据运算生成结果 集合 的子集的上下限, 直到结果集合的全部子集上下限都生成, 最后再来一个 "相邻" 子集合并, 即 如 [3,19] 和 [20, 37] 就合并成 [3,37], 当然这个合并不是必要的, 其中子集处理中, 即使是一个 单独的数, 也可以看成一个集合, 如 1 看成 [1,1], 这样就去除了单独数的特殊性.
1

评分人数

TOP

先做个并集的, 以后再抽空做个交集的, 补集难度较小, 暂不支持元素重复, 逆序排列
  1. @echo off&setlocal enabledelayedexpansion
  2. set /p debug=要以调试方式运行吗?[y/n][直接回车=n]:
  3. set LMin=1
  4. :getLUFlag
  5.   set /a "LMin<<=1"
  6.   if %LMin% lss 0 set /a UMax=-(LMin+1)&goto :endLUFlag
  7. goto :getLUFlag
  8. :endLUFlag
  9. echo 小于全集下限的标志数值=%LMin%, 大于全集上限的标志数值=%UMax%
  10. set "X={[-71,-54],[3,6],10,[20,30],  [32,60],[200,  3000  ],5000,[6000,8000],9000,9500}"
  11. set "Y={-66,-33,2,5,31,[300,500],[8000,9000],9500, 9876, 9932}"
  12. (call :initSet X&call :outputSet X&call :initSet Y&call :outputSet Y)
  13. (call :Union X Y XUY&call :outputSet XUY)
  14. echo 任意键退出&pause>nul
  15. exit /b
  16. :initSet
  17. set "%1=!%1: =!" & set "%1=!%1:{=!" & set "%1=!%1:}=!"
  18. set "pnt%1=0" & set "flag=CN"
  19. for %%i in (!%1!) do (
  20.   set "tt=%%i"
  21.   if "!tt:~0,1!"=="[" (
  22.     if "!flag!" equ "L" (echo 集合%1语法错误:%%i&pause&goto :err)
  23.     set "flag=L"
  24.     set /a pnt%1+=1&set "%1L!pnt%1!=!tt:~1!"
  25.   ) else if "!tt:~-1!"=="]" (
  26.     if "!flag!" neq "L" (echo 集合%1语法错误:%%i&pause&goto :err)
  27.     set "flag=R"
  28.     set "%1U!pnt%1!=!tt:~0,-1!"  
  29.   ) else if "!flag!" equ "L"  (echo 集合%1语法错误:%%i&pause&goto :err
  30.   ) else set /a pnt%1+=1&set "%1L!pnt%1!=!tt!"&set "%1U!pnt%1!=!tt!"&set "flag=CN"
  31. )
  32. set /a pnt%1+=1&set "%1L!pnt%1!=!UMax!"&set "%1U!pnt%1!=!UMax!"
  33. exit /b
  34. :Union A B A∪B
  35. (call :copySet %1 A&call :copySet %2 B)
  36. set /a "pntA=1,pntB=1,pntR=0"&(set RL0=%LMin%&set RU0=%LMin%)
  37. :UnionLoop
  38. if "!RL%pntR%!"=="!UMax!" echo 并集完成&goto :returnUnionValue
  39. :UnionSch1
  40. if !AU%pntA%! leq !RU%pntR%! set /a "pntA+=1"&goto :UnionSch1
  41. if !AL%pntA%! leq !RU%pntR%! set "RU!pntR!=!AU%pntA%!"
  42. :UnionSch2
  43. if !BU%pntB%! leq !RU%pntR%! set /a "pntB+=1"&goto :UnionSch2
  44. if !BL%pntB%! leq !RU%pntR%! set "RU!pntR!=!BU%pntB%!"
  45. set "intersec=Y"
  46. if !AL%pntA%! gtr !BU%pntB%! (set "intersec=N") else (
  47.   if !BL%pntB%! gtr !AU%pntA%! set "intersec=N")
  48. set /a pntR+=1
  49. (call :min !AL%pntA%! !BL%pntB%! RL!pntR!)
  50. if "!intersec!"=="Y" (call :max !AU%pntA%! !BU%pntB%! RU!pntR!) else (
  51.   call :min !AU%pntA%! !BU%pntB%! RU!pntR!)
  52. if /i "!debug!"=="y" (
  53.   echo pntA=!pntA!,pntB=!pntB!,pntR=!pntR!,intersec=!intersec!
  54.   call :outputSet R
  55. )
  56. goto :UnionLoop
  57. :returnUnionValue
  58. (call :copySet R %3)
  59. exit /b
  60. :copySet src dest
  61. for /l %%i in (1 1 10000) do (
  62.   if "!%1L%%i!"=="" (exit /b) else (set %2L%%i=!%1L%%i!&set %2U%%i=!%1U%%i!)
  63. )
  64. exit /b
  65. :min a b min (a,b 以串值调用, min 以变量名调用)
  66. if %1 lss %2 (set %3=%1) else (set %3=%2)
  67. exit /b
  68. :max a b max (a,b 以串值调用, max 以变量名调用)
  69. if %1 gtr %2 (set %3=%1) else (set %3=%2)
  70. exit /b
  71. :outputSet
  72. set /p=%1=<nul
  73. for /l %%i in (1 1 10000) do (
  74.   if "!%1L%%i!"=="" (echo  &exit /b) else set /p=[!%1L%%i!,!%1U%%i!],<nul
  75. )
  76. exit /b
  77. :err
  78. echo 错误, 任意键退出&pause
  79. exit /b
复制代码

TOP

交, 并, 补 完全求解, 但不考虑集合描述中 元素重复, 逆序排列
  1. @echo off&setlocal enabledelayedexpansion
  2. (set LOut=')&(set UOut=Z)& rem 在集合最后面加一个假子集 [UOut, UOut] 作为尾部标志
  3. rem echo 小于全集下限的标志=%LOut%, 大于全集上限的标志=%UOut%
  4. call :getUniverseLU& rem echo 全集U={[!universeL!,!universeU!]}
  5. set "I={[1,100000]}"& rem 题目指定的小全集
  6. set "X={1,[3,6],10,[20,30],[32,60],[200,3000],5000,[6000,8000],9000,9500}"
  7. set "Y={2,5,31,[300,500],[8000,9000],9500}"
  8. (call :initSet I) & (call :initSet X) & (call :initSet Y)
  9. (call :outputSet X) & (call :outputSet Y)
  10. call :Union X Y X∪Y
  11. call :Complement Y Y1
  12. call :Inter I Y1 _Y
  13. call :Inter X _Y X∩_Y
  14. call :Simplify X∪Y
  15. call :outputSet X∪Y
  16. call :Simplify X∩_Y
  17. call :outputSet X∩_Y
  18. echo 任意键退出&pause>nul
  19. exit /b
  20. :Union A B A∪B
  21. (call :copySet %1 A&call :copySet %2 B&call :clearSet R)
  22. set /a "pntA=1,pntB=1,pntR=0"&(set RL0=%LOut%&set RU0=%LOut%)
  23. :UnionLoop
  24. if "!RL%pntR%!"=="!UOut!" (call :copySet R %3)&exit /b
  25. :UnionSch1
  26. if !AU%pntA%! leq !RU%pntR%! set /a "pntA+=1"&goto :UnionSch1
  27. if !AL%pntA%! leq !RU%pntR%! set "RU!pntR!=!AU%pntA%!"
  28. :UnionSch2
  29. if !BU%pntB%! leq !RU%pntR%! set /a "pntB+=1"&goto :UnionSch2
  30. if !BL%pntB%! leq !RU%pntR%! set "RU!pntR!=!BU%pntB%!"
  31. set "intersec=Y"
  32. if !AL%pntA%! gtr !BU%pntB%! (set "intersec=N") else (
  33.   if !BL%pntB%! gtr !AU%pntA%! set "intersec=N")
  34. set /a "pntR+=1"
  35. (call :min !AL%pntA%! !BL%pntB%! RL!pntR!)
  36. if "!intersec!"=="Y" (call :max !AU%pntA%! !BU%pntB%! RU!pntR!) else (
  37.   call :min !AU%pntA%! !BU%pntB%! RU!pntR!)
  38. goto :UnionLoop
  39. exit /b
  40. :Inter A B A∩B
  41. (call :copySet %1 A&call :copySet %2 B&call :clearSet R)
  42. set /a "pntA=1,pntB=1,pntR=0"&(set RL0=%LOut%&set RU0=%LOut%)
  43. :InterLoop
  44. if "!RL%pntR%!"=="!UOut!" (call :copySet R %3)&exit /b
  45. :InterSch1
  46. if !AU%pntA%! lss !BL%pntB%! set /a "pntA+=1"&goto :InterSch1
  47. :InterSch2
  48. if !BU%pntB%! lss !AL%pntA%! set /a "pntB+=1"&goto :InterSch2
  49. if !AU%pntA%! lss !BL%pntB%! goto :InterSch1
  50. set /a "pntR+=1"
  51. (call :max !AL%pntA%! !BL%pntB%! RL!pntR!)
  52. (call :min !AU%pntA%! !BU%pntB%! RU!pntR!)
  53. if !AU%pntA%! lss !BU%pntB%! (set /a "pntA+=1") else set /a "pntB+=1"
  54. goto :InterLoop
  55. exit /b
  56. :copySet src dest
  57. call :clearSet %2
  58. for /l %%i in (1 1 10000) do (
  59.   if "!%1L%%i!"=="" (exit /b) else (set %2L%%i=!%1L%%i!&set %2U%%i=!%1U%%i!)
  60. )
  61. exit /b
  62. :min a b min (a,b 以串值调用, min 以变量名调用)
  63. if %1 lss %2 (set %3=%1) else (set %3=%2)
  64. exit /b
  65. :max a b max (a,b 以串值调用, max 以变量名调用)
  66. if %1 gtr %2 (set %3=%1) else (set %3=%2)
  67. exit /b
  68. :outputSet
  69. (set lastout=')
  70. set /p=%1={<nul
  71. if "!%1L1!"=="" echo }&exit /b
  72. for /l %%i in (1 1 10000) do (
  73.   if "!%1L%%i!"=="" (if %%i neq 1 (echo }) else echo })&exit /b
  74.   if "!%1L%%i!"=="!UOut!" (
  75.     (if %%i neq 1 (echo }) else echo })&exit /b
  76.   ) else if !%1L%%i! gtr !lastout! (
  77.     if !%1L%%i! neq !%1U%%i! (
  78.       set /p=[!%1L%%i!,!%1U%%i!],<nul
  79.     ) else set /p=!%1L%%i!,<nul
  80.     (set lastout=!%1U%%i!)
  81.   )
  82. )
  83. exit /b
  84. :clearSet
  85. for /l %%i in (1 1 10000) do (
  86.   if "!%1L%%i!"=="" (exit /b) else (set %1L%%i=&set %1U%%i=)
  87. )
  88. exit /b
  89. :err
  90. echo 错误, 任意键退出&pause
  91. exit /b
  92. :getUniverseLU
  93. set "universeL=1"
  94. :get_uniLU
  95.   set /a "universeL<<=1"
  96.   if %universeL% lss 0 (set /a "universeU=-(universeL+1), universeL=0"&exit /b) else goto :get_uniLU
  97. exit /b
  98. :Complement A compA
  99. (call :copySet %1 A&call :clearSet R)
  100. (set /a pntA=0, pntN=pntA+1, pntR=0)
  101. if !AL1! neq !universeL! (
  102.   set tL=!universeL!& set /a "tU=AL1-1"
  103. ) else (
  104.   set /a "pntA+=1"
  105.   if !AU1! lss !universeU! (
  106.     set /a "tL=AU1+1"
  107.     if "!AL2!" neq "!UOut!" (set /a tU=AL2-1) else set "tU=!universeU!"
  108.   ) else ( rem 补为空
  109.     (set /a "pntR+=1"&set RL!pntR!=!UOut!&set RU!pntR!=!UOut!)&(call :copySet R %2)&exit /b
  110.   )
  111. )
  112. :ComplementLoop
  113. if !tU! geq !tL! (
  114.   (set /a "pntR+=1"&set RL!pntR!=!tL!&set RU!pntR!=!tU!)
  115.   if !tU! geq !universeU! (
  116.     (set /a "pntR+=1"&set RL!pntR!=!UOut!&set RU!pntR!=!UOut!)&(call :copySet R %2)&exit /b
  117.   )
  118. )
  119. set /a "pntA+=1, pntN=pntA+1"
  120. set /a "tL=AU!pntA!+1"
  121. if !AL%pntN%!==!UOut! (set "tU=!universeU!") else set /a "tU=!AL%pntN%!-1"
  122. goto :ComplementLoop
  123. exit /b
  124. :Simplify A 仅用于最后输出之前(不再做任何运算), 将相邻子集合并
  125. (call :copySet %1 A)&(set /a pntA=0, pntN=pntA+1)&set "AU0=!LOut!"
  126. :SimplifyLoop
  127. if "!AL%pntN%!"=="!UOut!" (call :copySet A %1)&exit /b
  128. set /a "tt=AL!pntN!-1"
  129. if "!AU%pntA%!" equ "!tt!" (
  130.   set "AU!pntA!=!AU%pntN%!"
  131.   set /a "pntN+=1"
  132. ) else set /a "pntA=pntN,pntN+=1"
  133. goto :SimplifyLoop
  134. exit /b
  135. :initSet
  136. set "%1=!%1: =!" & set "%1=!%1:{=!" & set "%1=!%1:}=!"
  137. set "pnt%1=0" & set "flag=CN"
  138. for %%i in (!%1!) do (
  139.   set "tt=%%i"
  140.   if "!tt:~0,1!"=="[" (
  141.     if "!flag!" equ "L" (echo 集合%1语法错误:%%i&pause&goto :err)
  142.     set "flag=L"
  143.     set /a pnt%1+=1&set "%1L!pnt%1!=!tt:~1!"
  144.   ) else if "!tt:~-1!"=="]" (
  145.     if "!flag!" neq "L" (echo 集合%1语法错误:%%i&pause&goto :err)
  146.     set "flag=R"
  147.     set "%1U!pnt%1!=!tt:~0,-1!"  
  148.   ) else if "!flag!" equ "L"  (echo 集合%1语法错误:%%i&pause&goto :err
  149.   ) else set /a pnt%1+=1&set "%1L!pnt%1!=!tt!"&set "%1U!pnt%1!=!tt!"&set "flag=CN"
  150. )
  151. set /a pnt%1+=1&set "%1L!pnt%1!=!UOut!"&set "%1U!pnt%1!=!UOut!"
  152. exit /b
复制代码

[ 本帖最后由 neorobin 于 2010-4-17 22:35 编辑 ]

TOP

返回列表