我想创建一个包含 1000 个字符的表,这些字符是从 unicode 块“统一 CJK 表意文字”(4E00-9FFF)中随机选取的。每个单元格应只包含一个大字符,任何字符都不应出现两次。如果可以指定种子,那就太好了,这样就可以再次创建相同的字符集。
有没有办法使用 (Xe)TeX 自动创建这样的文件?我不太擅长 TeXnical 编程,所以任何帮助我都非常感谢。
答案1
我使用一种简单的方法来生成列表。它可能会占用太多内存,可以使用更好的算法来改进。
\documentclass{article}
\usepackage[scale=0.8,centering]{geometry}
\usepackage[nofonts]{ctex}
\setCJKmainfont{SimSun}
\parindent=0pt
\usepackage{pgfcore,pgffor}
\pgfmathsetseed{2} % set seed if you wish
\begin{document}
\foreach \i in {1,...,1000}{%
\loop
\pgfmathrandominteger\randind{"4E00}{"9FA5}%
\ifcsname used\randind\endcsname\repeat
\expandafter\xdef\csname used\randind\endcsname{}%
\symbol{\randind}%
\ifnum\numexpr\i/25*25\relax=\i (\i)\par \fi
}
\end{document}
我自己测试了一下,我认识表上大约 40% 的字符。20000 个字符中认识 8000 个比预期的多,但是有 2103 个简化汉字及其非简化变体,也就是说我认识大约 6000 个。
嗯,根据一些语言学研究,最常见的 3800 个字符可以覆盖 99.9% 的一般文本,而 6600 个字符可以覆盖 99.999%。因此,95% 的字符来自红楼梦并不意味着很多。最常见的 3500 个汉字来自《中国古代汉语常用字表》覆盖 99.48% 的文本,我认为你的朋友可以读懂他们全部进行适当的测试。
答案2
\documentclass[a4paper]{article}
\usepackage{geometry}
\geometry{margin=2cm,heightrounded}
\usepackage{fontspec}
\setmainfont{STFangsong}
\input{random}
\newcount\cjkcharcnt
%\random=3
\newif\ifshownumbers
\def\cjkchar{\setrannum{\cjkcharcnt}{"4E00}{"9FBB}%
\ifcsname CJK\the\cjkcharcnt\endcsname
\message{Recomputing (collision)}\let\next\cjkchar
\else
\expandafter\let\csname CJK\the\cjkcharcnt\endcsname\empty
\ifshownumbers{\footnotesize(\number\cjkcharcnt) }\fi
\ifnum\XeTeXcharglyph\cjkcharcnt=00
\message{Recomputing (missing character)}\let\next\cjkchar
\else
\char\cjkcharcnt\let\next\relax
\fi
\fi
\next}
\newcommand{\row}{\hbox to\hsize{%
\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil
\ifshownumbers\else
\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil
\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil
\fi
\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar\hfil\cjkchar}}
\begin{document}
%\shownumberstrue % uncomment to show (decimal) numbers
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\ifshownumbers
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\row\row\row\row\row\row\row\row\row\row
\fi
\end{document}
每行十个或二十个字符,五十个或一百个行;如果\shownumberstrue
取消注释,则附加(十进制)字符号。如果碰巧两次生成相同的数字,则将其丢弃并重新计算。我很少遇到冲突(不超过一次)。宏还会检查字体中是否存在字符。
time
(无)的响应\shownumberstrue
是
real 0m2.740s
user 0m1.660s
sys 0m0.384s