不同列表中元素的分配

不同列表中元素的分配

不同列表中元素的分配

使用自定义宏\CountLetter[optional](letters){Text},可以统计文本中不同的字母,并将其与它们的数量和相对频率显示在表中(此例中只有四个)。

演示应按编号排序。这是通过\seq_sort:Nn(再次感谢 Ulrike Fischer 的精彩回答:使用 l3 中的宏对不同表示形式的数字列表进行排序

可以使用可选参数输入表中显示的字母。只要您从头开始连续输入这些字母,宏就会正常工作。但是,如果您省略一个或多个字母,则不同列表的元素之间的分配将不再正确。

在这个大大简化的宏形式中,我只使用了四个字母,一个接一个:a、b、c、d。
计数字母的值存储在 \l_thomas_Text_a_int\l_thomas_Text_b_int\l_thomas_Text_c_int和中,\l_thomas_Text_d_int并按此顺序赋给一个列表

正确的: \CountLetter(a)

正确的: \CountLetter(a,b)

正确的: \CountLetter(a,b,c)

不正确: \CountLetter(b,c),因为省略了第一个字母a。

不正确: \CountLetter(a,c),因为第二个字母 b 被省略

我的问题是,当字母被省略/跳过时,如何获得适当的映射?

在此处输入图片描述

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}

\usepackage[margin=1.3cm]{geometry}

\usepackage{siunitx,xintexpr,booktabs,kantlipsum}

\ExplSyntaxOn
  \int_new:N \l_thomas_Text_a_int
  \int_new:N \l_thomas_Text_b_int
  \int_new:N \l_thomas_Text_c_int
  \int_new:N \l_thomas_Text_d_int
  \int_new:N \l_thomas_Text_ABCabc_int

  \seq_new:N \l_th_letter_seq
  \seq_new:N \l_th_letter_sorted_seq
  \seq_new:N \l_th_letter_qty_seq
  \seq_new:N \l_th_letter_qty_sorted_seq
  \seq_new:N \l_th_letter_relativQty_seq
  \seq_new:N \l_th_letter_relativQty_sorted_seq

