如何计算整数序列的部分和?这是我目前得到的结果
\documentclass{article}
\usepackage{calc, forloop, xparse}
\ExplSyntaxOn
\seq_new:N \g_tmp_seq
\seq_new:N \g_partialsum_seq
\seq_set_from_clist:Nn \g_tmp_seq {3, 1, 2, 4, 0, 1}
\newcounter{i}
\newcounter{j}
\newcounter{lengthplusone}
\setcounter{lengthplusone}{\seq_count:N \g_tmp_seq + 1}
\forloop{i}{1}{ \value{i} < \value{lengthplusone} }{
\seq_gput_right:Nn \g_partialsum_seq {0
\forloop{j}{1}{ \value{j} < \value{i} }{
+ \seq_item:Nn \g_tmp_seq { \value{j} - 1}
}
}
}
\cs_new:Npn \partialsum #1 {
\seq_item:Nn \g_partialsum_seq { #1 }
}
\ExplSyntaxOff
\begin{document}
\partialsum{1} % should be 0
\partialsum{2} % should be 3
\partialsum{3} % should be 4
\partialsum{4} % should be 6
\partialsum{5} % should be 10
\partialsum{6} % should be 10
\end{document}
不幸的是,总和并没有扩大,而且所有的值\partialsum
都等于最后的总和。
答案1
我认为对 seq 使用 expl3 迭代更自然:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \g_tmp_seq
\seq_new:N \g_partialsum_seq
\seq_set_from_clist:Nn \g_tmp_seq {3, 1, 2, 4, 0, 1}
\seq_set_from_clist:Nn \g_partialsum_seq {0}
\tl_new:N\l_sum
\seq_map_inline:Nn\g_tmp_seq{
\tl_set:Nx\l_sum{\int_eval:n{\l_sum+#1}}
\seq_gput_right:NV \g_partialsum_seq \l_sum
}
\NewDocumentCommand\partialsum {m}{
\seq_item:Nn \g_partialsum_seq { #1 }
}
\ExplSyntaxOff
\begin{document}
\partialsum{1} % should be 0
\partialsum{2} % should be 3
\partialsum{3} % should be 4
\partialsum{4} % should be 6
\partialsum{5} % should be 10
\partialsum{6} % should be 10
\end{document}
答案2
我完全放弃了calc
和forloop
,因为你可以使用普通的 来完成所有操作expl3
。作为奖励,你可以使命令可扩展,并使用可选参数来设置求和的起点。
与您的版本的主要区别在于代码不存储求和序列。每次使用该命令时,都会对选定的间隔进行求和。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \g_noibe_numbers_seq
\seq_set_from_clist:Nn \g_noibe_numbers_seq {3, 1, 2, 4, 0, 1}
\NewExpandableDocumentCommand \partialsum { O{1} m }
{ \__noibe_partialsum:Nnnn \g_noibe_numbers_seq {#1-2} {#2-2} { } }
\cs_new:Npn \__noibe_partialsum:Nnnn #1 #2 #3 #4
{
\int_compare:nNnTF {#2} > {#3}
{ \int_eval:n {#4 0} }
{
\exp_args:Nf
\__noibe_partialsum:nN { \int_eval:n {#2+1} } #1
{#4} {#3}
}
}
\cs_new:Npn \__noibe_partialsum:nN #1 #2
{
\exp_args:Nf
\__noibe_partialsum:nnNnn { \seq_item:Nn #2 {#1} + } {#1} #2
}
\cs_new:Npn \__noibe_partialsum:nnNnn #1 #2 #3 #4 #5
{ \__noibe_partialsum:Nnnn #3 {#2} {#5} {#4#1} }
\ExplSyntaxOff
\begin{document}
\partialsum{1} % should be 0
\partialsum{2} % should be 3
\partialsum{3} % should be 4
\partialsum{4} % should be 6
\partialsum{5} % should be 10
\partialsum{6} % should be 10
\ifnum\partialsum{5}=\partialsum{6}
The fifth item is zero.
\else
The fifth item is nonzero.
\fi
\end{document}
答案3
使用更少的代码expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\setsequence}{m}
{% #1 = items
\seq_set_from_clist:Nn \l_noibe_sequence_seq { #1 }
}
\NewExpandableDocumentCommand{\partialsum}{m}
{% #1 = (one more than the) number of items to sum
\int_eval:n
{
0 \int_step_function:nN { #1 - 1 } \__noibe_sequence_sum:n
}
}
\cs_new:Nn \__noibe_sequence_sum:n
{
\int_compare:nF { #1 > \seq_count:N \l_noibe_sequence_seq }
{
+ \seq_item:Nn \l_noibe_sequence_seq { #1 }
}
}
\ExplSyntaxOff
\begin{document}
\setsequence{3, 1, 2, 4, 0, 1}
\partialsum{1} --- should be 0
\partialsum{2} --- should be 3
\partialsum{3} --- should be 4
\partialsum{4} --- should be 6
\partialsum{5} --- should be 10
\partialsum{6} --- should be 10
\partialsum{7} --- should be 11
\partialsum{8} --- should be 11
\end{document}