Suponha que eu tenha uma lista com algumas entradas (todos valores inteiros, caso seja relevante), por exemplo,
1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0
O LaTeX pode de alguma forma contar o número de 0
's, 1
's, ..., 7
's na lista acima?
PS Todas as soluções são aceitáveis, mas uma versão LaTeX 3 é preferida.
Atualizar
Usandocódigo da egreg, por que os seguintes estão retornando apenas 0
e como posso (se possível) ainda usar todos os \def
s e obter o resultado correto?
\documentclass{article}
\usepackage{
xparse,
l3regex
}
\ExplSyntaxOn
\NewDocumentCommand{\countoccurrences}{ O{} m }
{
\group_begin:
\keys_set:nn { svend/occurrences } { #1 }
% if the self key appeared, make the list name equal to the sequence name
\bool_if:NT \l_svend_occurrences_self_bool
{
\tl_set_eq:NN \l__svend_occurrences_list_tl \l__svend_occurrences_name_tl
}
\svend_count_occurrences:n { #2 }
\group_end:
}
\NewDocumentCommand{\setsearchlist}{ O{default} m }
{
\svend_occurrences_set_searchlist:nn { #1 } { #2 }
}
\DeclareExpandableDocumentCommand{\getoccurrences}{ O{default} m }
{
\prop_item:cn { g_svend_occurrences_#1_prop } { #2 }
}
\keys_define:nn { svend/occurrences }
{
name .tl_set:N = \l__svend_occurrences_name_tl,
name .initial:n = default,
list .tl_set:N = \l__svend_occurrences_list_tl,
list .initial:n = default,
self .bool_set:N = \l_svend_occurrences_self_bool,
self .default:n = true,
self .initial:n = false,
}
\prop_new:N \g_svend_occurrences_default_prop
\seq_new:N \g_svend_occurrences_default_list_seq
\int_new:N \l__svend_occurrences_matches_int
\cs_new_protected:Npn \svend_count_occurrences:n #1
{
% create a new property list for storing the values for the current string
% or clear an existing one
\prop_gclear_new:c { g_svend_occurrences_ \l__svend_occurrences_name_tl _prop }
% populate the search list, if self is used
\bool_if:NT \l_svend_occurrences_self_bool
{
\svend_occurrences_set_searchlist:Vn \l__svend_occurrences_name_tl { #1 }
}
% map through the search list
\seq_map_inline:cn { g_svend_occurrences_ \l__svend_occurrences_list_tl _list_seq }
{
% store the current search item; using the token list in
% the regex search expression should avoid problems with
% special characters
\tl_set:Nn \l__svend_occurrences_temp_tl { ##1 }
% count the number of times “search item/space” appears
% (a trailing space is added) and store it in an integer variable
% (in a regex, \u{tl variable name} stands for the contents of the variable
\regex_count:nnN { \u{l__svend_occurrences_temp_tl}\s } { #1~ } \l__svend_occurrences_matches_int
% put the number of matches in the property list, corresponding to
% the current item as key
\prop_gput:cnx { g_svend_occurrences_ \l__svend_occurrences_name_tl _prop }
{ ##1 }
{ \int_to_arabic:n { \l__svend_occurrences_matches_int } }
}
}
% populate a search list (with duplicates removed)
\cs_new_protected:Npn \svend_occurrences_set_searchlist:nn #1 #2
{
\seq_gclear_new:c { g_svend_occurrences_#1_list_seq }
\seq_gset_split:cnn { g_svend_occurrences_#1_list_seq } { ~ } { #2 }
\seq_gremove_duplicates:c { g_svend_occurrences_#1_list_seq }
}
\cs_generate_variant:Nn \seq_gset_split:Nnn { c }
\cs_generate_variant:Nn \svend_occurrences_set_searchlist:nn { V }
\ExplSyntaxOff
\begin{document}
\def\fravaerElevEn{1}
\def\fravaerElevTo{2}
\def\fravaerElevTre{4}
\def\fravaerElevFire{0}
\def\fravaerElevFem{3}
\def\fravaerElevSeks{1}
\def\fravaerElevSyv{0}
\def\fravaerElevOtte{0}
\def\fravaerElevNi{2}
\def\fravaerElevTi{1}
\def\fravaerElevElleve{7}
\def\fravaerElevTolv{1}
\def\fravaerElevTretten{4}
\def\fravaerElevFjorten{2}
\def\fravaerElevFemten{3}
\def\fravaerElevSeksten{0}
\def\fravaerElevSytten{0}
\def\fravaerElevAtten{6}
\def\fravaerElevNitten{5}
\def\fravaerElevTyve{2}
\def\fravaerElevEnogtyve{1}
\def\fravaerElevToogtyve{2}
\def\fravaerElevTreogtyve{3}
\def\fravaerElevFireogtyve{0}
\setsearchlist{0 1 2 3 4 5 6 7}
\countoccurrences{
\fravaerElevEn
\fravaerElevTo
\fravaerElevTre
\fravaerElevFire
\fravaerElevFem
\fravaerElevSeks
\fravaerElevSyv
\fravaerElevOtte
\fravaerElevNi
\fravaerElevTi
\fravaerElevElleve
\fravaerElevTolv
\fravaerElevTretten
\fravaerElevFjorten
\fravaerElevFemten
\fravaerElevSeksten
\fravaerElevSytten
\fravaerElevAtten
\fravaerElevNitten
\fravaerElevTyve
\fravaerElevEnogtyve
\fravaerElevToogtyve
\fravaerElevTreogtyve
\fravaerElevFireogtyve
}
\begin{tabular}{cc}
0 & \getoccurrences{0} \\
1 & \getoccurrences{1} \\
2 & \getoccurrences{2} \\
3 & \getoccurrences{3} \\
4 & \getoccurrences{4} \\
5 & \getoccurrences{5} \\
6 & \getoccurrences{6} \\
7 & \getoccurrences{7}
\end{tabular}
\end{document}
Responder1
Isto explora o fato de que os tokens a serem contados são dígitos:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\countoccurrences}{ O{default} m }
{
\svend_count_occurrences:nn { #1 } { #2 }
}
\DeclareExpandableDocumentCommand{\getoccurrences}{ O{default} m }
{
% just retrieve the property corresponding to the requested digit
\prop_item:cn { g_svend_occurrences_#1_prop } { #2 }
}
\prop_new:N \g_svend_occurrences_default_prop
\tl_new:N \l__svend_input_tl
\tl_new:N \l__svend_temp_tl
\cs_new_protected:Npn \svend_count_occurrences:nn #1 #2
{
% make a new property list, if necessary, or clear an existing one
\prop_gclear_new:c { g_svend_occurrences_#1_prop }
% store the string
\tl_set:Nn \l__svend_input_tl { #2 }
% the items are octal digits so do a loop on them
\int_step_inline:nnnn { 0 } { 1 } { 7 }
{
% make a copy of the given string
\tl_set_eq:NN \l__svend_temp_tl \l__svend_input_tl
% remove all items that are the same as the current digit
\tl_remove_all:Nn \l__svend_temp_tl { ##1 }
% put in the property list the current digit as property
% and the difference between the number of items of the
% full list and the temporary one (count the number of removed items)
\prop_gput:cnx { g_svend_occurrences_#1_prop }
{ ##1 }
{ \int_eval:n { \tl_count:N \l__svend_input_tl - \tl_count:N \l__svend_temp_tl } }
}
}
\ExplSyntaxOff
\begin{document}
\countoccurrences[new]{1 1 1 1 2 2 2 2}
\getoccurrences[new]{0}\quad
\getoccurrences[new]{1}\quad
\getoccurrences[new]{2}
\bigskip
\countoccurrences{1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0}
\begin{tabular}{cc}
0 & \getoccurrences{0} \\
1 & \getoccurrences{1} \\
2 & \getoccurrences{2} \\
3 & \getoccurrences{3} \\
4 & \getoccurrences{4} \\
5 & \getoccurrences{5} \\
6 & \getoccurrences{6} \\
7 & \getoccurrences{7} \\
\end{tabular}
\end{document}
Para itens arbitrários é necessário um código mais complexo.
Sequências arbitrárias de caracteres podem ser tratadas com expressões regulares. Observe que aqui \countoccurrences
toma como argumento opcional uma lista de pares de valores-chave: name
define um nome para a lista (o padrão é default
) e list
a lista de sequências a serem contadas. Apenas \setsearchlist
a lista deve ser especificada como argumento opcional e no \getoccurrences
nome.
Se o argumento opcional contiver \countoccurrences
( self
isso implica self=true
), então list
não deverá aparecer e a lista de itens será construída a partir do argumento obrigatório e receberá o mesmo nome da lista de tokens. Em particular
\countoccurrences[self]{0 1 2 3}
configuraria a lista da mesma forma que a emissão
\setsearchlist{0 1 2 3}
antecipadamente.
Exemplo completo:
\documentclass{article}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\countoccurrences}{ O{} m }
{
\group_begin:
\keys_set:nn { svend/occurrences } { #1 }
% if the self key appeared, make the list name equal to the sequence name
\bool_if:NT \l_svend_occurrences_self_bool
{
\tl_set_eq:NN \l__svend_occurrences_list_tl \l__svend_occurrences_name_tl
}
\svend_count_occurrences:n { #2 }
\group_end:
}
\NewDocumentCommand{\setsearchlist}{ O{default} m }
{
\svend_occurrences_set_searchlist:nn { #1 } { #2 }
}
\DeclareExpandableDocumentCommand{\getoccurrences}{ O{default} m }
{
\prop_item:cn { g_svend_occurrences_#1_prop } { #2 }
}
\keys_define:nn { svend/occurrences }
{
name .tl_set:N = \l__svend_occurrences_name_tl,
name .initial:n = default,
list .tl_set:N = \l__svend_occurrences_list_tl,
list .initial:n = default,
self .bool_set:N = \l_svend_occurrences_self_bool,
self .default:n = true,
self .initial:n = false,
}
\prop_new:N \g_svend_occurrences_default_prop
\seq_new:N \g_svend_occurrences_default_list_seq
\int_new:N \l__svend_occurrences_matches_int
\cs_new_protected:Npn \svend_count_occurrences:n #1
{
% create a new property list for storing the values for the current string
% or clear an existing one
\prop_gclear_new:c { g_svend_occurrences_ \l__svend_occurrences_name_tl _prop }
% populate the search list, if self is used
\bool_if:NT \l_svend_occurrences_self_bool
{
\svend_occurrences_set_searchlist:Vn \l__svend_occurrences_name_tl { #1 }
}
% map through the search list
\seq_map_inline:cn { g_svend_occurrences_ \l__svend_occurrences_list_tl _list_seq }
{
% store the current search item; using the token list in
% the regex search expression should avoid problems with
% special characters
\tl_set:Nn \l__svend_occurrences_temp_tl { ##1 }
% count the number of times “search item/space” appears
% (a trailing space is added) and store it in an integer variable
% (in a regex, \u{tl variable name} stands for the contents of the variable
\regex_count:nnN { \u{l__svend_occurrences_temp_tl}\s } { #1~ } \l__svend_occurrences_matches_int
% put the number of matches in the property list, corresponding to
% the current item as key
\prop_gput:cnx { g_svend_occurrences_ \l__svend_occurrences_name_tl _prop }
{ ##1 }
{ \int_to_arabic:n { \l__svend_occurrences_matches_int } }
}
}
% populate a search list (with duplicates removed)
\cs_new_protected:Npn \svend_occurrences_set_searchlist:nn #1 #2
{
\seq_gclear_new:c { g_svend_occurrences_#1_list_seq }
\seq_gset_split:cnn { g_svend_occurrences_#1_list_seq } { ~ } { #2 }
\seq_gremove_duplicates:c { g_svend_occurrences_#1_list_seq }
}
\cs_generate_variant:Nn \seq_gset_split:Nnn { c }
\cs_generate_variant:Nn \svend_occurrences_set_searchlist:nn { V }
\ExplSyntaxOff
\begin{document}
\setsearchlist{0 1 2 3 4 5 6 7}
\countoccurrences[name=new]{1 1 1 1 2 2 2 2}
\getoccurrences[new]{0}\quad
\getoccurrences[new]{1}\quad
\getoccurrences[new]{2}
\bigskip
\countoccurrences{1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0}
\begin{tabular}{cc}
0 & \getoccurrences{0} \\
1 & \getoccurrences{1} \\
2 & \getoccurrences{2} \\
3 & \getoccurrences{3} \\
4 & \getoccurrences{4} \\
5 & \getoccurrences{5} \\
6 & \getoccurrences{6} \\
7 & \getoccurrences{7} \\
\end{tabular}
\bigskip
\setsearchlist[alph]{a b c ce}
\countoccurrences[name=letters,list=alph]{a b c a d b b ce f}
\begin{tabular}{cc}
a & \getoccurrences[letters]{a} \\
b & \getoccurrences[letters]{b} \\
c & \getoccurrences[letters]{c} \\
ce & \getoccurrences[letters]{ce} \\
\end{tabular}
\bigskip
\countoccurrences[name=letters,self]{a b c a d b b ce f}
\begin{tabular}{cc}
a & \getoccurrences[letters]{a} \\
b & \getoccurrences[letters]{b} \\
c & \getoccurrences[letters]{c} \\
ce & \getoccurrences[letters]{ce} \\
d & \getoccurrences[letters]{d} \\
f & \getoccurrences[letters]{f} \\
\end{tabular}
\end{document}
Uma versão que permite também controlar sequências, desde que se expandam para personagens. Quando se espera que sequências de controle sejam contadas na lista, um separadordeveser especificado com a chave sep=
(um ponto e vírgula no exemplo), porque os espaços são ignorados após a sequência de controle (a menos que você queira inseri-los como
\countoccurrences{
\fravaerElevEn\space
\fravaerElevTo\space
\fravaerElevTre\space
...
}
Aqui está o exemplo
\documentclass{article}
\usepackage{xparse,l3regex}
\ExplSyntaxOn
\NewDocumentCommand{\countoccurrences}{ O{} m }
{
\group_begin:
\keys_set:nn { svend/occurrences } { #1 }
% if the self key appeared, make the list name equal to the sequence name
\bool_if:NT \l__svend_occurrences_self_bool
{
\tl_set_eq:NN \l__svend_occurrences_list_tl \l__svend_occurrences_name_tl
}
\svend_count_occurrences:x { #2 }
\group_end:
}
\NewDocumentCommand{\setsearchlist}{ O{default} m }
{
\svend_occurrences_set_searchlist:nn { #1 } { #2 }
}
\DeclareExpandableDocumentCommand{\getoccurrences}{ O{default} m }
{
\prop_item:cn { g_svend_occurrences_#1_prop } { #2 }
}
\keys_define:nn { svend/occurrences }
{
name .tl_set:N = \l__svend_occurrences_name_tl,
name .initial:n = default,
list .tl_set:N = \l__svend_occurrences_list_tl,
list .initial:n = default,
self .bool_set:N = \l__svend_occurrences_self_bool,
self .default:n = true,
self .initial:n = false,
sep .tl_set:N = \l__svend_occurrences_sep_tl,
sep .initial:n = {~},
}
\prop_new:N \g_svend_occurrences_default_prop
\seq_new:N \g_svend_occurrences_default_list_seq
\int_new:N \l__svend_occurrences_matches_int
\tl_new:N \l__svend_occurrences_input_tl
\cs_new_protected:Npn \svend_count_occurrences:n #1
{
\tl_set:Nn \l__svend_occurrences_input_tl { #1~ } % add a trailing space
\tl_replace_all:NVn \l__svend_occurrences_input_tl \l__svend_occurrences_sep_tl { ~ }
% create a new property list for storing the values for the current string
% or clear an existing one
\prop_gclear_new:c { g_svend_occurrences_ \l__svend_occurrences_name_tl _prop }
% populate the search list, if self is used
\bool_if:NT \l__svend_occurrences_self_bool
{
\svend_occurrences_set_searchlist:Vn \l__svend_occurrences_name_tl { #1 }
}
% map through the search list
\seq_map_inline:cn { g_svend_occurrences_ \l__svend_occurrences_list_tl _list_seq }
{
% store the current search item; using the token list in
% the regex search expression should avoid problems with
% special characters
\tl_set:Nn \l__svend_occurrences_temp_tl { ##1 }
% count the number of times “search item/space” appears
% (a trailing space is added) and store it in an integer variable
% (in a regex, \u{tl variable name} stands for the contents of the variable
\regex_count:nVN
{ \u{l__svend_occurrences_temp_tl}\s } % search expression
\l__svend_occurrences_input_tl % token list to search in
\l__svend_occurrences_matches_int % store the result here
% put the number of matches in the property list, corresponding to
% the current item as key
\prop_gput:cnx { g_svend_occurrences_ \l__svend_occurrences_name_tl _prop }
{ ##1 }
{ \int_to_arabic:n { \l__svend_occurrences_matches_int } }
}
}
\cs_generate_variant:Nn \tl_replace_all:Nnn { NV }
\cs_generate_variant:Nn \regex_count:nnN { nV }
\cs_generate_variant:Nn \svend_count_occurrences:n { x }
% populate a search list (with duplicates removed)
\cs_new_protected:Npn \svend_occurrences_set_searchlist:nn #1 #2
{
\seq_gclear_new:c { g_svend_occurrences_#1_list_seq }
\seq_gset_split:cnn { g_svend_occurrences_#1_list_seq } { ~ } { #2 }
\seq_gremove_duplicates:c { g_svend_occurrences_#1_list_seq }
}
\cs_generate_variant:Nn \seq_gset_split:Nnn { c }
\cs_generate_variant:Nn \svend_occurrences_set_searchlist:nn { V }
\ExplSyntaxOff
\begin{document}
\setsearchlist{0 1 2 3 4 5 6 7}
\countoccurrences[name=new]{1 1 1 1 2 2 2 2}
\getoccurrences[new]{0}\quad
\getoccurrences[new]{1}\quad
\getoccurrences[new]{2}
\bigskip
\countoccurrences{1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0}
\begin{tabular}{cc}
0 & \getoccurrences{0} \\
1 & \getoccurrences{1} \\
2 & \getoccurrences{2} \\
3 & \getoccurrences{3} \\
4 & \getoccurrences{4} \\
5 & \getoccurrences{5} \\
6 & \getoccurrences{6} \\
7 & \getoccurrences{7} \\
\end{tabular}
\bigskip
\setsearchlist[alph]{a b c ce}
\countoccurrences[name=letters,list=alph]{a b c a d b b ce f}
\begin{tabular}{cc}
a & \getoccurrences[letters]{a} \\
b & \getoccurrences[letters]{b} \\
c & \getoccurrences[letters]{c} \\
ce & \getoccurrences[letters]{ce} \\
\end{tabular}
\bigskip
\countoccurrences[name=letters,self]{a b c a d b b ce f}
\begin{tabular}{cc}
a & \getoccurrences[letters]{a} \\
b & \getoccurrences[letters]{b} \\
c & \getoccurrences[letters]{c} \\
ce & \getoccurrences[letters]{ce} \\
d & \getoccurrences[letters]{d} \\
f & \getoccurrences[letters]{f} \\
\end{tabular}
\bigskip
\def\fravaerElevEn{1}
\def\fravaerElevTo{2}
\def\fravaerElevTre{4}
\def\fravaerElevFire{0}
\def\fravaerElevFem{3}
\def\fravaerElevSeks{1}
\def\fravaerElevSyv{0}
\def\fravaerElevOtte{0}
\def\fravaerElevNi{2}
\def\fravaerElevTi{1}
\def\fravaerElevElleve{7}
\def\fravaerElevTolv{1}
\def\fravaerElevTretten{4}
\def\fravaerElevFjorten{2}
\def\fravaerElevFemten{3}
\def\fravaerElevSeksten{0}
\def\fravaerElevSytten{0}
\def\fravaerElevAtten{6}
\def\fravaerElevNitten{5}
\def\fravaerElevTyve{2}
\def\fravaerElevEnogtyve{1}
\def\fravaerElevToogtyve{2}
\def\fravaerElevTreogtyve{3}
\def\fravaerElevFireogtyve{0}
\setsearchlist{0 1 2 3 4 5 6 7}
\countoccurrences[sep={;}]{
\fravaerElevEn;
\fravaerElevTo;
\fravaerElevTre;
\fravaerElevFire;
\fravaerElevFem;
\fravaerElevSeks;
\fravaerElevSyv;
\fravaerElevOtte;
\fravaerElevNi;
\fravaerElevTi;
\fravaerElevElleve;
\fravaerElevTolv;
\fravaerElevTretten;
\fravaerElevFjorten;
\fravaerElevFemten;
\fravaerElevSeksten;
\fravaerElevSytten;
\fravaerElevAtten;
\fravaerElevNitten;
\fravaerElevTyve;
\fravaerElevEnogtyve;
\fravaerElevToogtyve;
\fravaerElevTreogtyve;
\fravaerElevFireogtyve;
}
\begin{tabular}{cc}
0 & \getoccurrences{0} \\
1 & \getoccurrences{1} \\
2 & \getoccurrences{2} \\
3 & \getoccurrences{3} \\
4 & \getoccurrences{4} \\
5 & \getoccurrences{5} \\
6 & \getoccurrences{6} \\
7 & \getoccurrences{7}
\end{tabular}
\end{document}
A última tabela é igual à primeira.
Responder2
Os valores de contagem são salvos \csname c:<token>\endcsname
e <token>
podem ser um token temporário ou uma string de token. A \countthis
macro conta as ocorrências e a \showcount
macro expande para o resultado.
Compare a compactação do código quando usamos primitivas TeX:
\newcount\tmpnum
\def\countthis#1{\countthisA #1 {} }
\def\countthisA#1 {\ifx^#1^\else \countthisB{#1}\expandafter\countthisA\fi}
\def\countthisB#1{%
\tmpnum=0\csname c:#1\endcsname\relax
\advance\tmpnum by1
\expandafter\edef\csname c:#1\endcsname{\the\tmpnum}%
}
\def\showcount#1{%
\expandafter\ifx\csname c:#1\endcsname\relax 0\else \csname c:#1\endcsname\fi}
\countthis{1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0}
test:
0:\showcount0, 1:\showcount1, 2:\showcount2, 3:\showcount3, 4:\showcount4,
5:\showcount5, 6:\showcount6, 7:\showcount7, 8:\showcount8, 9:\showcount9,
Responder3
Aqui está algo bastante rudimentar que resolverá o problema, desde que você não tenha muitos valores inteiros que deseja testar:
\documentclass{article}
\usepackage{etoolbox}
\makeatletter
\newcommand\countoccurances[1]{\ae@count@occurances #1 \relax\@nil}
\def\ae@count@occurances#1 #2\@nil{%%
\def\ae@continue{}%%
\ifx\relax#2
\ae@increment@item{#1}%%
\else
\def\ae@continue{\ae@count@occurances#2\@nil}%%
\ae@increment@item{#1}%%
\fi
\ae@continue
}
\def\ae@increment@item#1{%%
\ifcsundef{ae@num@#1}
{\expandafter\edef\csname ae@num@#1\endcsname{1}}
{\expandafter\edef\csname ae@num@#1\endcsname{\number\numexpr\csname ae@num@#1\endcsname+1}}
}
\newcommand\aegetcount[1]{\csname ae@num@#1\endcsname}
\makeatother
\begin{document}
\countoccurances{1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0}
\begin{tabular}{cc}
1 & \aegetcount{1} \\
2 & \aegetcount{2} \\
3 & \aegetcount{3} \\
4 & \aegetcount{4} \\
5 & \aegetcount{5} \\
6 & \aegetcount{6} \\
7 & \aegetcount{7} \\
\end{tabular}
\end{document}
Aqui está uma versão LaTeX3 do acima:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\countoccurances{m}
{
\ae_count_occurences:n {#1}
}
\seq_new:N \l_count_integer_seq
\seq_new:N \l_count_integer_values_traced_seq
\cs_new_protected:Npn \ae_count_occurences:n #1
{
\seq_set_split:Nnn \l_count_integer_seq {~} {#1}
\seq_map_inline:Nn \l_count_integer_seq
{
\cs_if_free:cTF { __ae_count_integer_##1: }
{
\cs_new:cn { __ae_count_integer_##1: } { 1 }
\seq_put_right:Nn \l_count_integer_values_traced_seq
{ __ae_count_integer_##1: }
}
{ \cs_set:cx { __ae_count_integer_##1: }
{ \int_eval:n
{ \use:c { __ae_count_integer_##1: } + 1 } } }
}
}
\NewDocumentCommand\aegetcount{m}
{
\cs_if_free:cF { __ae_count_integer_#1: }
{ \use:c { __ae_count_integer_#1: }}
}
\NewDocumentCommand\aeclearcounts{}
{
\seq_map_inline:Nn \l_count_integer_values_traced_seq
{
\cs_undefine:c { ##1 }
}
\seq_clear:N \l_count_integer_values_traced_seq
}
\ExplSyntaxOff
\begin{document}
\countoccurances{1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0}
\begin{tabular}{cc}
1 & \aegetcount{1} \\
2 & \aegetcount{2} \\
3 & \aegetcount{3} \\
4 & \aegetcount{4} \\
5 & \aegetcount{5} \\
6 & \aegetcount{6} \\
7 & \aegetcount{7} \\
\end{tabular}
\vspace{1in}
\aeclearcounts
\countoccurances{1 2 4 0 3 1 0 0 2 1 7 1 4 2 3 0 0 6 5 2 1 2 3 0}
\begin{tabular}{cc}
1 & \aegetcount{1} \\
2 & \aegetcount{2} \\
3 & \aegetcount{3} \\
4 & \aegetcount{4} \\
5 & \aegetcount{5} \\
6 & \aegetcount{6} \\
7 & \aegetcount{7} \\
\end{tabular}
\end{document}
Para a versão LaTeX3, adicionei a capacidade de limpar as contagens de vários números inteiros. Eu criei um segundo comando para que o usuário possa controlar quando é desejável fazer isso.
Responder4
Aqui está uma solução usando pgffor
:
\documentclass[varwidth,border=7]{standalone}
\usepackage{pgffor}
% the occurence macro using foreach
\newcounter{founded}
\def\occurence[#1]#2{%
\setcounter{founded}{0}%
\foreach \element in #2 {\ifnum \element = #1 \stepcounter{founded}\fi}%
\thefounded%
}
\begin{document}
% store the data
\newcommand{\data}{
3,4,0,3,0,4,3,7,7,3,
4,4,7,4,1,1,4,7,8,2,
9,3,4,1,3,3,5,7,9,5,
8,1,8,5,1,9,1,2,9,8,
8,7,0,0,9,1,9,5,7,8,
5,8,1,7,7,1,1,7,4,2,
7,9,0,5,4,2,5,9,4,8,42}
% count the data
\foreach \j in {0,...,9} {
\j : \occurence[\j]\data\par
}
42 : \occurence[42]\data
\end{document}
A ideia é semelhante ahttps://tex.stackexchange.com/a/216376/9335.