\NewDocumentCommand{ \CountLetter }{ O{} D(){a,b,c,d} m }
{
  \regex_count:nnN { [A-Za-z] } {  #3 }  \l_thomas_Text_ABCabc_int % Zählt alle Buchstaben
  \regex_count:nnN { a|A }      {  #3 }  \l_thomas_Text_a_int      % Zählt kleine und große a
  \regex_count:nnN { b|B }      {  #3 }  \l_thomas_Text_b_int      % Zählt kleine und große b
  \regex_count:nnN { c|C }      {  #3 }  \l_thomas_Text_c_int      % Zählt kleine und große c
  \regex_count:nnN { d|D }      {  #3 }  \l_thomas_Text_d_int      % Zählt kleine und große d

  \seq_set_from_clist:Nn\l_th_letter_seq { #2 }
  \seq_set_from_clist:Nn\l_th_letter_qty_seq {
                                               \fp_eval:n { \l_thomas_Text_a_int },
                                               \fp_eval:n { \l_thomas_Text_b_int },
                                               \fp_eval:n { \l_thomas_Text_c_int },
                                               \fp_eval:n { \l_thomas_Text_d_int }
                                              }
  \seq_set_from_clist:Nn\l_th_letter_relativQty_seq
                          {
                            \fp_eval:n { \l_thomas_Text_a_int / \l_thomas_Text_ABCabc_int },
                            \fp_eval:n { \l_thomas_Text_b_int / \l_thomas_Text_ABCabc_int },
                            \fp_eval:n { \l_thomas_Text_c_int / \l_thomas_Text_ABCabc_int },
                            \fp_eval:n { \l_thomas_Text_d_int / \l_thomas_Text_ABCabc_int }
                          }

  \int_zero:N\l_tmpa_int
  \seq_clear:N\l_tmpa_seq

  \seq_map_inline:Nn\l_th_letter_seq % a temporary seq with 1,2,3,4 for the sorting
    {
     \int_incr:N\l_tmpa_int
     \seq_put_right:NV\l_tmpa_seq {\l_tmpa_int}
    }

  \seq_sort:Nn \l_tmpa_seq % sort over the quantity
    {
     \int_compare:nNnTF { \seq_item:Nn\l_th_letter_qty_seq {##1} } < { \seq_item:Nn\l_th_letter_qty_seq {##2} }
     { \sort_return_swapped: }
     { \sort_return_same:    }
    }

  \seq_map_inline:Nn \l_tmpa_seq  % apply the sorting to the seqs:
    {
      \seq_put_right:Nx \l_th_letter_sorted_seq     { \seq_item:Nn  \l_th_letter_seq{##1}    }
      \seq_put_right:Nx \l_th_letter_qty_sorted_seq { \ensuremath { \seq_item:Nn  \l_th_letter_qty_seq{##1} } }
      \seq_put_right:Nx \l_th_letter_relativQty_sorted_seq
          { \ensuremath {
                         \xintFrac{ \xinttheexpr
                                      reduce( \seq_item:Nn  \l_th_letter_qty_seq{##1} / \l_thomas_Text_ABCabc_int )
                                    \relax
                                  }
                        }
          }
    }

 \emph{#3}

 \par\bigskip

  \begin{tabular}{c *{\seq_count:N \l_th_letter_sorted_seq}{c}}     \toprule
    letter  & \seq_use:Nn \l_th_letter_sorted_seq {&}            \\ \midrule
    abs.~H. & \seq_use:Nn \l_th_letter_qty_sorted_seq {&}        \\ \midrule
    rel.~H. & \seq_use:Nn \l_th_letter_relativQty_sorted_seq {&} \\ \bottomrule
  \end{tabular}

\def\LetterAll{ \fp_eval:n { \l_thomas_Text_ABCabc_int } }
\def\LetterA{   \fp_eval:n { \l_thomas_Text_a_int } }
\def\LetterB{   \fp_eval:n { \l_thomas_Text_b_int } }
\def\LetterC{   \fp_eval:n { \l_thomas_Text_c_int } }
\def\LetterD{   \fp_eval:n { \l_thomas_Text_d_int } }

}

\ExplSyntaxOff

\parindent0pt

\begin{document}

%\CountLetter{\kant[3-4]}

\CountLetter(a,b,c,d){Das ist ein sinnloser Text ohne Hand und Fuß. Der Bärtige lachte höhnisch, Fußball war nie sein Über nnnnnnn  xxx Es war ein langer Tag, an dem es wieder einmal nur wenig zu Essen gab und die Hühner wurden auch nicht fett.}

\bigskip
In this text are \LetterA{} a's and \LetterAll{} letters overall.

\end{document}

提前致谢。

在@Manuel 回答之后,这是带有垂直和水平表的完整代码:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}

\usepackage[margin=1.3cm]{geometry}

\usepackage{siunitx,xfp,xintexpr,booktabs,kantlipsum}

\ExplSyntaxOn

  \int_new:N \l_thomas_Text_ABCabc_int

  \seq_new:N \l_th_letter_seq
  \seq_new:N \l_th_letter_sorted_seq
  \seq_new:N \l_th_letter_qty_seq
  \seq_new:N \l_th_letter_qty_sorted_seq
  \seq_new:N \l_th_letter_relativQty_seq
  \seq_new:N \l_th_letter_relativQty_sorted_seq

  \seq_new:N \l_th_letter_row_seq

  \cs_generate_variant:Nn \regex_count:nnN { xnc }

\NewDocumentCommand{ \CountLetter }{ O{} D(){a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,ä,ö,ü,ß} m }
{
\regex_count:nnN { [A-Za-z] } { #3 } \l_thomas_Text_ABCabc_int
\seq_set_from_clist:Nn \l_th_letter_seq { #2 }
\seq_clear:N \l_th_letter_qty_seq
\seq_clear:N \l_th_letter_relativQty_seq
\seq_map_inline:Nn \l_th_letter_seq
 {
  \int_zero_new:c { l_thomas_Text_ \tl_to_str:n {##1} _int }
  \regex_count:xnc { \text_lowercase:n {##1} | \text_uppercase:n {##1} }
   { #3 } { l_thomas_Text_ \tl_to_str:n {##1} _int }
  \seq_put_right:Nx \l_th_letter_qty_seq
   { \fp_eval:n { \use:c{ l_thomas_Text_ \tl_to_str:n {##1} _int } } }
  \seq_put_right:Nx \l_th_letter_relativQty_seq
   { \fp_eval:n { \use:c { l_thomas_Text_ \tl_to_str:n {##1} _int } / \l_thomas_Text_ABCabc_int } }
 }

\int_zero:N\l_tmpa_int
\seq_clear:N\l_tmpa_seq

\seq_map_inline:Nn\l_th_letter_seq % a temporary seq with 1,2,3,4 for the sorting
 {
  \int_incr:N\l_tmpa_int
  \seq_put_right:NV\l_tmpa_seq {\l_tmpa_int}
 }

\seq_sort:Nn \l_tmpa_seq %sort over the quantity
 {
  \int_compare:nNnTF { \seq_item:Nn\l_th_letter_qty_seq {##1} } < { \seq_item:Nn\l_th_letter_qty_seq {##2} }
   { \sort_return_swapped: }
   { \sort_return_same:    }
 }

\seq_map_inline:Nn \l_tmpa_seq  % apply the sorting to the seqs:
{
 \seq_put_right:Nx \l_th_letter_sorted_seq     { \seq_item:Nn  \l_th_letter_seq{##1}    }
 \seq_put_right:Nx \l_th_letter_qty_sorted_seq { \ensuremath { \seq_item:Nn  \l_th_letter_qty_seq{##1} } }
 \seq_put_right:Nx \l_th_letter_relativQty_sorted_seq { \ensuremath { 
                    \xintFrac{ \xinttheexpr reduce( \seq_item:Nn  \l_th_letter_qty_seq{##1} / \l_thomas_Text_ABCabc_int ) \relax } } }
}

\seq_clear:N \l_th_letter_row_seq
\seq_map_inline:Nn \l_tmpa_seq
        {
         \seq_put_right:Nx \l_th_letter_row_seq
                          {
                             \seq_item:Nn \l_th_letter_seq{##1}
                              &
                             \seq_item:Nn \l_th_letter_qty_seq{##1}
                              &
%                            \ensuremath { \xintFrac{ \xinttheexpr reduce(
%                            \seq_item:Nn  \l_th_letter_qty_seq{##1} / \l_thomas_Text_ABCabc_int
                            \seq_item:Nn \l_th_letter_relativQty_seq{##1} 
%                            ) \relax } }
                           }
         }

\emph{#3}
\par\bigskip
Buchstaben~nach~Häufigkeiten~sortiert:\\
\seq_use:Nn\l_th_letter_sorted_seq {,~}
\par
Quantities:\\
\seq_use:Nn \l_th_letter_qty_sorted_seq {,~}
\par
Gesamtzahl~aller~Buchstaben: ~\fp_eval:n { \l_thomas_Text_ABCabc_int }

\par\bigskip
{\setlength\tabcolsep{2pt}
\begin{tabular}{c *{\seq_count:N \l_th_letter_sorted_seq}{c}}\toprule
letter  & \seq_use:Nn\l_th_letter_sorted_seq {&}     \\\midrule
abs.~H. & \seq_use:Nn \l_th_letter_qty_sorted_seq {&} \\\midrule
rel.~H. & \seq_use:Nn\l_th_letter_relativQty_sorted_seq {&} 
%\\\midrule
%Bla       & \seq_item:Nn \l_th_letter_relativQty_sorted_seq {2}
\\\bottomrule
\end{tabular}
}


\sisetup{
%table-number-alignment=left,
%table-figures-decimal =8,
round-mode=places,
round-precision=5
}
\par\bigskip
\begin{tabular}{ c S[table-format=2.0] S[table-format=1.5] }
 Buchstabe & {abs. H} & {rel. H.} \\ \midrule
\seq_use:Nn \l_th_letter_row_seq { \\ }
\end{tabular}

}

\ExplSyntaxOff

\parindent0pt

\begin{document}

%\kant[3-4]

\CountLetter{Das ist ein sinnloser Text ohne Hand und Fuß. Er lachte höhnisch, Fußball war nie sein Über nnnnnnn  xxx Es war ein langer Tag, 
              an dem es wieder einmal nur wenig zu Essen gab und die Hühner wurden auch nicht fett.}

\end{document}

在此处输入图片描述

答案1

这是目前的评论。我现在无法编译,但目前这里有一些提示,这样你就不用硬编码了

这样,你就不用手动做事了,而是通过参数

\regex_count:nnN { [A-Za-z] } { #3 } \l_thomas_Text_ABCabc_int
\seq_set_from_clist:Nn \l_th_letter_seq { #2 }
\seq_clear:N \l_th_letter_qty_seq
\seq_clear:N \l_th_letter_relativQty_seq
\seq_map_inline:Nn \l_th_letter_seq
 {
  \int_zero_new:c { l_thomas_Text_ \tl_to_str:n {##1} _int }
  \regex_count:xnc { \text_lowercase:n {##1} | \text_uppercase:n {##1} }
   { #3 } { l_thomas_Text_ \tl_to_str:n {##1} _int }
  \seq_put_right:Nx \l_th_letter_qty_seq
   { \fp_eval:n { \use:c{ l_thomas_Text_ \tl_to_str:n {##1} _int } } }
  \seq_put_right:Nx \l_th_letter_relativQty_seq
   { \fp_eval:n { \use:c { l_thomas_Text_ \tl_to_str:n {##1} _int } / \l_thomas_Text_ABCabc_int } }
 }

而你需要从外面\cs_generate_variant:Nn \regex_count:nnN { xnc }

其余的,请记住\int_step_inline:存在,这样可能会优化一点,另外您可能需要对扩展采取预防措施。使用:x带有内部的参数\ensuremath,您可能希望停止扩展\exp_not:N \ensuremath,并且可能还有更多的事情。

相关内容