FC2ブログ

Excelじゆうちょう

Excelのお絵描きツール『りっぷ2(りっぷつぅ)』のサポートページ、まずは「はじめに」をご覧ください。 [NewEntry] [Admin]

記事更新カレンダー

07 « 2019-08 « 09
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

やたらに多いカテゴリ

比較的新しい記事

新しいコメント

ありがたいブログ拍手

拍手コメント一覧(拍手はしない)

さみしいトラックバック

申し訳ないプロフィール

申し訳ない

管理人  [ 申し訳ない ]

pxivもやってます
リンクの一番上からのぞきに来てください
※閲覧にはユーザー登録が必要です

RSSってなんぞ?

広告は消せないらしい

        2011-07-31       基本情報(平23春)午後問11

平成23年度特別試験の基本情報技術者試験の午後問の解説です。

ただし、表計算とJavaに限る!

あれ、 この前 も似たようなこと言ってたような…

えっと、申し訳ないです。
前言撤回してJavaも解説してみようと思います。
今日は特別、許してください。



↓平成23年特別試験基本情報技術者試験午後問題問11↓
基本情報(平23春)午後問51
基本情報(平23春)午後問52
基本情報(平23春)午後問53
基本情報(平23春)午後問54
基本情報(平23春)午後問55
基本情報(平23春)午後問56

今回のJavaの問題は少々難しいかもしれません。
というのも、プログラムの内容が抽象的なのです。
文字列を扱うふたつのクラスがあり、両者の違いを確認しながら、最終的に実行時間の違いを考えるというものです。
問のほとんどは文字列クラスのプログラムです。
ですから、これらのクラスがどういった動きをするのかというのを理解できるかで、解けるかどうかが決まってきます。
今回は珍しくコンストラクタやsuperに関する設問はありません、直球勝負です。

各設問を考える前に、それぞれのプログラムを見てみることにしましょう。

・[プログラム1]インタフェースAppedableCharSequence
文字列を扱うクラスが実装するインタフェースです。
これを実装するクラスは、ここで定義されているメソッドの中身ををすべて記述しなければなりません。
メソッドの動きは[プログラムの説明]の(1)~(4)で説明されています。
ここがこの問の要ですからね、よく読んでおきましょう。

・[プログラム2]クラスArrayAppedableCharSequence
文字列を一連の配列として格納するクラスです。
これはすぐにイメージがわくと思います。

最初は10文字(EXT_SIZEが10だから)の配列を用意し、文字列を追加していっぱいになったら、そのたびに10文字分ずつ拡張していきます。

●初期状態
[ , , , , , , , , , ]

●'a'を追加
[a, , , , , , , , , ]

●どんどん要素を追加
[a,b,c,d,e,f,g,h,i,j]

●次の要素'k'を追加したい場合は、配列を拡張してから追加
[a,b,c,d,e,f,g,h,i,j,k, , , , , , , , , ]

このような感じで、10文字ずつどんどん配列が長くなっていきます。
ですので、この配列に要素を追加したり取り出したりする場合は、何文字目かを指定するだけでOKです。

・[プログラム3]クラスListAppedableCharSequence
文字列を一定数ごとにまとめて、それらを順番に連結させてひとつづりの文字列として扱うクラスです。
こちらは少しイメージしづらいと思います。

最初は10文字(EXT_SIZEが10だから)の配列を用意し、文字列を追加していっぱいになったら、そのたびに10文字の配列をnextで連結させます。

●初期状態
[ , , , , , , , , , ]

●'a'を追加
[a, , , , , , , , , ]

●どんどん要素を追加
[a,b,c,d,e,f,g,h,i,j]

●次の要素'k'を追加したい場合は、新しい配列を用意して連結
[a,b,c,d,e,f,g,h,i,j]…(next)…[k, , , , , , , , , ]

このような感じで、10文字ずつの配列がどんどん連結されていきます。
ですので、この配列に要素を追加したり取り出したりする場合は、何連結目の何文字目かを考えなければなりません。

・[プログラム4]クラスTest
これは実行時間を測定するだけのクラスです。
'a'から'z'までの26文字の小文字アルファベットを順番に追加しながら決められた回数を繰り返して('z'の次は'a'へ戻る)、ArrayAppedableCharSequenceとListAppedableCharSequenceでの実行時間を画面に出力します。

【設問1】
・[プログラム2]クラスArrayAppedableCharSequence
まずはArrayAppedableCharSequenceを見ていきます。
ここはそんなに難しくありません。
ですから、空欄もひとつだけです。

public ArrayAppedableCharSequence()は、初期化です。
最初に10文字(EXT_SIZEが10だから)の配列を用意します。

public char charAt(int index)は、indexの位置にある要素を返します。
indexが範囲外にあるとエラーが発生します。
戻り値のdata[index]はそのまま配列の位置を参照しています。
配列の要素は0から始まりますので、1文字目を取得したい場合はcharAt(0)とします。

public int length()は、文字列の長さを求めます。
単にlengthを返すだけ、ただそれだけです。

public AppedableCharSequence append(char c)は、文字列の最後尾に要素を追加します。
もし配列がいっぱいだったら、10文字分配列を拡張してから、要素を追加します。
配列を拡張する方法は、新しく10文字分大きい配列を別に用意し、中身をコピーしてから元の配列と入れ替えます。
[a]は、中身をコピーする際の繰り返しのendが入ります。
ループのカウンタiは0から、文字列の長さをあらわすlengthは1から、よってlengthは含めずに0からlength未満まで繰り返します。

■a、ウ

public String toString()は、格納した文字列を返します。
格納した文字列を返すだけ、ただそれだけです。

・[プログラム3]クラスListAppedableCharSequence
次にListAppedableCharSequenceを見ていきます。

public ListAppedableCharSequence()は、初期化です。
新しく作成しているBucket()が、連結する10文字ずつの配列です。

public char charAt(int index)は、indexの位置にある要素を返します。
indexは文字列の位置を通し番号で指定します。
よってまずはindexが何連結目を示すのかを求める必要があります。
それをしているのが、getBucket(index)です。
メソッドでいうと、private Bucket getBucket(int index)です。
getBucketに通し番号を与えると、通し番号の要素を含むBucket(10文字の文字列)が返ります。
ですから、indexが範囲外でなければgetBucket(0)もgetBucket(9)も同じBucketが返ってきます。
最終的に10文字の中から何文字目かを指定して、このメソッドの返り値となります。
それが[b]で、各Bucketが10文字分ありますから、int indexを10で割った余りを計算すればいいわけです。

■b、イ

public int length()は、文字列の長さを求めます。
単にlengthを返すだけ、ただそれだけです。

public AppedableCharSequence append(char c)は、文字列の最後尾に要素を追加します。
もし配列がいっぱいだったら、10文字分配列を新しく連結してから、要素を追加します。
配列がいっぱいかどうかは、一番後ろに連結されているBucketを調べる必要があります。
そこで、[c]の部分に文字列の長さを示すlengthを指定して最後のBucketを調べます。
ただし、getBucket(int index)の引数は0から始まる値でしたので、1から始まるlengthから1を減算しておきます。

■c、ウ

public String toString()は、格納した文字列を返します。
格納した文字列を返すだけ、といいたいところですが、10文字ずつに区切られているBucketをひとつにまとめないといけません。
それをしているのが入れ子になっているforループなのですが、これがなかなかくせものです。
この問一番の難問ではないでしょうか。

外側のループではBucketの数だけ、内側のループでは各Bucketの要素数だけ繰り返します。

外側の繰り返しはintを0からlength % EXT_SIZEでよさそうな感じもしますが、そうはしていません。
lengthからループごとに処理した文字数分だけ減算することで、カウンタのlenで残りの文字数を管理しています。
処理した文字数分とはsizeのことです、最後のBucketならそこに格納されている要素数、それ以外なら10(EXT_SIZE)になります。
外側のループ直後でsizeに代入しているのが、内側のループで繰り返す回数にもなります。

内側のループでは、各Bucketの要素を順番に取り出しています。
data[j]は出力するための文字列、bucket.data[i]はBucketの文字列です。
dataのjはひとつづりの文字列になりますから、文字数の通し番号になります。
具体的には、0からlength - 1の値まで増えていきます。
bucket.dataのiは、各Bucketの要素番号になります。
具体的には、最後のBucketは0から要素数 - 1まで、それ以外なら0から9まで繰り返します。
[d]はjの開始の値を指定します。
jは通し番号ですから、前の外側のループで格納した続きから再開しなければなりません。
元々の文字数はlengthですね、そこから残りの文字数lenを減算すれば求められます。

■d、カ

public Bucket getBucket(int index)は、もう説明しましたので省きます。

クラスprivate static class Bucketも、省きます。
10文字格納するBucketクラスを定義しています。

・[プログラム4]クラスTest

最後に、Testを見てみます。

static final int[] TIMESは、繰り返す回数です。
5000回、10000回、50000回、100000回を繰り返して実行時間を計測します。

public static void main(String[] args)は、このプログラムを開始する最初のメソッドです。
拡張for文でTIMESの数だけ繰り返して、メソッドmeasureTimeで実行時間を計測します。

