标题: 【练习-062】找出文本中内容完全相同的列 [打印本页]
作者: batman 时间: 2011-3-10 01:02 标题: 【练习-062】找出文本中内容完全相同的列
出题目的:
强化字符处理能力;
复习变量赋值法。
解题要求:
代码简洁、高效;
不生成临时文件。
加分原则:
代码技术含量高,技巧出众的加技术分1分;
pb加分上限20分(本主题同一id各贴累计),视代码精悍程度加分;
批处理新人积极参与解题或讨论的可获额外参与奖励2pb(本主题同一id各贴累计)。
题目如下:
有一文本a.txt(见附件)共50行50列(以tab为列分隔符),其中每行每列的字符串是由a-z以及空格、_、
#、$、.30个字符组合而成的,现知道其中有若干列的内容是相同的,要求找出各自相同的列组合并输出其共
同的内容,在这其中要注意如下的两列是不能视为内容相同(眼睛是可以判断出,但代码中就要考虑了):
abc abc
m_空格 m_
k $ 空格k$
链接: https://pan.baidu.com/s/1AI27WrBgDbfMGgXEN7IIXg?pwd=ybun
----------------------------------------------------------------------------------------------------------------------------------------
代码运行标准输出(含升序处理):- 5列 12列内容相同,列内容如下:
- fh xs|r|_cwq|unrjh|ebbk|bm|tv|_yy|a $z|onph|unw|ms|xi|dv|vcsya|t|s._|i|f|titm$|
- ioz|h_|n.b|wv_m|su|bmi| h_|paxvv|zzl|rsqiy|b|fp|nqdm.|_no|q|b|d.|lf|d in|pl|..cx
- |tui|woe|yst|rkpnq|z|.wwo|wyq|zwch|nisle
-
- 9列 26列内容相同,列内容如下:
- i|lgxeo|ybfep|as| rp| trzl|gc|chr|gj|b|a.n|q|f|v|e|hzwwl|aw|_zjet|o|_|j|f|zepyn
- |$.ma|s|ocdvw|jep|ud|x|pmu|ywlni|$wnle| bflz|wciuq|o|fr og|.$amq|ub|qkqh|g|f|s.x
- |g|xc|em|mc|c|o|ajb|as
-
- 18列 31列内容相同,列内容如下:
- hok|_z |va|mi|h.x$|u|s|k_|almdx|kkp|j|t|$aeg|yvn|se r|ylw|dzv|so_|ltn|vtokb|yyf
- c|a|ql.n|uom|mouvn|fbgr|_|.sid|b|dpb|rrnb$|__fay|d|ewck|w |q|na|ecoj|r_h|h|l|i|x
- l|ame|x$|ynin_|cq|hc$l|$.io|gnigp
-
- 38列 41列 47列内容相同,列内容如下:
- eez|yq|fgbq|aeazh|k.u|phnw|byj$|ke|onr.q|a pum|frf|qem$t|qpskt|vqpto|nwm|qm yx|
- vyw|szrc|xfcee|_|xfx|x$sxu|l|iw|hg|je$rr|yj|vr |i.alj|ew|hio|y|iz|bw|ctl|kvbzi|j
- fp|bm|qvuyt|yioz |fs|vvi$|iq t|vo|e|pv|t|hxkqe|sayds|c
复制代码
作者: 随风 时间: 2011-3-10 02:21
没看懂~
作者: batman 时间: 2011-3-10 08:16 标题: 回复 2楼 的帖子
就是找出a.txt中完全相同的列,这有可能是3 5 12列相同,同时21 49列相同,输出其共同的内容即为输出这些相同列的内容(在一行内输出,中间用|格开)。
[ 本帖最后由 batman 于 2011-3-10 19:15 编辑 ]
作者: batman 时间: 2011-3-10 11:01
新手可以先尝试着生成a.txt这样的文本,有助于打开解题思路。。。
作者: terse 时间: 2011-3-10 11:32
先发个- @echo off&setlocal enabledelayedexpansion
-
- set "Tab= "这里改为跳格键
-
- for /f "delims=" %%i in (a.txt) do (
-
- set "str=%%i"
-
- set "str="!str:%Tab%="%Tab%"!""
-
- for %%j in (!str!) do (
-
- set "var=!str:*%%j=!"
-
- set "var1=!var:*%%j=!"
-
- if "!var!" neq "" if "!var!" neq "!var1!" set "Tem=!Tem! %%~j"
-
- )
-
- echo!Tem!&set Tem=
-
- )
-
- pause
复制代码
[]
作者: CrLf 时间: 2011-3-10 12:59
不知道我有没有理解错- @echo off&setlocal enabledelayedexpansion
- for /f "tokens=1* delims=:" %%a in ('findstr /n .* a.txt') do (
- set /p=第%%a行: <nul
- set tmp=%%b
- for %%c in ("!tmp: =" "!") do (
- if "!.%%a%%c!"=="" (set ".%%a%%c=.") else set /p=%%~c <nul
- )
- echo;
- )
- pause
复制代码
作者: batman 时间: 2011-3-10 13:25 标题: 回复 6楼 的帖子
理解错误,难道这题这么难理解!
作者: terse 时间: 2011-3-10 14:55
在列里找相同吗?- @echo off&setlocal enabledelayedexpansion
- set "Tab= "这里改为跳格键
- for /f "delims=" %%i in (_a.txt) do (
- set "str=%%i"
- set n=
- for %%j in ("!str:%Tab%="%Tab%"!") do (
- set /a n+=1
- for %%k in (!n!) do set l_%%k=!l_%%k!%Tab%%%j
- )
- )
- for /l %%i in (1 1 %n%) do (
- for %%j in (!l_%%i!) do (
- set "var=!l_%%i:*%%j=!"
- if "!var!" neq "" if "!var!" neq "!var:*%%j=!" set "Tem=!Tem! %%~j"
- )
- if defined Tem echo %%i列:!Tem!&set Tem=
- )
- pause
复制代码
作者: weichenxiehou 时间: 2011-3-10 18:59
- @echo off&setlocal enabledelayedexpansion
- ::将下面的[tab]改为实际的跳格键
- set "tab=[tab]"
- for /f "delims=" %%a in (a.txt) do (
- set "str=%%a"
- for /l %%b in (1 1 50) do (
- for /f "delims=%tab%" %%c in ("!str!") do set "_%%b=!_%%b!批%%c"&set "str=!str:*%tab%=!"
- )
- )
- echo,与前面列存在重复的列有:
- for /f "tokens=1* delims==" %%h in ('set _') do (
- if "!%%i!"=="a" set "var=%%i"&echo,第%%h列:!var:批= !"
- set "%%i=a"
- )
- pause>nul
复制代码
[ 本帖最后由 weichenxiehou 于 2011-3-10 19:02 编辑 ]
作者: batman 时间: 2011-3-10 19:04 标题: 回复 9楼 的帖子
题意还只有你理解对了,但结果不正确,请修改。。。
[ 本帖最后由 batman 于 2011-3-10 19:05 编辑 ]
作者: batman 时间: 2011-3-10 19:07 标题: 回复 8楼 的帖子
题意还是没有理解对,难道我表达能力这么差!题目是要找出a.txt中所有彼此相同的列啊。。。
[ 本帖最后由 batman 于 2011-3-11 00:16 编辑 ]
作者: weichenxiehou 时间: 2011-3-10 20:53 标题: 回复 10楼 的帖子
谢谢加分!我把我的代码执行结果跟11楼对比了下,多显示了一行,代码修改了一下,就是没列出哪些列是一样的,只把这些列的内容打印出来了:- @echo off&setlocal enabledelayedexpansion
- ::将下面的[tab]改为实际的跳格键
- set "tab=[tab]"
- for /f "delims=" %%a in (a.txt) do (
- set "str=%%a"
- for /l %%b in (1 1 50) do (
- for /f "delims=%tab%" %%c in ("!str!") do set "_%%b=!_%%b!批%%c"&set "str=!str:*%tab%=!"
- )
- )
- echo,相同的列有:
- for /f "tokens=1* delims==" %%h in ('set _') do (
- if "!%%i!"=="a" set "var=%%i"&echo,!var:批= !"
- set "%%i=!%%i!a"
- )
- pause>nul
复制代码
[ 本帖最后由 weichenxiehou 于 2011-3-10 21:00 编辑 ]
作者: batman 时间: 2011-3-10 21:03 标题: 回复 12楼 的帖子
重要也是最难点就是列出这些相同的列组,请继续修改
作者: weichenxiehou 时间: 2011-3-10 22:23 标题: 回复 13楼 的帖子
- @echo off&setlocal enabledelayedexpansion
- ::将下面的[tab]改为实际的跳格键
- set "tab=[tab]"
- for /f "delims=" %%a in (a.txt) do (
- set "str=%%a"
- for /l %%b in (1 1 50) do (
- for /f "delims=%tab%" %%c in ("!str!") do set "_%%b=!_%%b!批%%c"&set "str=!str:*%tab%=!"
- )
- )
- echo,相同的列有:
- set n=
- for /f "tokens=1* delims==" %%h in ('set _') do (
- if "!%%i!"=="" set/a n+=1&set "#!n!=%%i"
- set "%%i=!%%i!%%h"
- )
-
- for /l %%j in (1 1 %n%) do (
- set num=!#%%j!
- call,set value=%%!num!%%
- for /f "tokens=1-3 delims=_" %%x in ("!value!") do if not "%%y"=="" echo,第%%x %%y %%z列,内容为:!num:批= !
- )
- pause>nul
复制代码
效率不高,见谅。
[ 本帖最后由 weichenxiehou 于 2011-3-10 22:25 编辑 ]
作者: CrLf 时间: 2011-3-10 23:10
呃,终于明白了,貌似不太难...这么长的行,我感觉用眼睛更判断不了- @echo off&setlocal enabledelayedexpansion
- ::将下面的[tab]改为实际的跳格键
- set "tab= "
- for /f "delims=" %%a in (a.txt) do (
- set "tmp=%%a"
- for %%b in ("!tmp: =" "!") do (
- set /a n=n%%50+1
- for %%z in (!n!) do set .!n!=!.%%z!^|%%~b
- )
- )
- for /l %%a in (1 1 50) do (
- set tmp=
- for %%b in ("\!.%%a!") do set tmp=!%%~b!
- set \!.%%a!=*!tmp! %%a列
- )
- for /f "tokens=1* delims=\=*" %%a in ('set\^|findstr "**"') do (
- echo 第%%b相同,内容为:
- echo %%a
- )
- pause
复制代码
作者: terse 时间: 2011-3-11 01:45
原来这样 理解能力问题
- @echo off&setlocal enabledelayedexpansion
- set "Tab= "这里改为跳格键
- for /f "delims=" %%i in (_a.txt) do (
- set str=%%i&set n=
- for %%j in ("!str:%Tab%="%Tab%"!") do (
- set /a n+=1
- for %%k in (!n!) do set "l_%%k=!l_%%k!|%%~j"
- )
- )
- for /l %%i in (1 1 %n%) do (
- for %%j in ("!l_%%i:~1!") do (
- if defined _%%j (
- if defined -%%j (
- set "-%%j=!-%%j! %%i列"
- ) else set /a m+=1&set __!m!=%%j&set "-%%j=!_%%j! %%i列"
- ) else set _%%j=%%i列
- )
- )
- for /l %%i in (1 1 %m%) do for %%j in (!__%%i!) do echo 第!-%%j!内容相同,列内容如下:&echo %%~j
- pause
复制代码
作者: CrLf 时间: 2011-3-11 12:34
排序很容易,现在最心痛的是效率...- @echo off&setlocal enabledelayedexpansion
- set tab=[tab]
- ::请手动替换[tab]为tab键
- set "dq=%tab%%tab%%tab%%tab%%tab%%tab%%tab%%tab%%tab%%tab% "
- for /f "delims=" %%a in (a.txt) do (
- set "tmp=%%a"
- for %%b in ("!tmp:%tab%=" "!") do (
- set /a n=n%%50+1
- for %%z in (!n!) do set .!n!=!.%%z!^|%%~b
- )
- )
- for /l %%a in (1 1 50) do (
- set tmp=
- set m= %%a
- for %%b in ("\!.%%a!") do set tmp=!%%~b!
- set \!.%%a!=*!tmp! !m:~-2!行
- )
- (@echo off
- for /f "tokens=1* delims=\=*" %%a in ('set\^^^|findstr "**"') do (
- for /f "tokens=* delims=^|" %%c in ("%%a") do echo 第%%b相同,内容为:%dq%%%c%dq%
- ))|sort
- pause
复制代码
作者: batman 时间: 2011-3-11 12:38
少用set *和|findstr这样的语句,太影响效率了。。。
既然有人用上了退格,是不是可以考虑多行回退,呵呵。。。
[ 本帖最后由 batman 于 2011-3-11 12:40 编辑 ]
作者: CrLf 时间: 2011-3-11 12:39
本来想写成一行判断一次,这样只需要一个for,而无须把整个代码“横过来”,不过懒啊...
若非一行有50列,就可以直接用tokens了
作者: CrLf 时间: 2011-3-11 17:41
呃,我用退格不是为了多行回退...仔细看下会发现我用的是[十个tab][一个空格][80个退格键],目的就是利用退格键不能跨行的特点来对齐超过一行的内容,这样可以把两行当成一行来排序,但却显示为两行。
那个空格是特意用来隔开tab和空格的,免得效果变成退行。
作者: terse 时间: 2011-3-11 22:42
就现思路效率很难提升了 或许有其他路径走
最多也就16楼的第二段上简化下 但效率差不多 也就不在上面改了- for /l %%i in (1 1 %n%) do (
- for %%j in ("!l_%%i:~1!") do (
- if "!-%%j:*列=!" equ "" set /a m+=1&set __!m!=%%j
- set "-%%j=!-%%j! %%i列"
- )
- )
复制代码
作者: netbenton 时间: 2011-3-11 22:54
只写个找相同项的演示代码- @echo off&setlocal enabledelayedexpansion
- for /l %%a in (1,1,50) do (
- set nums=!nums! %%a
- set _%%a=### !random:~-1! ### ### !random:~-1! ###
- )
-
- for /l %%a in (1,1,50) do (
- set nums=!nums: %%a=!
- set yn=%%a列
- for %%b in (!nums!) do (
- if "!_%%a!" equ "!_%%b!" (
- set nums=!nums: %%b=!
- set yn=!yn! %%b列
- )
- )
- if "!yn!" neq "%%a列" (
- echo; !yn! 相同,内容为:
- echo;!_%%a!
- echo;
- )
- )
复制代码
作者: batman 时间: 2011-3-12 11:40 标题: 效率总还是问题
- @echo off&setlocal enabledelayedexpansion
- set "t=%time%"
- for /f "delims=" %%a in (a.txt) do (
- set /a m=0,n+=1
- set "str=%%a"&set "str=!str: =空!"
- for %%a in (!str!) do (
- set /a m+=1
- for %%b in (!m!) do (
- set "_%%b=!_%%b!|%%a"
- if !n! equ 50 (
- for %%c in (!_%%b!) do (
- if not defined %%c (
- set "%%c=%%b列"
- ) else (
- if defined .%%c (
- for /f "tokens=2 delims=列 " %%d in ("!.%%c!") do set "..%%d=!..%%d! %%b列"
- ) else (
- set "..%%b=!%%c! %%b列"&set ".%%c=!..%%b!"
- )
- )
- )
- )
- )
- )
- )
- for /l %%a in (1,1,%m%) do (
- if defined ..%%a (
- set "str=!_%%a:~1!
- echo !..%%a!内容相同,列内容如下:
- echo !str:空= !&echo.
- )
- )
- echo %t%
- echo %time%
- pause>nul
复制代码
作者: qzwqzw 时间: 2011-3-12 22:43
贴一个正统的解法
只为提供一种思路
为了增强代码的可读性
比较大的牺牲了效率
据说将变量名和值改为简短的英文可以提高部分效率
有心人可以试试
另外,没有细看其它人的代码
算法如有雷同,纯属巧合
- @echo off & setlocal EnableDelayedExpansion
- rem 清空环境变量空间,防止被意外变量影响
- for /f "delims==" %%e in ('set') do set %%e=
- set 起始时间=%time%
-
- rem 逐行读取测试文本
- for /f "delims=" %%l in (a.txt) do (
- set "某行=%%l"
- set "某行=!某行: =空格!
- set 列序号=0
- rem 将当前行的字符串逐个追加赋值到列变量中
- for %%s in (!某行!) do (
- set /a 列序号+=1
- rem 将列分割符放在后面,是为了显示出字符串末尾可能存在的空格
- for %%e in (_V!列序号!) do set _V!列序号!=!%%e!%%s列分割符
- )
- )
-
- rem 整理得到的所有整列
- for /l %%i in (1,1,!列序号!) do (
- set "某整列=!_V%%i!"
- if not defined !某整列! (
- set "!某整列!=%%i列"
- ) else (
- for %%d in (!某整列!) do set "!某整列!=!%%d! %%i列"
- set 重复列=!重复列! !某整列!
- )
- )
-
- for %%c in (%重复列%) do (
- echo !%%c!内容相同,列内容如下:
- set "列内容=%%c"
- set "列内容=!列内容:空格= !"
- set "列内容=!列内容:列分割符=|!"
- echo !列内容!
- echo.
- )
- echo %起始时间%
- echo %time%
复制代码
[ 本帖最后由 qzwqzw 于 2011-3-12 22:48 编辑 ]
作者: CrLf 时间: 2011-3-13 12:29
发错地方...
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |