找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
楼主: 思想之翼

[其他] 【已解决】BAT:多次随机组合不重复的字符,如何控制各字符总数均等

[复制链接]
发表于 2023-9-3 16:44:24 | 显示全部楼层
Test.js
  1. var arr = [];
  2. var tmp = [];
  3. var fso = new ActiveXObject('Scripting.FileSystemObject');

  4. for(var i=100; i<=199; i++) tmp.push( (''+i).substr(1) );

  5. for(var i=1; i<=500; i++){
  6.     tmp.sort(function(){return Math.random()>0.5 ? 1 : -1});
  7.     var str = tmp.join(' ');
  8.     str = str.replace(/^((?:\d\d ){49}\d\d) /, '$1\r\n');
  9.     arr.push(str);
  10. }

  11. fso.OpenTextFile('1.txt', 2, true).Write(arr.join('\r\n'));

  12. WSH.Echo('Done');
复制代码

评分

参与人数 2技术 +2 收起 理由
buyiyang + 1 好算法
思想之翼 + 1 感谢!符合题意,速度快。

查看全部评分

发表于 2023-9-3 16:46:55 | 显示全部楼层
Test.ps1
  1. $arr = (100..199) -replace '^1';
  2. $out = [Collections.ArrayList]@();

  3. for ($i=1; $i -le 500; $i++) {
  4.     $arr = Get-Random $arr -Count $arr.Count;
  5.     [void]$out.Add($arr[0..49] -join ' ');
  6.     [void]$out.Add($arr[50..99] -join ' ');
  7. }

  8. [IO.File]::WriteAllLines('1.txt', $out);
复制代码

评分

参与人数 2技术 +2 收起 理由
思想之翼 + 1 感谢!符合题意,速度快。
77七 + 1 神奇!ps如此简洁

查看全部评分

发表于 2023-9-3 17:29:24 | 显示全部楼层
回复 17# WHY


    这样是不是有点不随机了  比如任意一个值在第一行出现后就不可能在第二行出现。
发表于 2023-9-3 17:49:02 | 显示全部楼层
额,确实像这样排好再打乱简单方便快速准确,不过输出顺序应该再打乱一次
发表于 2023-9-3 18:18:40 | 显示全部楼层
回复 18# pd1


    是的,如果一个数(比如01)第一行、第二行都出现,有可能总数会超过500个,不符合题意。
如果有必要,可以在第10行上面插入一行:
  1. $out = Get-Random $out -Count $out.Count
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

发表于 2023-9-3 19:13:53 | 显示全部楼层
本帖最后由 77七 于 2023-9-3 20:35 编辑

下午用定义行号和数字也写了个,但是在某一行,应该是出现有51个数已经用了500次...总是陷入死循环
WHY大佬直接将00-99一组分为两行,非常巧妙。
用批处理参考此思路也写了个,打乱排序需要2分钟,效率还是不行...,不打乱排序快点,
优化了下,打乱排序17秒
  1. @echo off
  2. %1 (for /f "tokens=2 delims==" %%a in ('%0 rem^|sort') do (echo %%a))>1.txt&pause&exit
  3. for /l %%l in (1001,1,1500) do (
  4.         setlocal enabledelayedexpansion
  5.         for /l %%k in (100,1,199) do (
  6.                 set str=%%k
  7.                 set #!random!#%%k=!str:~-2!
  8.         )
  9.         for /f "tokens=2 delims==" %%a in ('set #') do (
  10.                 set str2=%%a !str2!
  11.         )
  12.         echo !random!#%%l1=!str2:~0,149!
  13.         echo !random!#%%l2=!str2:~150,149!
  14.         endlocal
  15. )
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

发表于 2023-9-4 09:32:45 | 显示全部楼层
和楼上的基本相似,理了理思路,这样代码更易懂:
  1. @echo off
  2. (for /l %%i in (1,1,500) do (
  3.     setlocal enabledelayedexpansion
  4.     for /l %%j in (0,1,99) do (
  5.         set /a n+=1
  6.         if %%j lss 10 (
  7.             set _!random!-!n!=0%%j
  8.         ) else (
  9.             set _!random!-!n!=%%j
  10.         )
  11.     )
  12.     for /f "tokens=2 delims==" %%k in ('set _') do (
  13.         set /a m+=1
  14.         if !m! leq 50 (
  15.             set str1=!str1! %%k
  16.         ) else (
  17.             set str2=!str2! %%k
  18.         )
  19.     )
  20.     echo,!str1!
  21.     echo,!str2!
  22.     endlocal
  23. ))>1.txt
  24. pause
复制代码

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

发表于 2023-9-4 10:29:16 | 显示全部楼层
回复 20# WHY
所以我感觉这个是一个算法题,需要判断如果超过500个了就不再使用它了,还得考虑的一个点是500-任意一个值已经使用过的次数不能大于剩余生成的行数。
不过既然楼主对数据没有这方面的需求,你的这个方法还是比较巧妙的。

评分

参与人数 1技术 +1 收起 理由
buyiyang + 1 确实如此

查看全部评分

发表于 2023-9-4 11:34:40 | 显示全部楼层
回复 23# pd1
是算术题,1002行重复个数就是501,2000行个数就是1000。
发表于 2023-9-4 13:13:27 | 显示全部楼层
本帖最后由 qixiaobin0715 于 2023-9-4 13:15 编辑

回复 18# pd1
我觉得WHY的思路没有问题。楼主的题目要求决定了只要出现一行随机数,必定要跟随互补的另一行。可以自己手工排排看,按最简单4行或6行,每个数出现2次或3次。只不过代码输出的是:单数行紧跟一偶数行,为互补行,给人表面的感觉不是随机的,实际上互补行是必须出现的。如果按照楼主的要求,最终数据都是两两互补,没有意外,只是出现的位置可以不同而已。

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

发表于 2023-9-4 14:23:59 | 显示全部楼层
回复 25# qixiaobin0715
我也说了思路没问题啊,只是没那么随机,可能如果要生成的数据量足够多才能必然出现互补行吧,虽然我没计算过到底需要多少行才出现,我也不会算。

    举个小例子,0-9  每个出现2次
01234
56789
03579
12468

上面是生产的12互补,34互补
把2行的7和4行的4换一下,有没有互补行呢
01234
56489
03579
12768

所以你是如何得出必有互补行的

评分

参与人数 1技术 +1 收起 理由
思想之翼 + 1 感谢分享

查看全部评分

发表于 2023-9-4 14:35:06 | 显示全部楼层
回复 26# pd1
唐突了,是我自己考虑欠妥。
发表于 2023-9-4 14:36:04 | 显示全部楼层
本帖最后由 buyiyang 于 2023-9-4 14:38 编辑

回复 23# pd1


    这个算法题还是有点复杂,我一开始只判断某数使用次数达500次就不再使用,结果到980多行时就没有50个数可使用了(比如999行时,75个数使用了500次,25个数使用了498次),我实在没有什么好的办法解决这个问题。你说的“500-任意一个值已经使用过的次数不能大于剩余生成的行数”也不行
发表于 2023-9-4 14:40:40 | 显示全部楼层
本帖最后由 buyiyang 于 2023-9-4 14:43 编辑

回复 26# pd1


    0-9随机10行每个数出现5次就会互补。
发表于 2023-9-4 14:45:25 | 显示全部楼层
回复 23# pd1
又看了看,开始回复23楼的帖子也是文不对题,没有理解你所说的意思,抱歉。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 05:41 , Processed in 0.021567 second(s), 7 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表