나는 다음 작업에 대한 아이디어를 찾고 있습니다. \listb
항목을 에 있는 항목으로 정렬하고 싶습니다 \lista
. 항상 의 요소만 에 \lista
있다고 가정할 수는 없습니다 \listb
. 의 모든 요소가 \lista
에 있다고 가정할 수도 없습니다 \listb
.
\def\lista{a,b,c,d} % no 'e,f,g,h' in \lista
\def\listb{c,e,a,h,f,g,b} % no 'd' in \listb
여기서 나는 \listb
되고 싶다 {a,b,c,e,h,f,g}
. 참고: e,h,f,g
결과는 \listb
원본의 '부분 순서' \listb
, 즉 원본의 순서를 따라야 합니다 \listb
.
답변1
일반 TeX(물론 LaTeX에서도 작동하지만)
\def\lista{a,b,c,d}
\def\listb{c,e,a,h,f,g,b}
\def\x#1#2,{\ifx\relax#2\else
\expandafter\let\csname #1-#2\endcsname\hbox
\expandafter\x\expandafter#1\fi}
\def\y#1#2#3,{\ifx\relax#3\else
\expandafter\ifx\csname #2-#3\endcsname#1,#3\fi
\expandafter\y\expandafter#1\expandafter#2\fi}
\def\z#1,{}
\expandafter\x\expandafter a\lista,\relax,
\expandafter\x\expandafter b\listb,\relax,
\edef\listb{%
\expandafter\z\romannumeral`\x%
\expandafter\y\expandafter\hbox\expandafter b\lista,\relax,%
\expandafter\y\expandafter\relax\expandafter a\listb,\relax,}
\show\listb
\bye
This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012)
restricted \write18 enabled.
entering extended mode
(./sort111.tex
> \listb=macro:
->a,b,c,e,h,f,g.
l.19 \show\listb
?
)
No pages of output.
답변2
우선 초보적인 시도에 대해 사과드립니다.
내가 가진 겸손한 아이디어는 다음과 같습니다 expl3
.
\documentclass{article}
\usepackage{expl3}
\begin{document}
\def\lista{a,b,c,d}
\def\listb{c,e,a,h,f,g,b}
\ExplSyntaxOn
\clist_new:N \l_ahmed_clist
\clist_map_inline:Nn \lista
{
\clist_if_in:NnT \listb { #1 }
{
\clist_put_right:Nn \l_ahmed_clist { #1 }
}
}
\clist_concat:NNN \listb \l_ahmed_clist \listb
\clist_remove_duplicates:N \listb
\ExplSyntaxOff
\texttt{\meaning\listb}
\end{document}
출력:
어떻게 든 도움이되기를 바랍니다.:)
답변3
David Carlisle의 솔루션은 다음과 같습니다. 나의 유일한 관심사는 내가 사용한 가비지 수집기(로컬 그룹)를 사용하더라도 정의된 컨트롤 수가 기하급수적으로 증가한다는 것입니다.
\def\listb{c,e,a,h,f,g,b} ->
3601 multiletter control sequences out of 15000+200000
\def\listb{c,e,a,h,f,g,b,i,j,k} ->
3607 multiletter control sequences out of 15000+200000
임의의 목록 파서를 허용하도록 일반화했습니다.
\documentclass{article}
\makeatletter
% \SortToMatchGivenList[<parser>]{<master list cmd>}{<user list cmd>}
\protected\def\SortToMatchGivenList{\@testopt\S@rtToMatchGivenList,}
\def\S@rtToMatchGivenList[#1]#2#3{%
\begingroup
% Define temporary macros of elements of master and user lists:
\def\x##1##2#1{%
\ifx\relax##2\else
\expandafter\let\csname ##1-\detokenize{##2}\endcsname\noboundary
\expandafter\x\expandafter##1%
\fi
}%
% Insert elements of master list if they appear in the user list,
% and insert elements of user list if they don't exist in master list:
\def\y##1##2##3#1{%
\ifx\relax##3\else
\expandafter\ifx\csname ##2-\detokenize{##3}\endcsname##1#1##3\fi
\expandafter\y\expandafter##1\expandafter##2%
\fi
}%
% Gobble some remnant code when building the sorted user list:
\def\z##1#1{}%
\expandafter\x\expandafter a#2#1\relax#1%
\expandafter\x\expandafter b#3#1\relax#1%
\edef#3{%
\expandafter\z\romannumeral`\x%
\expandafter\y\expandafter\noboundary\expandafter b#2#1\relax#1%
\expandafter\y\expandafter\relax\expandafter a#3#1\relax#1%
}%
\edef\x{\endgroup\def\noexpand#3{#3}}\x
}
\makeatother
\def\lista{a,b,c,d}
\def\listb{c,e,a,h,f,g,b}
\SortToMatchGivenList\lista\listb
\show\listb
\begin{document}
x
\end{document}
다음 접근 방식은 많은 수의 임시 매크로를 정의하지 않지만 (Paulo Cereda의 경우처럼) David Carlisle의 경우보다 속도가 느립니다.
\documentclass{article}
\makeatletter
% \SortToMatchGivenList[<parser>]{<master list cmd>}{<user list cmd>}
\protected\def\SortToMatchGivenList{\@testopt\S@rtToMatchGivenList,}
\def\S@rtToMatchGivenList[#1]#2#3{%
\begingroup
\def\tempe##1##2{%
\def\do####1#1{%
\ifx\do####1\else
\if\relax\detokenize{####1}\relax
\let\next\do
\else
\edef\next{\unexpanded{##2\do}}%
\fi
\expandafter\next
\fi
}%
\expandafter\do##1#1\do#1%
}%
\def\tempc##1{\unexpanded\expandafter{##1}}%
\def\tempd##1##2{%
\@expandtwoargs\in@
{#1\detokenize{##1}#1}{#1\detokenize\expandafter{##2}#1}%
}%
\def\tempa{}\def\tempb{}%
\tempe{#2}{%
\tempd{##1}{#3}%
\ifin@
\edef\tempa{%
\tempc\tempa\ifx\tempa\@empty\else#1\fi
\unexpanded{##1}}%
\fi
}%
\tempe{#3}{%
\tempd{##1}\tempa
\ifin@\else
\edef\tempb{%
\tempc\tempb\ifx\tempb\@empty\else#1\fi
\unexpanded{##1}%
}%
\fi
}%
\edef\tempa{\endgroup
\edef\noexpand#3{%
\noexpand\unexpanded{\tempc\tempa#1\tempc\tempb}%
}%
}%
\tempa
}
\makeatother
\def\lista{a,b,c,d}
\def\listb{c,e,a,h,f,g,b}
\SortToMatchGivenList\lista\listb
\show\listb
\begin{document}
x
\end{document}