Subject | : Re^2: SAD Update. V1.0.10.4.4a31 |
Date | : 2010/04/16(Fri) 16:49:35 |
Contributor | : Akio Morita |
> > 1. The next version will extedn StringFill to take a negative number for the third argument. > > > > Example: > > StringFill["abc","de", 6] returns "abcded" > > StringFill["abc","de",-6] returns "dedabc" > > > 第3引数が負の場合の動作なのですが、返り値の連続性に関して直感に反する動作をすると思うのですが > 定義を再考しませんか?まだ、ユースケースはほとんど存在しないので現時点からの変更は傷が浅いはずです。 > # 提案1.に関しては、提示された用例には反しません > > 現在の実行結果 > Print[TableForm[Map[{#, StringFill["ABCD", "123", #]}&, Range[-10, 10]]]]; > -10 123123ABCD > -9 12312ABCD > -8 1231ABCD > -7 123ABCD > -6 12ABCD > -5 1ABCD > -4 ABCD > -3 ABC > -2 AB > -1 A > 0 > 1 A > 2 AB > 3 ABC > 4 ABCD > 5 ABCD1 > 6 ABCD12 > 7 ABCD123 > 8 ABCD1231 > 9 ABCD12312 > 10 ABCD123123 > > 提案1. > StringFill[s1_String, s2_String, len_Real]にて、 > -StringLength[s1] =< len < 0の返り値がs1[1, Abs[len]]なのですが、 > 0 < len =< StringLength[s1]側の返り値がs1[1, len]であることや、 > s1[pos]の参照で pos < 0の場合の参照位置の知識から直感的に > 期待される動作は、s1[-len, -1]だと思われるのですが、どうでしょうか? > > 提案2. > StringFill[s1_String, s2_String, len_Real]にて、 > len > 0側の動作は、形式的には StringJoin[s1, s2, s2, s2, ...][1, len]と記述でき、 > StringFill[s1, s2, len1] = StringFill[s1, s2, len1 + n][1, len1] (len1 > 0, n >0)が > 一般に成立します。 > よって、直感的な対称性を持たせるには > StringFill[s1, s2, len1] = StringFill[s1, s2, len1 - n][-len1, -1] (len1 < 0, n > 0)を > 満足すべきなので、len < 0側の動作は、形式的な表現を反対方向に延長した > StringJoin[s2, ..., s2, s2, s2, s1][-len, -1] (*1)若しくは > With[{s2r = StringReverse[s2]}, StringJoin[s2r, ..., s2r, s2r, s2r, s1][-len, -1]] (*2) > になると思いますが、実際には s2の末尾から文字列が削られて調整されています。 > > 実装コスト的には(*1)が安いはずですが、上記の用例と整合させると (*2)であるべきです。 > > (*1)の定義を採用する場合は、形式表現的StringJoin[s2,...,s2,s2,s1,s2,s2,...,s2]の部分文字列を > s1を先頭(len > 0)若しくは末尾(len < 0)から切り出すという意味で一貫した定義になります。 > 提案1 + 提案2-(*1)に基づいた以下の形式的な定義へ tfconvstr.fを修正するパッチを作りました StringFill[s1_String, s2_String, len_Real] := Which[ len > 0, StringJoin[s1, s2, s2, ..., s2][1, len], len == 0, "", len < 0, StringJoin[s2, ..., s2, s2, s1][-len, -1]]; 具体的な動作は以下のようになります In[1]:= Print[TableForm[Map[{#, StringFill["ABCD", "123", #]}&, Range[-10, 10]]]]; -10 123123ABCD -9 23123ABCD -8 3123ABCD -7 123ABCD -6 23ABCD -5 3ABCD -4 ABCD -3 BCD -2 CD -1 D 0 1 A 2 AB 3 ABC 4 ABCD 5 ABCD1 6 ABCD12 7 ABCD123 8 ABCD1231 9 ABCD12312 10 ABCD123123 --- src/tfconvstr.f.1.97 2010-04-12 18:51:48.000000000 +0900 +++ src/tfconvstr.f 2010-04-16 16:41:09.000000000 +0900 @@ -1,4 +1,3 @@ -c$Header: /SAD/cvsroot/oldsad/src/tfconvstr.f,v 1.97 2010/04/12 05:08:30 oide Exp $ character*(*) function tfconvstr(it,ia,v,nc,form) implicit none integer*4 it,ia,nc @@ -189,17 +188,24 @@ ia2=itastk(2,isp0-1) n2=ilist(1,ia2) if(n .gt. 0)then - call putstringbufb(ibuf,ilist(1,ia1+1),m,full) - do while(m .lt. n) - call putstringbufb(ibuf,ilist(1,ia2+1),min(n2,n-m),full) - m=m+n2 - enddo - else + call putstringbufb(ibuf,jlist(1,ia1+1),m,full) do while(m .lt. na) - call putstringbufb(ibuf,ilist(1,ia2+1),min(n2,na-m),full) + call putstringbufb(ibuf,jlist(1,ia2+1),min(n2,na-m),full) m=m+n2 enddo - call putstringbufb(ibuf,ilist(1,ia1+1),m,full) + else + if(m .lt. na)then + n=mod(na-m,n2) + if(n .gt. 0)then + call putstringbufb(ibuf,jlist(1+(n2-n),ia2+1),n,full) + na=na-n + endif + do while(m .lt. na) + call putstringbufb(ibuf,jlist(1,ia2+1),n2,full) + na=na-n2 + enddo + endif + call putstringbufb(ibuf,jlist(1+(n1-m),ia1+1),m,full) endif iax=itfstringbuftostring(ibuf) isp=isp0