static void measureTime(int n,[e] a)は、実行時間を計測するメソッドです。
System.currentTimeIllis()で現在の時間をミリ単位で取得します。
その後一連の処理をした後、もう一度現在の時間をミリ単位で取得し、その差分で実行時間を計測します。
空欄の[e]には、繰り返し処理をさせる対象のクラスを指定します。
クラスArrayAppedableCharSequenceとクラスListAppedableCharSequenceでしたね。
このふたつは異なるクラスですが、同じ型で指定します。
共通といえば、両者は同じインタフェースを実装しています。
AppendableCharSequenceですね、これでOKです。

■e、ア

【設問2】
問題文にある通り、一番最後のBucketを格納しておくlastを用意します。
コンストラクタはクラスが生成された時に実行されますから、この時点ではBucketは連結されていません。
今あるbucketlistをそのまま代入すれば、すなわち最後のBucketということになります。

■f、ア

[g]の直前のlast.next = new Bucket()で新しいBucketがlastの次に連結されます。
ですが、ここでは連結されただけで、lastが参照しているのは新しいBucketのひとつ手前のままです。
そこで、[g]の行でlast.nextを改めて代入しておきます。

■g、エ
スポンサーサイト



        2011-07-12       基本情報(平23春)午後問13

お待たせしました、 昨日 に引き続きどこよりも早い(かもしれない)基本情報の解説です。

ただし、表計算に限る!

【設問1】
代金後払いの取引にあたって、取引先からちゃんと代金が支払われるかを予測するため基準が与信枠で、それを管理することが与信管理です。
この予測するため基準には、流動比率から求めるもの、自己資本比率から求めるものの2種類があります。
そのうちよくないほうを基準にして与信枠を決定します。
一方がよくてももう他方がわるければ、結局足を引っ張られてしまいます。
はい、これを「木桶原理」と言います。
木桶の外枠に1枚でも短い板があると、水はそこまでしか汲めなくなることからそう呼ばれています。

おっと、話がそれてしまいました。
今度こそちゃんと解説します。

基準1の信用度を求めます。
基準1は流動比率ですね、これはすでにD列に入力されています。
ここの値をもとに、ワークシート'信用度評価基準'の下限度(%)に対応する信用度を参照します。

使う関数は垂直照合です、表3に説明がありますね。

第1引数の式には、流動比率の値を指定します。
この後数式を複写しますからね、絶対参照はなしでしす。
第2引数の範囲には、信用度評価基準の基準1に対応する下限度(%)と信用度のセル範囲を指定します。
このセル範囲は数式を複写しても同じ範囲を参照しますので、絶対参照にしておきます。
第3引数の列の位置には、2を指定します。
第2引数のセル範囲の中で、求める信用度は2列目にあるからです。
第4引数の検索の指定には、1を指定します。
D3の値より小さくて、かつ、もっとも大きい値を探します。
だってそうですよね、基準値は範囲で設定されてますから、仮に90%ならバッチリ90%の値でないと一致しないんじゃ判定できません。

■a、ア

次の基準2も同じ要領で、垂直照合を使って信用度を求めます。

第1引数の式には、自己資本比率の値を指定します。
G3ですね、ここも相対参照になります。
第2引数の範囲には、信用度評価基準の基準2に対応する下限度(%)と信用度のセル範囲を指定します。
行位置が2~6だったのが7~11に変わるだけです、絶対参照もそのままです。
第3引数の列の位置には、2を指定します。
同様ですね、求める信用度は2列目にあります。
第4引数の検索の指定には、1を指定します。
ちなみに、Excelで同じはたらきをするVLOOKUP関数では、ここをTRUEとFALSEで指定します。

■b、キ

[a]と[b]で求めた信用度に対応する与信枠係数を使って、基準1と基準2の計算値を求めます。
与信枠の計算式は表1にあります。

基準1は、0もしくは(流動資産-流動負債)×与信枠係数です。
(流動資産-流動負債)は(B3-C3)でいいですね。
与信枠係数には、もう一度垂直照合を使用します。

第1引数は、同じくD3。
第2引数は、与信枠係数を参照するために終わりの列がFになります。
第3引数は、与信枠係数を参照するために3になります。
第4引数も、同じく1。

■c、ウ

基準2は、0もしくは自己資本×与信枠係数です。
自己資本はF3です。

もう大丈夫ですね。
垂直照合の第1引数をG3にして、第2引数の行範囲を2~6から7~11にするだけです。

■d、ケ

基準1と基準2の計算値がそろいました。
木桶原理にのっとって、低いほうの基準を与信枠に採用します。
ただし、与信枠が負の値となった場合は0になります。

低いほうを採用しますから、使用する関数は最小です。

おや、関数の説明がありませんね。
いいえ、表計算ソフトの機能・用語の77ページにあります。
難しい関数じゃないけど、ちょっと不親切です。
あせらず確認しておきましょう。

与信枠が負の値かどうかは、IFを使って判定します。
これも77ページを見てください。

ここまでわかれば選択肢はひとつしかありません、数式の引数を確認する必要もありません。

■e、ア

【設問2】
次は与信管理の表を完成させます。
ワークシート'与信管理'のA~K列は、ワークシート'与信枠'とまったく同じです。
途中の列が…で省略されているのは、この設問で使わないからです。
思い切って無視しちゃいましょう。

信用度の基準1と基準2から、支払いサイトの月数を求めます。
行方向が基準1、列方向が基準2です。

ですが、ここで使用するのは垂直照合でも水平照合でもありません。
これらの関数だとセルの値を返してしまうからです。
必要なのは、基準1の行の位置と基準2の列の位置です。
位置を返すのは、照合一致の関数です。

この行の位置と列の位置を引数にして、表引きの関数から月数を求めます。
表引きの中に行位置を求める照合一致と列位置を求める照合一致が入ってきますから、数式はかなり長くなります。
うっかり見間違わないよう気を付けてください。

まずは、外側の照合一致について見てみます。
第1引数の範囲は、ワークシート'支払いサイト'の数値が入力されているセル範囲を指定します。
この範囲に対して、何行目で何列目の値を返すのかを設定します。
第2引数の行の位置は、照合一致で基準1の信用度が何行目にあるかを指定します。
第3引数の列の位置は、照合一致で基準2の信用度が何行目にあるかを指定します。

選択肢がオ~クに絞られましたね、あとはふたつの照合一致の中身を考えるだけです。

続いて、行方向の照合一致を見てみます。
第1引数の式には、基準1の信用度があるH3を指定します。
第2引数の範囲は、ワークシート'支払いサイト'のA2~A6のセル範囲を指定します。
この中で、第1引数の値と一致する信用度が何番目にあるのかがわかります。
第3引数の検索の指定は、0を指定します。
信用度は慎重とか積極といった文字列ですので、大きい小さいなんて判定できません。
完全一致じゃないと具合がわるいんです。

残る列方向の照合一致も同じ要領です。
第1引数の式には、基準2の信用度があるI3を指定します。
第2引数の範囲は、ワークシート'支払いサイト'のB1~F1のセル範囲を指定します。
おっと、言い忘れてましたが、このふたつの照合一致の範囲は絶対参照にしておきます。
でないと、複写した時に参照元がずれてしまいますからね。
第3引数の検索の指定は、0を指定します。

■f、オ

いよいよ正念場です。
先ほど支払いサイトの月数を求めました。
この月数が多ければ、それだけ支払いに猶予があるということで、つまりは売掛金として残っているということです。
信用のある取引先ならちゃんと回収の見込みがあるということで、3ヶ月分の未払いがあります。

ところで、この管理方法だとひとつ問題があります。
今月3ヶ月の猶予がある優良企業が来月突然1ヶ月の猶予に落ちてしまった場合、実際には2ヶ月分も売掛金が残っているのにもかかわらず、前月売掛金残(千円)には反映されません。
まあ、問題文中でも「売掛金回収は、前倒し及び延滞なく」と述べていますので、どうにかこうにか集金しているんでしょう。
余計なお世話でしたね。

使用する関数は、条件付合計です。
平成22年春季基本情報技術者試験午後問題問13 に出てきた複合条件照合合計とよく似ています。
今回の方が若干簡素になってますから、少し楽です。

第1引数の検索の範囲は、N2~P2のセル範囲を指定します。
行方向に数式を複写しますから、行を絶対参照にします。
この範囲には1~3の値が入力されています。
この値が支払いサイトの月数以下なら、支払が残っていることになります。
第2引数の検索条件の記述は、'≦M3'を指定します。
第1引数の範囲それぞれのセルに対して、≦M3を評価して真となるセルだけ合計の対象に含めます。

ここでまたまたどうでもいい話、「≦M3」ではなく「'≦M3'」となっているのは、検索条件の「記述」だから文字列にしなければならないという意味でしょう。
そもそも、データ型を明確にしてないのにこんなとここだわる必要なんてないのに。

第3引数の合計の範囲は、実際の金額が入力されているN3~P3のセル範囲を指定します。
第1引数で真となったセル位置と相対的に同じ位置にある、第3引数の値だけを合計します。
取引先K1を例にすると、月数は1ですから、第1引数は以下のようになります。
{ 1(真) , 2(偽) , 3(偽) }
{ 対象 , 対象外, 対象外}
{ 2438 , 2212 , 2543 }
= 2438 +  0 +  0

第1引数の範囲は計算するかどうかを判定する場所、第3引数の範囲は実際に計算する場所なんです。

■g、ク

判定結果を満たす条件はふたつあります。
・前月売掛残と当月注文額の合計が与信枠以下であること。
・与信枠が0より大きいこと。
両者は同時に成立していなければなりません。

ですが、選択肢ではIF関数の結果が真ならば×で、偽ならば○となっています。
なんていやらしい、逆を考えなさいというひっかけ問題です。

判定結果を満たさない条件はふたつあります。
・前月売掛残と当月注文額の合計が与信枠より大きいこと。
・与信枠が0であること。
両者の少なくとも片方が成立していれば×となります。

論理和を使います。
(Q3+R3)>L3
L3=0
の条件が少なくとも片方が成立していれば×となります。

■h、ケ

        2011-07-11       基本情報(平23春)表計算

昨日は平成23年度特別試験の基本情報技術者試験が実施されました。
受験されたか方々、暑い中お疲れ様でした。

さて、こちらExcelじゆうちょうでも恒例の午後問の解説をやっちゃいます。
たぶん、どこよりも早い解説サイト?(ただし表計算に限る)

とりあえず、今回の問題は以下の通りです。

↓平成23年特別試験基本情報技術者試験午後問題問13↓
基本情報(平23春)午後問61
基本情報(平23春)午後問62
基本情報(平23春)午後問63
基本情報(平23春)午後問64
基本情報(平23春)午後問65
基本情報(平23春)午後問66
基本情報(平23春)午後問67
基本情報(平23春)午後問68
基本情報(平23春)午後問69

いやはや、今回は質がいい。
IPAで公開している問題のPDFファイルのスキャナがきれいで、いい感じに画像圧縮できました。
ええ、良質な問題用紙です。

肝心の問題はというと、これまでの出題傾向からして、易しすぎず難しすぎずちょうどいいくらいの難易度ではないでしょうか。
ただひとつ、条件付合計というExcelにはない関数が難易度を押し上げていますが、これは以前に複数条件照合合計という類似の関数が登場しています。



7/15(金)追記
申し訳ないです、Excelにこれと対応する関数がありました。
引数の役割も順番もバッチリのやつです。
一応、SUMPRODUCT関数でも同じ計算は可能ですが、解説としては適切ではありませんでした。

Excelで対応しているのは、SUMIF関数です。
使い方は問題文とほぼ同じです。
ただ、第2引数の指定方法が若干異なっています。

問にある条件付き合計は「'<M3'」などと文字列でしていしますが、SUMIF関数では「"<M3"」としても正しい結果が返ってきません。
"M3"という文字列より小さいかどうかを判定されてしまうのです。
文字列は大小の比較はできませんが、TRUEでないということでFALSEと判定され、数式のエラーにはなりません。
Excelでは、「"<"&M3」とするのが正解です。

画像やリンクのファイルは修正したものと差し替えてあります。
大変お騒がせしました。



※条件付合計も複数条件照合合計も、ExcelではSUMPRODUCT関数を使えば同様の計算が可能です。
ですから、過去問題で勉強していればきっと大丈夫なはず。
見栄を張ったら、 基本情報(平22春)午後問13 を見ておけばきっと大丈夫なはず…?

それでは、解説の前に実際にExcelで再現したワームシートを並べておきましょう。
解説文がまだまとまってないとかは知らんぷり知らんぷり。

↓ワークシート'信用度評価基準'↓
ワークシート'信用度評価基準'

↓ワークシート'与信枠'↓
ワークシート'与信枠'

↓ワークシート'支払いサイト'↓
ワークシート'支払いサイト'

↓ワークシート'与信管理'↓
ワークシート'与信管理'

画像だけだったらなんのこっちゃですよね、数式を表示させた含めた各シートをいかにテキストファイルでリンクしておきます。

↓テキストだから罫線なんてないよ↓
与信枠
与信管理

う~ん、よけいわかりにくいですかね。
わかりました、実際のExcelファイル(旧Excel版)をリンクします。
ただし、拡張子が.txtになってますので、適宜.xlsに変更してください。
普通に開いたら文字化けするだけですからね、[名前を付けてリンク先を保存(K)]してくださいね。

↓右クリックですからね↓
平23年春基本情報午後問13_xls ←文字化け注意!

ふう、いっぱい画像はっつけたはっつけた。
本編の解説は明日かなあ?(申し訳ないです)

 | HOME |