<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>アルゴリズムとプログラミング問題を解くコツ | 基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</title>
	<atom:link href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi</link>
	<description>基本情報技術者試験を学習する人のためにつくられた専門メディア。250本以上の記事を掲載し、勉強方法や各分野のポイント、過去問解説など、試験に役立つ情報を発信。試験対策書籍を執筆する著者が、はじめて学ぶ人でもわかりやすく解説します。（2023年度からの新制度に対応済み）</description>
	<lastBuildDate>Fri, 10 Apr 2026 05:38:35 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.29</generator>
	<item>
		<title>具体的な値を入れるとプログラムがわかる練習問題｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/technique_instant_value/</link>
		<pubDate>Sun, 23 Aug 2020 23:30:20 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[2進数]]></category>
		<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[テクニック 具体的な値を想定]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4442</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/technique_instant_value/">具体的な値を入れるとプログラムがわかる練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,pre{font-family:'consolas','Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important;}pre{background:#263238;color:#eceff1;border-radius:unset;font-size:1em;line-height:1.8;position:relative;margin:auto -7.5%;padding:1em 7.5%;}.card-panel>pre{margin:1em -24px;padding:1em 24px;border-radius:unset}.table-container{padding:1.5em 1em}table{font-size:.85em;}@media screen and (min-width:601px){.responsive-width{width:60%}}dl.inline dd{margin-left:2em}.comment{position:absolute;padding:.5em;color:#f44336;background:#fff;font-size:.9em;box-shadow:rgba(0,0,0,.05) 0 4px 12px 0;z-index:3}@media only screen and (max-width:600px){ol{padding-left:1em}.table-container{padding:unset}caption{text-align:left}}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 4　「 M 進数字列を N 進数字列に基数変換するプログラム」（平成 16 年度 秋期 午後）を一部改変</p>
<p>　RadixConv 関数は、 M 進数字列（ 2 ≦ M ≦ 16 ）を、 N 進数字列（ 2 ≦ N ≦ 16 ）に基数変換するプログラムである。</p>
<ol>
<li>M 進数字列および N 進数字列は、数字を表す文字だけで構成され、空白文字は含まない。 11 ～ 16 進数の 10 以上の数字には、 &#8220;A&#8221; ～ &#8220;F&#8221; のアルファベットを用いる。</li>
<li>RadixConv 関数は、 M 進数字列を整数値に変換した後、その整数値を N 進数字列に変換する。その際に、 M 進数字列を整数値に変換する MToInt 関数と、整数値を N 進数字列に変換する IntToN 関数を使う。</li>
<li>MToInt 関数と IntToN 関数は、数字を整数に変換して返す ToInt 関数、整数値を数字に変換する ToStr 関数、文字列の長さを返す Length 関数、および文字列の一部を切り出して返す SubStr 関数を使う。</li>
<li>このプログラムで使われる関数の引数と戻り値の仕様を表 1 ～ 7 に示す。</li>
</ol>
<div class="table-container">
<table class="striped responsive-width">
<caption>表 1　RadixConv 関数</caption>
<thead>
<tr>
<th>引数／<br class="hide-on-med-and-up">戻り値</th>
<th>データ型</th>
<th>意味</th>
</tr>
</thead>
<tr>
<td>Frdx</td>
<td>整数型</td>
<td>変換元の数字列の基数<br class="hide-on-med-and-up">（ 2 ≦ Frdx ≦ 16 ）</td>
</tr>
<tr>
<td>Fnum</td>
<td>文字列</td>
<td>変換元の数字列</td>
</tr>
<tr>
<td>Trdx</td>
<td>整数型</td>
<td>変換後の数字列の基数<br class="hide-on-med-and-up">（ 2 ≦ Trdx ≦ 16 ）</td>
</tr>
<tr>
<td>戻り値</td>
<td>文字列型</td>
<td>変換後の数字列</td>
</tr>
</table>
</div>
<div class="table-container">
<table class="striped responsive-width">
<caption>表 2　MToInt 関数</caption>
<thead>
<tr>
<th>引数／<br class="hide-on-med-and-up">戻り値</th>
<th>データ型</th>
<th>意味</th>
</tr>
</thead>
<tr>
<td>Rdx</td>
<td>整数型</td>
<td>変換元の数字列の基数<br class="hide-on-med-and-up">（ 2 ≦ Rdx ≦ 16 ）</td>
</tr>
<tr>
<td>Num</td>
<td>文字列型</td>
<td>変換元の数字列</td>
</tr>
<tr>
<td>戻り値</td>
<td>整数型</td>
<td>変換後の整数</td>
</tr>
</table>
</div>
<div class="table-container">
<table class="striped responsive-width">
<caption>表 3　IntToN 関数</caption>
<thead>
<tr>
<th>引数／<br class="hide-on-med-and-up">戻り値</th>
<th>データ型</th>
<th>意味</th>
</tr>
</thead>
<tr>
<td>Val</td>
<td>整数型</td>
<td>変換元の整数</td>
</tr>
<tr>
<td>Rdx</td>
<td>整数型</td>
<td>変換後の数字列の基数<br class="hide-on-med-and-up">（ 2 ≦ Rdx ≦ 16 ）</td>
</tr>
<tr>
<td>戻り値</td>
<td>文字列型</td>
<td>変換後の数字列</td>
</tr>
</table>
</div>
<div class="table-container">
<table class="striped responsive-width">
<caption>表 4　ToInt 関数</caption>
<thead>
<tr>
<th>引数／<br class="hide-on-med-and-up">戻り値</th>
<th>データ型</th>
<th>意味</th>
</tr>
</thead>
<tr>
<td>P</td>
<td>文字型</td>
<td>変換元の数字（ &#8220;0&#8221;, &#8220;1&#8221;, …, &#8220;F&#8221; ）</td>
</tr>
<tr>
<td>戻り値</td>
<td>整数型</td>
<td>変換後の整数</td>
</tr>
</table>
</div>
<div class="table-container">
<table class="striped responsive-width">
<caption>表 5　ToStr 関数</caption>
<thead>
<tr>
<th>引数／<br class="hide-on-med-and-up">戻り値</th>
<th>データ型</th>
<th>意味</th>
</tr>
</thead>
<tr>
<td>Q</td>
<td>整数型</td>
<td>変換元の整数（ 0 ≦ Q ≦ 15 ）</td>
</tr>
<tr>
<td>戻り値</td>
<td>文字型</td>
<td>変換後の数字</td>
</tr>
</table>
</div>
<div class="table-container">
<table class="striped responsive-width">
<caption>表 6　Length 関数</caption>
<thead>
<tr>
<th>引数／<br class="hide-on-med-and-up">戻り値</th>
<th>データ型</th>
<th>意味</th>
</tr>
</thead>
<tr>
<td>S</td>
<td>文字列型</td>
<td>長さを求める文字列</td>
</tr>
<tr>
<td>戻り値</td>
<td>整数型</td>
<td>文字列の長さ</td>
</tr>
</table>
</div>
<div class="table-container">
<table class="striped responsive-width">
<caption>表 7　SubStr 関数</caption>
<thead>
<tr>
<th>引数／<br class="hide-on-med-and-up">戻り値</th>
<th>データ型</th>
<th>意味</th>
</tr>
</thead>
<tr>
<td>S</td>
<td>文字列型</td>
<td>切り出し元の文字列</td>
</tr>
<tr>
<td>Idx</td>
<td>整数型</td>
<td>切り出しを始める位置（先頭を 1 とする）</td>
</tr>
<tr>
<td>N</td>
<td>整数型</td>
<td>切り出す文字数</td>
</tr>
<tr>
<td>戻り値</td>
<td>文字列型</td>
<td>S の先頭から Idx の位置から N 文字を返す</td>
</tr>
</table>
</div>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>プログラムは横スクロールできます</p>
<p>［プログラム］</p>
<pre>
◯文字列型: RadixConv(整数型: Frdx, 文字列型: Fnum, 整数型: Trdx)
  return IntToN(MToInt(Frdx, Fnum), Trdx)

◯整数型: MToInt(整数型: Rdx, 文字列型: Num)
  整数型: Idx, Val
  Val ← 0

  for (Idx を 1 から Length(Num) 以下まで 1 つずつ増加)
    Val ← <span class="blank">a</span> + ToInt(Substr(Num, Idx, 1))
  endfor

  return Val

◯文字列型: IntToN(整数型: Val, 整数型: Rdx)
  整数型: Quo	/* 商 */
  整数型: Rem	/* 剰余 */
  文字列型: Num  

  <span class="blank mag_lt00">b</span>
  Num ← ""

  while (Quo が Rdx 以上)
    Rem ← Quo mod Rdx
    Num ← ToStr(Rem) + Num  /* + は文字列を連結する演算子 */
    <span class="blank mag_lt00">c</span>
  endwhile

  <span class="blank mag_lt00">d</span>
  return Num
</pre>
<p class="small-text grey-text mag_bt30"><i class="material-icons yellow-text mag_rt05">add_alert</i>注　ToInt 関数、ToStr 関数、Length 関数、SubStr 関数のプログラムは示さないが、正しく作成されているとする。</p>
<p>設問　プログラム中の<span class="blank"></span>に入れる正しい答えを、解答群の中から選べ。</p>
<p>a に関する解答群<br />
ア　Rdx<br />
イ　Val<br />
ウ　Val × Rdx<br />
エ　Val ÷ Rdx</p>
<p>b ～ d に関する解答群</p>
<dl class="inline">
<dt>ア</dt>
<dd>Quo ← Quo ÷ Rdx</dd>
<dt>イ</dt>
<dd>Quo ← Quo ÷ Rem</dd>
<dt>ウ</dt>
<dd>Quo ← Rdx</dd>
<dt>エ</dt>
<dd>Quo ← Rem ÷ Rdx</dd>
<dt>オ</dt>
<dd>Quo ← Val</dd>
<dt>カ</dt>
<dd>Rem ← Rdx</dd>
<dt>キ</dt>
<dd>Rem ← Val</dd>
<dt>ク</dt>
<dd>Num ← ToStr(Quo) + Num</dd>
<dt>ケ</dt>
<dd>Num ← ToStr(Rem) + Num</dd>
</dl>
</div>
<h2>ポイント1: 自分にわかりやすい具体例を想定する</h2>
<p>RadixConv 関数は、 M 進数字列を N 進数字列に基数変換するプログラムですが、 M と N のままではプログラムを読むことはできません。</p>
<p class="bold">M と N に、自分に分かりやすい具体例を想定してください。</p>
<p>ここでは以下のように想定します。</p>
<ul class="background c-round">
<li>M = 10, N = 2 として、 10 進数字列を 2 進数字列に変換すること</li>
<li>具体的な数字列として、 &#8220;12&#8221; という 10 進数字列を &#8220;1100&#8221; という 2 進数字列に変換する</li>
</ul>
<p>これらの想定によって、 RadixConv 関数は、以下の処理を行うことになります。</p>
<p class="grey-text">図　RadixConv 関数が行う処理の具体例</p>
<pre class="pad_h40">
◯文字列型: RadixConv(整数型: <span class="red-text">Frdx</span>, 文字列型: <span class="red-text">Fnum</span>, 整数型: <span class="red-text">Trdx</span>)
  <span class="red-text">return</span> IntToN(MToInt(<span class="red-text">Frdx</span>, <span class="red-text">Fnum</span>), <span class="red-text">Trdx</span>)
<span class="comment" style="top:.6em;left:21em;">10</span><span class="comment" style="top:.6em;left:30em;">"12"</span><span class="comment" style="top:.6em;left:39em;">2</span><span class="comment" style="bottom:2.5em;left:4em;">戻り値 "1100"</span><span class="comment" style="bottom:2.5em;left:17em;">10</span><span class="comment" style="bottom:2.5em;left:21em;">"12"</span><span class="comment" style="bottom:2.5em;left:26em;">2</span>
</pre>
<p>これで、プログラムの内容を読めるはずです。同じ具体例を想定して、他の関数のプログラムも読んでみましょう。</p>
<h2>ポイント2: 具体例で処理内容を理解し、選択肢をヒントにして穴埋めをする</h2>
<p>まず、空欄 a がある MToInt 関数です。 MToInt 関数は、数字列を数値に変換して返します。</p>
<p>想定した具体例で、プログラムを読んでみましょう。</p>
<p>ここでは、<br />
Rdx = 10 進数の数字列 Num = &#8220;12&#8221; を、<br />
Val = 12 という整数値に変換<br />
して返すことを想定します。</p>
<p class="grey-text">図　MToInt 関数が行う処理の具体例</p>
<pre class="pad_h50">
◯MToInt(整数型: <span class="red-text">Rdx</span>, 文字列型: <span class="red-text">Num</span>)
  整数型: Idx, Val
  Val ← 0

  for (Idx を 1 から <span class="red-text">Length(Num)</span> 以下まで 1 つずつ増加)
    Val ← <span class="blank">a</span> + <span class="red-text">ToInt(Substr(Num, Idx, 1))</span>
  endfor

  return <span class="red-text">Val</span>
<span class="comment" style="top:1em;left:13em;">10</span><span class="comment" style="top:1em;left:22em;">"12"</span><span class="comment" style="top:9em;left:17em;">2</span><span class="comment" style="top:16em;left:18em;">"12" の先頭から 1 文字ずつ取り出し、それを整数に変換する</span><span class="comment" style="top:21.5em;left:9em;">変換後の 12 を返す</span>
</pre>
<p>この想定では、 Length(Num) は 2 です。したがって、 Idx をループカウンタとした繰り返しは、 Idx を 1, 2 と変化させて繰り返します。</p>
<p>繰り返しの中にある</p>
<pre>Substr(Num, Idx, 1)</pre>
<p>は、 &#8220;12&#8221; の先頭から 1 文字ずつ &#8220;1&#8221;, &#8220;2&#8221; を取り出します。</p>
<p>そして、 </p>
<pre>ToInt(Substr(Num, Idx, 1))</pre>
<p>は、 &#8220;1&#8221;, &#8220;2&#8221; という数字を、 1, 2 という数値に変換します。関数は、 12 という戻り値を返すので、空欄 a がある</p>
<pre>Val ← <span class="blank">a</span>+ ToInt(Substr(Num, Idx, 1))</pre>
<p> は、 1, 2 から 12 を作り出し、それを Val に格納する処理です。</p>
<p>&nbsp;</p>
<p>それでは、どうすれば 1, 2 から 12 を作り出せるでしょう。</p>
<p>もしも、手順が思い浮かばないなら、選択肢を見てください。選択肢の中に必ず正解があるのですから、選択肢を見れば「あっ、これだ！」と気付くはずです。</p>
<blockquote>
<p class="blue-grey-text">a に関する解答群<br />
ア　Rdx<br />
イ　Val<br />
ウ　Val × Rdx<br />
エ　Val ÷ Rdx</p>
</blockquote>
<p>1, 2 から 12 を作り出すには、 1 を 10 倍して、それに 2 を足せばよいのです。つまり、</p>
<pre>Val ← <span class="blank">a</span>+ ToInt(Substr(Num, Idx, 1))</pre>
<p>の部分が、</p>
<pre>Val ← [Val × 10] + 2</pre>
<p>になればよいのです。ここでは、 Rdx = 10 を想定しているので、これに該当するのは、 Val × Rdx （選択肢ウ）です。</p>
<h2>ポイント3: 具体的な場面を想定して穴埋めを行う</h2>
<p>今度は、空欄 b, 空欄 c, 空欄 d がある IntToN 関数です。 IntToN 関数は、整数値を数字列に変換して返します。</p>
<p>想定した具体例で、プログラムを読んでみましょう。ここでは、<br />
Val = 12 という整数値を、<br />
Rdx = 2 進数の数字列 Num = &#8220;1100&#8221; に変換<br />
して返すことを想定します。</p>
<pre class="pad_h40 mag_h30">
◯文字列型: IntToN(整数型: <span class="red-text">Val</span>, 整数型: <span class="red-text">Rdx</span>)
  整数型: Quo	/* 商 */
  整数型: Rem	/* 剰余 */
  文字列型: Num  

  <span class="blank mag_lt00">b</span>
  Num ← ""

  while (Quo が Rdx 以上)
    Rem ← Quo mod Rdx
    Num ← <span class="red-text">ToStr(Rem)</span> + Num  /* + は文字列を連結する演算子 */
    <span class="blank mag_lt00">c</span>
  endwhile

  <span class="blank mag_lt00">d</span>
  return <span class="red-text">Num</span>
<span class="comment" style="top:.6em;left:19em;">12</span><span class="comment" style="top:.6em;left:27em;">2</span><span class="comment" style="top:25em;left:13em;">除算の余りを上位桁に連結する</span><span class="comment" style="bottom:2.5em;left:9em;">"1100"</span>
</pre>
<pre>Rem ← Quo mod Rdx</pre>
<p>の部分で、 Quo を Rdx = 2 で除算した余りを Rem に格納し、</p>
<pre>Num ← ToStr(Rem) + Num</pre>
<p>の部分で、それを数字にして、戻り値 Num （数字列）上位桁に連結しています。</p>
<p>どうして、これらの処理で、 12 を &#8220;1100&#8221; に変換できるのでしょう。</p>
<p>これは、手作業で 10 進数を 2 進数に変換する手順に当てはめればわかるはずです。</p>
<p>&nbsp;</p>
<p>手作業で 12 という 10 進数を 2 進数に変換するには、以下のように 12 を 2 で除算して余りを得る処理を繰り返します。</p>
<figure><figcaption class="mag_h10 center grey-text">図　手作業で 12 という 10 進数を 2 進数に変換する手順</figcaption><img class="materialboxed z-depth-5 hoverable responsive-width" src="../../wp-content/uploads/2020/08/figure_calc_10_2.jpg" loading="lazy" /><br />
</figure>
<p>これによって、変換後の 2 進数が下位桁から順に得られるので、後から得られた値を文字に変換して上位桁に連結すればよいのです。</p>
<p>&nbsp;</p>
<p>このプログラムでは、被除数が Quo で、序数が Rdx = 2 です。 Quo の初期値は、 Val = 12 であるべきなので、空欄 b は Quo ← Val （選択肢オ）です。</p>
<pre class="pad_tp40">
◯文字列型: IntToN(整数型: <span class="red-text">Val</span>, 整数型: <span class="red-text">Rdx</span>)
  整数型: Quo	/* 商 */
  整数型: Rem	/* 剰余 */
  文字列型: Num  

  <span class="blank mag_lt00">b</span>
  Num ← ""
<span class="comment" style="top:.6em;left:19em;">12</span><span class="comment" style="top:.6em;left:27em;">2</span>
</pre>
<p>Rem ← Quo mod Rdx の部分で、 Rem に除算の余りを求めたら、次の繰り返し処理に備えて、 Quo の値を除算の商で更新するべきなので、空欄 c は Quo ← Quo ÷ Rdx （選択肢ア）です。</p>
<pre>
  while (Quo が Rdx 以上)
    Rem ← Quo mod Rdx
    Num ← <span class="red-text">ToStr(Rem)</span> + Num  /* + は文字列を連結する演算子 */
    <span class="blank mag_lt00">c</span>
  endwhile
<span class="comment" style="top:7em;left:13em;">除算の余りを上位桁に連結する</span>
</pre>
<p>&#8220;Quo が Rdx 以上&#8221; つまり &#8220;Quo が 2 以上&#8221; という条件で繰り返しを行っているので、繰り返しを抜けると Quo は 1 になっています。繰り返しを抜けたら最後に、この 1 を文字に変換して上位桁に連結する必要があるので、空欄 d は Num ← ToStr(Quo) + Num （選択肢ク）です。</p>
<pre class="pad_bt40">
  while (Quo が Rdx 以上)
    Rem ← Quo mod Rdx
    Num ← <span class="red-text">ToStr(Rem)</span> + Num  /* + は文字列を連結する演算子 */
    <span class="red-text">Quo ← Quo ÷ Rdx</span>
  endwhile

  <span class="blank mag_lt00">d</span>
  return <span class="red-text">Num</span>
<span class="comment" style="top:17em;left:9em;">"1100"</span>
</pre>
<p>&nbsp;</p>
<p class="bold">10 進数を 2 進数に変換する手順は、基本情報技術者試験の受験者なら必ず知っておくべきことです。</p>
<p>それを知っていたからこそ、 &#8220;12&#8221; という 10 進数字列を &#8220;1100&#8221; という 2 進数字列に変換することを想定して、問題を解けたのです。</p>
<p>もしも、試験の出題範囲の中に、まだ手を付けてない分野があるなら、それがアルゴリズム問題のテーマとなることもあるので、必ず学習しておきましょう。</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － ウ, b － オ, c － ア, d ― ク</p>
<div class="divider mag_tp50 mag_bt30"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載は、今回で最終回になります。もしも、これまでの記事の中に理解が不十分なものがあれば、何度も学習を繰り返して「慣れて」ください。そうすれば、多くの問題に共通した解法のポイントをつかめるはずです。</p>
<p>それでは、またお会いしましょう！</p>
<p>&nbsp;</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/technique_instant_value/">具体的な値を入れるとプログラムがわかる練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>具体例からヒントを掴む練習問題｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/actual_case_hinting/</link>
		<pubDate>Sun, 16 Aug 2020 23:30:26 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[テクニック 具体的な値を想定]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4422</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/actual_case_hinting/">具体例からヒントを掴む練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。 とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,pre{font-family:'consolas','Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important;}td{border-left:1px #d0d0d0 solid}table{font-size:.85em;}.red-border-t-l-b{border-left:.3em #e91e63 solid;border-top:.3em #e91e63 solid;border-bottom:.3em #e91e63 solid}.red-border-t-r-b{border-right:.3em #e91e63 solid;border-top:.3em #e91e63 solid;border-bottom:.3em #e91e63 solid}.blue-border-t-l-b{border-left:.3em #03a9f4 solid;border-top:.3em #03a9f4 solid;border-bottom:.3em #03a9f4 solid}.blue-border-t-r-b{border-right:.3em #03a9f4 solid;border-top:.3em #03a9f4 solid;border-bottom:.3em #03a9f4 solid}.blue-border-t-b{border-top:.3em #03a9f4 solid;border-bottom:.3em #03a9f4 solid}pre{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;margin:1em -7.5%;padding:1em 7.5%}.card-panel>pre{margin:1em -24px}.u-pink{background:linear-gradient(transparent 60%,#f8bbd0 40%)}.style-alpha li{list-style-type:lower-alpha}.inline dd{margin-left:2em}@media only screen and (max-width:600px){ol{padding-left:1em}}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 2　「文字列を置換するプログラム」（平成 17 年度 春期 午後）を一部改変</p>
<p>　手続 Replace は、文字列を置換するプログラムである。 Replace には、文字型の配列の引数 A[], S[], D[], B[] があり、 A[] を先頭からコピーして B[] に格納する（ B[] は十分に大きいとする）。 このとき、 A[] 中に S[] と一致する文字列を見つけるたびに、それを D[] の内容に置き換える。 このプログラムで扱う文字型の配列の添字は 0 から始まり、配列の末尾には定数 EOS が格納されている。</p>
<div class="table-container">
<table class="centered bordered responsive-width">
<caption>図　Replace の実行例</caption>
<tr>
<th>添字</th>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<th>A[]</th>
<td>&#8220;a&#8221;</td>
<td>&#8220;a&#8221;</td>
<td>&#8220;b&#8221;</td>
<td>&#8220;c&#8221;</td>
<td>&#8220;a&#8221;</td>
<td>&#8220;b&#8221;</td>
<td>&#8220;b&#8221;</td>
<td>EOS</td>
<td></td>
<td></td>
</tr>
<tr>
<th>S[]</th>
<td>&#8220;a&#8221;</td>
<td>&#8220;b&#8221;</td>
<td>EOS</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>D[]</th>
<td>&#8220;A&#8221;</td>
<td>&#8220;B&#8221;</td>
<td>&#8220;C&#8221;</td>
<td>EOS</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>B[]</th>
<td>&#8220;a&#8221;</td>
<td>&#8220;A&#8221;</td>
<td>&#8220;B&#8221;</td>
<td>&#8220;C&#8221;</td>
<td>&#8220;c&#8221;</td>
<td>&#8220;A&#8221;</td>
<td>&#8220;B&#8221;</td>
<td>&#8220;C&#8221;</td>
<td>&#8220;b&#8221;</td>
<td>EOS</td>
</tr>
</table>
</div>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>表やプログラムは横スクロールできます</p>
<p>［プログラム］</p>
<pre>
◯Replace(文字型の配列: A, 文字型の配列: S, 文字型の配列: D, 文字型の配列: B)
  整数型: Aidx, Sidx, Didx, Bidx, Idx
  Aidx ← 0
  Bidx ← 0

  while (A[Aidx] が EOS と等しくない)
    if (A[Aidx] と S[0] が等しい)
      Idx ← Aidx
      <span class="blank">a</span>

      do
        Sidx ←　Sidx + 1
        Aidx ←　Aidx + 1
      while (<span class="blank">b</span>と A[Aidx] がどちらとも EOS と等しくない)

      if (<span class="blank">c</span>)
        Didx ← 0

        while (D[Didx] が EOS と等しくない)
          B[Bidx] ← D[Didx]
          Didx ← Didx + 1
          Bidx ← Bidx + 1
        endwhile
      else
        <span class="blank">d</span>
        Aidx ← Idx + 1
        Bidx ← Bidx + 1
      endif

      B[Bidx] ← A[Aidx]
      Aidx ← Aidx + 1
      Bidx ← Bidx + 1
    endif
  endwhile

  B[Bidx] ← EOS
</pre>
<p class="mag_tp30">設問</p>
<p>　プログラム中の<span class="blank"></span>に入れる正しい答えを、解答群の中から選べ。</p>
<p>a, d に関する解答群</p>
<dl class="inline">
<dt>ア</dt>
<dd>B[Bidx] ← A[Aidx]</dd>
<dt>イ</dt>
<dd>B[Bidx] ← S[0]</dd>
<dt>ウ</dt>
<dd>Idx ← 0</dd>
<dt>エ</dt>
<dd>Idx ← 1</dd>
<dt>オ</dt>
<dd>Sidx ← 0</dd>
<dt>カ</dt>
<dd>Sidx ← 1</dd>
</dl>
<p>b, c に関する解答群</p>
<dl class="inline">
<dt>ア</dt>
<dd>A[Aidx] と EOS が等しくない</dd>
<dt>イ</dt>
<dd>A[Aidx] と S[Sidx] が等しい</dd>
<dt>ウ</dt>
<dd>A[Aidx] と S[Sidx] が等しくない</dd>
<dt>エ</dt>
<dd>A[Aidx] と S[Sidx] が等しくなく、かつ S[Sidx] と EOS が等しくない</dd>
<dt>オ</dt>
<dd>S[Sidx] と EOS が等しい</dd>
<dt>カ</dt>
<dd>S[Sidx] と EOS が等しくない</dd>
</dl>
</div>
<h2>ポイント1: 問題に示された具体例でプログラムの機能を理解する</h2>
<p>問題文の説明を読んだだけでは、プログラムの機能を理解するのが困難な場合があります。 この問題では、理解を助けるために、具体例が図示されています。</p>
<p>以下のように、問題文の説明と具体例の図を対応させれば、プログラムの機能を理解できるでしょう。</p>
<blockquote>
<p class="blue-grey-text">　手続 Replace は、文字列を置換するプログラムである。 Replace には、文字型の配列の引数 A[], S[], D[], B[] があり、 A[] を先頭からコピーして B[] に格納する（ B[] は十分に大きいとする）。 このとき、 <span class="u-pink">A[] 中に S[] と一致する文字列を見つけるたびに、</span> <span class="u">それを D[] の内容に置き換える。 </span>このプログラムで扱う文字型の配列の添字は 0 から始まり、配列の末尾には定数 EOS が格納されている。</p>
</blockquote>
<p class="center"><i class="material-icons blue-text large">expand_more</i></p>
<div class="table-container">
<table class="centered bordered blue-grey-text responsive-width">
<tr>
<th>添字</th>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<th>A[]</th>
<td>&#8220;a&#8221;</td>
<td class="red-border-t-l-b">&#8220;a&#8221;</td>
<td class="red-border-t-r-b">&#8220;b&#8221;</td>
<td>&#8220;c&#8221;</td>
<td class="red-border-t-l-b">&#8220;a&#8221;</td>
<td class="red-border-t-r-b">&#8220;b&#8221;</td>
<td>&#8220;b&#8221;</td>
<td>EOS</td>
<td></td>
<td></td>
</tr>
<tr>
<th>S[]</th>
<td class="red-border-t-l-b">&#8220;a&#8221;</td>
<td class="red-border-t-r-b">&#8220;b&#8221;</td>
<td>EOS</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>D[]</th>
<td class="blue-border-t-l-b">&#8220;A&#8221;</td>
<td class="blue-border-t-b">&#8220;B&#8221;</td>
<td class="blue-border-t-r-b">&#8220;C&#8221;</td>
<td>EOS</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>B[]</th>
<td>&#8220;a&#8221;</td>
<td class="blue-border-t-l-b">&#8220;A&#8221;</td>
<td class="blue-border-t-b">&#8220;B&#8221;</td>
<td class="blue-border-t-r-b">&#8220;C&#8221;</td>
<td>&#8220;c&#8221;</td>
<td class="blue-border-t-l-b">&#8220;A&#8221;</td>
<td class="blue-border-t-b">&#8220;B&#8221;</td>
<td class="blue-border-t-r-b">&#8220;C&#8221;</td>
<td>&#8220;b&#8221;</td>
<td>EOS</td>
</tr>
</table>
</div>
<h2>ポイント2: プログラムを区切ってコメントを書き込む</h2>
<p>プログラムの機能（概要だけで OK です）を理解できたら、プログラムを区切って、それぞれの区切りごとに、そこで何をしているかをコメントとして書き込んでみましょう（わかる範囲だけで OK です）。</p>
<p>以下に、区切りとコメントの例を示します。 ここでは、区切りの線とコメントを赤色で示していますが、試験当日は、問題用紙に鉛筆で書き込んでください。 こうすることで、プログラムの内容が、とても見やすくなるでしょう。</p>
<pre>
◯Replace(文字型の配列: A, 文字型の配列: S, 文字型の配列: D, 文字型の配列: B)
  整数型: Aidx, Sidx, Didx, Bidx, Idx
  Aidx ← 0
  Bidx ← 0

  while (A[Aidx] が EOS と等しくない)
  <div class="divider red" style="height: .25em; margin-top: 1em;"></div>
    if (A[Aidx] と S[0] が等しい)     <span class="red-text">A[Aidx] と S[0] が等しい場合の処理</span>
      Idx ← Aidx                      <span class="red-text">Idx に Aidx の値を保存する</span>
      <span class="blank">a</span>

      do                              <span class="red-text">A [] と S[] が一致するかどうか繰り返しチェックする</span>
        Sidx ←　Sidx + 1
        Aidx ←　Aidx + 1
      while (<span class="blank">b</span>と A[Aidx] がどちらとも EOS と等しくない)
      <div class="divider red" style="height: .25em; margin-top: 1em;"></div>
      if (<span class="blank">c</span>)               <span class="red-text">A[] と S[] が一致した場合は、</span>
        Didx ← 0                      <span class="red-text">B[] に D[] を格納する</span>

        while (D[Didx] が EOS と等しくない)
          B[Bidx] ← D[Didx]
          Didx ← Didx + 1
          Bidx ← Bidx + 1
        endwhile
      else
        <div class="divider red" style="height: .25em; margin-top: 1em;"></div>
        <span class="blank">d</span>                  <span class="red-text">A[Aidx] と S[0] が等しかったが、</span>
        Aidx ← Idx + 1                <span class="red-text">A[] と S[] が一致しなかった場合の処理</span>
        Bidx ← Bidx + 1
      endif
      
      <div class="divider red" style="height: .25em; margin-top: 1em;"></div>
      B[Bidx] ← A[Aidx]               <span class="red-text">A[Aidx] と S[0] が等しくない場合は、</span>
      Aidx ← Aidx + 1                 <span class="red-text">B[] に A[] を格納する</span>
      Bidx ← Bidx + 1
    endif
  endwhile
  <div class="divider red" style="height: .25em; margin-top: 1em;"></div>

  B[Bidx] ← EOS
</pre>
<h2>ポイント3: 具体的な場面を想定して穴埋めを行う</h2>
<p>プログラムを区切ってコメントを書けたら、穴埋めのある区切りごとに、具体的な場面を想定してみましょう。</p>
<p>まず、<br />
A[1], A[2] の &#8220;a&#8221;, &#8220;b&#8221; が、<br />
S[0], S[1] の &#8220;a&#8221;, &#8220;b&#8221; に一致する<br />
場面を想定してみます。</p>
<p>これに関わるのは、空欄 a, 空欄 b, 空欄 c がある区切りです。 空欄 a と空欄 b がある区切りでは、 A[] と S[] が一致するかどうかをチェックしています。</p>
<pre>
  while (A[Aidx] が EOS と等しくない)
    if (A[Aidx] と S[0] が等しい)     <span class="red-text">A[Aidx] と S[0] が等しい場合の処理</span>
      Idx ← Aidx                      <span class="red-text">Idx に Aidx の値を保存する</span>
      <span class="blank">a</span>

      do                              <span class="red-text">A [] と S[] が一致するかどうか繰り返しチェックする</span>
        Sidx ←　Sidx + 1
        Aidx ←　Aidx + 1
      while (<span class="blank">b</span>と A[Aidx] がどちらとも EOS と等しくない)
</pre>
<pre>if (A[Aidx] と S[0] が等しい) </pre>
<p>の部分では、 Aidx が 1 であり、 A[1] と S[0] が等しいことをチェックします。</p>
<p>その後にある繰り返し処理で、 Sidx と Aidx の値を 1 ずつ増やします。 Sidx は、その名前から S[] の添字だとわかります。</p>
<p>A[1] と S[0] が等しいことをチェックした後は、 A[2] と S[1] が等しいことをチェックします。</p>
<p>したがって、空欄 a は S[Sidx] のSidx を 0 に設定する処理であり、Sidx ← 0 （選択肢オ）です。</p>
<pre>
  while (<span class="blank">b</span>と A[Aidx] がどちらとも EOS と等しくない)
</pre>
<p>の部分では、 A[Aidx] と S[Sidx] が等しい限りチェックが繰り返されます。 したがって、空欄 b は A[Aidx] = S[Sidx] （選択肢イ）です。</p>
<h2>ポイント4: 選択肢を空欄に当てはめて考える</h2>
<p>同じ場面を想定したまま、空欄 d がある区切りを見てみましょう。</p>
<p>ここでは、空欄 c の条件が真なら B[] に D[]を 格納する処理を行っています。</p>
<pre>
if (<span class="blank">c</span>)               <span class="red-text">A[] と S[] が一致した場合は、</span>
  Didx ← 0                      <span class="red-text">B[] に D[] を格納する</span>
  while (D[Didx] が EOS と等しくない)
    B[Bidx] ← D[Didx]
    Didx ← Didx + 1
    Bidx ← Bidx + 1
  endwhile
</pre>
<p>したがって、空欄 c は、 A[] と S[] が一致したことを判断する条件です。 どのような条件でしょうか？</p>
<p>&nbsp;</p>
<p>もしも、プログラムを見ても処理が思い浮かばないなら、選択肢を見てください。</p>
<p>空欄 c の選択肢は、以下に示したア～カがあります。 これらの中に、 A[] と S[] が一致したことを判断できる条件があるのです。</p>
<blockquote>
<p class="blue-grey-text">b, c に関する解答群</p>
<dl class="inline blue-grey-text">
<dt>ア</dt>
<dd>A[Aidx] と EOS が等しくない</dd>
<dt>イ</dt>
<dd>A[Aidx] と S[Sidx] が等しい</dd>
<dt>ウ</dt>
<dd>A[Aidx] と S[Sidx] が等しくない</dd>
<dt>エ</dt>
<dd>A[Aidx] と S[Sidx] が等しくなく、かつ S[Sidx] と EOS が等しくない</dd>
<dt>オ</dt>
<dd>S[Sidx] と EOS が等しい</dd>
<dt>カ</dt>
<dd>S[Sidx] と EOS が等しくない</dd>
</dl>
</blockquote>
<p>これらの選択肢を 1 つずつ空欄 c に当てはめていくと、「あっ、そうか！」と気付くでしょう。</p>
<p>ここで想定している<br />
A[1], A[2] の &#8220;a&#8221;, &#8220;b&#8221; が、<br />
S[0], S[1] の &#8220;a&#8221;, &#8220;b&#8221; に一致する<br />
場面では、 &#8220;A[Aidx] が S[Sidx] と等しい&#8221; という条件が真である限りチェックが繰り返され、 S[Sidx] が EOS になったときに、それまでの文字がすべて等しいことが確認され、繰り返しが終わります。</p>
<p>したがって、 A[] と S[] が一致したことを判断できる条件は、 &#8220;S[Sidx] と EOS が等しい&#8221; （選択肢オ）です。</p>
<h2>ポイント5: 選択肢を見て「待てよ！」と思いとどまる</h2>
<p>最後は、空欄 d がある区切りです。</p>
<p>ここでは、 A[Aidx] と S[0] が等しかったが、 A[] と S[] が一致しなかった場合の処理が行われます。</p>
<p>これは、これまでに想定した場面とは異なるので、<br />
A[0] の &#8220;a&#8221; と S[0] の &#8220;a&#8221; が等しかったが、<br />
A[1] の &#8220;a&#8221; と S[1] の &#8220;b&#8221; が等しくなかった<br />
場面を想定してみましょう。</p>
<pre>
<span class="blank">d</span>                  <span class="red-text">A[Aidx] と S[0] が等しかったが、</span>
Aidx ← Idx + 1                <span class="red-text">A[] と S[] が一致しなかった場合の処理</span>
Bidx ← Bidx + 1
</pre>
<p>この場面では、　B[] に A[0] の &#8220;a&#8221; を格納します。 選択肢を見てみましょう。</p>
<blockquote>
<p class="blue-grey-text">a, d に関する解答群</p>
<dl class="inline blue-grey-text">
<dt>ア</dt>
<dd>B[Bidx] ← A[Aidx]</dd>
<dt>イ</dt>
<dd>B[Bidx] ← S[0]</dd>
<dt>ウ</dt>
<dd>Idx ← 0</dd>
<dt>エ</dt>
<dd>Idx ← 1</dd>
<dt>オ</dt>
<dd>Sidx ← 0</dd>
<dt>カ</dt>
<dd>Sidx ← 1</dd>
</blockquote>
<p>これらの選択肢を見ると、「 B[] に A[0] を格納するのだから、選択肢アの B[Bidx] ← A[Aidx] だろう！」と思うでしょう。</p>
<p>しかし、ここで「待てよ！」と思いとどまってください。</p>
<p>B[] に格納する処理として、もう 1 つ、選択肢イの B[Bidx] ← S[0] があります。</p>
<p>A[Aidx] は、 A[] と S[] が一致するかどうかのチェックで Aidx に 1 を加えているので 0 ではなくなっています。<br />
S[0] には、 Aidx が 0 のときの</p>
<pre>if (A[Aidx] が S[0] と等しい)</pre>
<p>というチェックが真だったのですから、 A[0] の &#8220;a&#8221; が入っています。</p>
<p>したがって、空欄 d は、 B[Bidx] ← S[0]（選択肢イ）です。</p>
<p>&nbsp;</p>
<p>このように、<span class="u">同様の処理をしている選択肢がある場合は、最初に「これかな？」と思っても、そこで早合点せずに、他の選択肢も「もしかすると、これかも？」と確認するようにしてください。 </span>選択肢は、大きなヒントなのですから、大いに活用しましょう。</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － オ, b － イ, c － オ, d ― イ</p>
<div class="divider mag_tp50 mag_bt30"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。 アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/actual_case_hinting/">具体例からヒントを掴む練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>プログラムを分割するコツがわかる練習問題｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/partitioning_program/</link>
		<pubDate>Thu, 06 Aug 2020 04:46:00 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[テクニック 具体的な値を想定]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4407</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/partitioning_program/">プログラムを分割するコツがわかる練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。 とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,pre{font-family:consolas,'Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important}pre{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;padding:.5em 0 .5em 1em;}.card-panel>pre{margin:1em -24px;padding:1em 24px}ol.style-alpha li{list-style-type:lower-alpha}dl.inline dd{margin-left:2em}@media only screen and (max-width:600px){ol{padding-left:1em}}</style>
<h2>練習問題</h2>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>プログラムは横スクロールできます</p>
<div class="card-panel">
問 4　「タブ文字を展開するプログラム」（平成 18 年度 秋期 午後）を一部改変</p>
<p>　手続 TabSpc は、タブ文字を展開するプログラムである。</p>
<ol>
<li>TabSpc は、引数で指定された文字型配列 Src[] を先頭から調べ、 Src[] 中のすべてのタブ文字をそれぞれ一つ以上の間隔文字（スペース）に変換して、引数で指定された文字型配列 Dst[] に格納する。 </li>
<li>文字型配列の各要素には、文字を 1 文字ずつ順に格納し、最後の文字の次の要素にはシステム定数である EOS を格納する。 なお、配列の添字は 1 から始まり、添字の値を文字位置と呼ぶ。 </li>
<li>Src[] 中にタブ文字が出現した場合、次の文字が最も近い右のタブ位置に格納されるように、タブ文字を一つ以上の間隔文字に置換して、 Dst[] （要素数は十分に大きいとする）に格納する。 ここで、タブ位置とは、整数型の引数 TabGap で渡されるタブ間隔（≧ 2）を用いて、次の式で計算される文字位置である。
<pre class="mag_w00">タブ位置 = タブ間隔 × n + 1 （ n は 1 以上の整数）</pre>
</li>
<li>タブ間隔が 4 のときの実行例を図に示す。  &#8220;j&#8221; を Dst[] のタブ位置である文字位置 13 （ = 4 × 3 + 1 ）に格納したのでは、タブ文字が間隔文字に置き換わらないので、最も近い右のタブ位置である文字位置 17 （ = 4 × 4 + 1 ）に格納する。 </li>
</ol>
<figure><figcaption>図　タブ間隔が 4 のときの TabSpc の実行例</figcaption><img class="responsive-width materialboxed hoverable z-depth-5" src="../../wp-content/uploads/2020/08/figure1_q4.jpg" loading="lazy" /><br />
</figure>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>アルゴリズムは横スクロールできます</p>
<p>［プログラム］</p>
<pre>
◯TabSpc(文字型の配列: Src, 文字型の配列: Dst, 整数型: TabGap)
  整数型: Sidx, Didx, N, TabPos
  Sidx ← 1
  Didx ← 1

  while (Src[Sidx] が EOS とは等しくない) /* EOS: 文字列の終わりを表すシステム定数 */
    if (Src[Sidx] が TAB と等しい)        /* TAB: タブ文字を表すシステム定数 */
      N ← ( <span class="blank">a</span> ) ÷ TabGap
      TabPos ← TabGap × N + 1
      while (Didx が TabPos より小さい)
        Dst[Didx] ← SPC                 /* SPC: 間隔文字を表すシステム定数 */
        <span class="blank">b</span>
      endwhile
    else
      <span class="blank">c</span>
      Didx ← Didx + 1
    endif

    Sidx ← Sidx + 1
  endwhile

  Dst[Didx] ← EOS
</pre>
<p class="mag_tp30 bold">設問</p>
<p>プログラム中の<span class="blank"></span>に入れる正しい答えを、解答群の中から選べ。</p>
<p>a に関する解答群</p>
<dl class="inline">
<dt>ア</dt>
<dd>Didx + 1</dd>
<dt>イ</dt>
<dd>Didx &#8211; 1</dd>
<dt>ウ</dt>
<dd>Didx + TabGap + 1</dd>
<dt>エ</dt>
<dd>Didx + TabGap &#8211; 1</dd>
</dl>
<p>b 、 c に関する解答群</p>
<dl class="inline">
<dt>ア</dt>
<dd>Didx ← Didx + 1</dd>
<dt>イ</dt>
<dd>Dst[Didx] ← Src[Sidx]</dd>
<dt>ウ</dt>
<dd>Dst[Didx + 1] ← Src[Sidx]</dd>
<dt>エ</dt>
<dd>Dst[Didx] ← Src[Sidx + 1]</dd>
</div>
<h2>ポイント1: プログラムを区切って見る</h2>
<p><span class="u">私の講師経験上、「アルゴリズムが苦手です！」という受講者の多くは、プログラム全体を一気に見て理解しようとします</span>。 それでは、なかなか理解できなくて当然です。</p>
<p>プログラムというものは、全体をいくつかの部分に区切って見るものだからです。 「そんなこと言われても、どうやって区切ったらよいかわかりません！」だと思いますので、区切り方をアドバイスしましょう。</p>
<p>&nbsp;</p>
<p>プログラムの処理の流れの種類は、<br />
<span class="bold">順次（まっすぐ進む）</span><br />
<span class="bold">分岐（条件に応じて選択する）</span><br />
<span class="bold">反復（条件に応じて繰り返す）</span><br />
の 3 つです。</p>
<p>擬似言語では、何も指定しなければ順次になり、 if と endif で囲めば分岐になり、 while と endwhile で囲めば反復になります。 これらの表記に注目すれば、機械的に区切れるはずです。</p>
<p>プログラムを区切った例を下図に示します。</p>
<figure><figcaption>図　プログラムを「順次」「分岐」「反復」で区切った例</figcaption><pre style="position:relative;" class="grey">
◯TabSpc(文字型の配列: Src, 文字型の配列: Dst, 整数型: TabGap)<span class="badge white grey-text">順次</span>
  整数型: Sidx, Didx, N, TabPos
  Sidx ← 1
  Didx ← 1
<div class="grey darken-1" style="margin-left:2em;">while (Src[Sidx] が EOS とは等しくない) /* EOS: 文字列の終わりを表すシステム定数 */<span class="badge white grey-text text-darken-1">反復</span>
  
  
  
  
  
  
  
  
  
  
  
  
  
endwhile</div><span>  Dst[Didx] ← EOS</span><span class="badge white grey-text">順次</span>
<span class="grey darken-3" style="position:absolute;top:9.5em;left:4em">if (Src[Sidx] が TAB と等しい)        /* TAB: タブ文字を表すシステム定数 */<span class="badge white grey-text text-darken-3">分岐</span>
  N ← ( <span class="blank">a</span> ) ÷ TabGap
  TabPos ← TabGap × N + 1
  while (Didx が TabPos より小さい)
    Dst[Didx] ← SPC                 /* SPC: 間隔文字を表すシステム定数 */
    <span class="blank">b</span>
  endwhile
else
  <span class="blank">c</span>
  Didx ← Didx + 1
endif

Sidx ← Sidx + 1</span></pre>
</figure>
<p>プログラムを区切ったことで、空欄 a 、空欄 b 、空欄 c があるのが、分岐の部分だとわかります。 それがわかったら（ここが大事です！）、<span class="bold">プログラム全体ではなく、分岐の部分だけを見てください。 </span></p>
<p>この分岐は、どのような条件で分岐するのでしょう。</p>
<pre>Src[Sidx] が TAB と等しい</pre>
<p>という条件が真なら空欄 a と空欄 b がある上側の処理を行い、そうでないなら空欄 c がある下側の処理を行います。 これもプログラムの区切りです。 これらの区切りごとに、プログラムを見てください。</p>
<h2>ポイント2: わかりやすい部分を先に穴埋めする</h2>
<p><span class="u">空欄の穴埋めは、わかりやすい部分から先に行ってください。 </span>分岐の下側にある空欄 c の穴埋めが、わかりやすいでしょう。</p>
<p>ここでは、 Src[Sidx] が TAB と等しい という条件が真でないときの処理なのですから、 Src[] から取り出した文字（タブ文字でない文字）を、そのまま Dst[] に格納する処理です。</p>
<p>したがって、</p>
<pre>Dst[Didx] ← Src[Sidx]</pre>
<p>が適切であり、選択肢イが正解です。</p>
<h2>ポイント3: 選択肢をヒントにして考える</h2>
<p>それでは、空欄 a と空欄 b がある分岐の上側の処理を見てみましょう。</p>
<p>ここは、 Src[Sidx] が TAB と等しい という条件が真のときの処理なので、タブ文字を間隔文字に置き換える処理です。</p>
<pre>
  N ← ( <span class="blank">a</span> ) ÷ TabGap
  TabPos ← TabGap × N + 1
  while (Didx が TabPos より小さい)
    Dst[Didx] ← SPC                 /* SPC: 間隔文字を表すシステム定数 */
    <span class="blank">b</span>
  endwhile
</pre>
<p>空欄 a より空欄 b の方がわかりやすそうなので、空欄 b の穴埋めを先に行うことにしましょう。</p>
<p>さて、どのような処理をすればよいのでしょうか？</p>
<p>こういうことは、腕を組んで考えることではありません。 基本情報技術者試験の問題は、すべて多岐選択式です。 <span class="u">したがって、解答群に示された選択肢をヒントにして考えてください。 </span></p>
<p>空欄 b の選択肢を以下に示します。</p>
<blockquote>
<p class="blue-grey-text">b 、 c に関する解答群</p>
<dl class="inline blue-grey-text">
<dt>ア</dt>
<dd>Didx ← Didx + 1</dd>
<dt>イ</dt>
<dd>Dst[Didx] ← Src[Sidx]</dd>
<dt>ウ</dt>
<dd>Dst[Didx + 1] ← Src[Sidx]</dd>
<dt>エ</dt>
<dd>Dst[Didx] ← Src[Sidx + 1]</dd>
</dl>
</blockquote>
<p>空欄 b の処理が、</p>
<p>選択肢アだったら？<br />
選択肢イだったら？<br />
選択肢ウだったら？<br />
選択肢エだったら？</p>
<p>と考えると「あっ、そうか！」と気付くでしょう。</p>
<p>空欄 b は、 Dst[Didx] に必要な数だけ SPC （間隔文字）を格納する処理です。  1 つ SPC を格納したら、 Didx に 1 を加えて格納先を 1 つ先に進めます。</p>
<p>したがって、選択肢アの</p>
<pre>Didx ← Didx + 1</pre>
<p>が正解です。</p>
<h2>ポイント4: 具体例を想定し、想定した値で計算する</h2>
<p>それでは、最後に残った空欄 a の穴埋めです。</p>
<p>ここは、空欄 a から N（ タブ位置の計算式の n ）の値を求め、さらに N から TabPos （タブ位置）の値を求める処理です。 これは、かなり難しそうです。</p>
<pre>
  N ← ( <span class="blank">a</span> ) ÷ TabGap
  TabPos ← TabGap × N + 1
</pre>
<p>こういうときに頼りになるのが、問題に示された具体例です。</p>
<p>問題には、 TabGap（タブ間隔）= 4 としたときの具体例の図が示されていて、そこには、問題に示された</p>
<blockquote>
<p class="blue-grey-text">タブ位置 = タブ間隔 × n + 1 （ n は 1 以上の整数）</p>
</blockquote>
<p>という計算で得られるタブ位置も示されています。 そして、</p>
<blockquote>
<p class="blue-grey-text">&#8220;j&#8221; を Dst[] のタブ位置である文字位置 13 （ = 4 × 3 + 1 ）に格納したのでは、タブ文字が間隔文字に置き換わらないので、最も近い右のタブ位置である文字位置 17 （ = 4 × 4 + 1 ）に格納する</p>
</blockquote>
<p>という注意書きがあります。 おそらく、この注意書きが答えを見出すポイントなのでしょう。</p>
<p>&nbsp;</p>
<p>この注意書きに注目して、具体例を想定してみましょう。</p>
<p>Src[] の文字位置 12 にあるタブ文字を展開するときに、 Dst[] のタブ位置が 13 でなく 17 になればよいわけです。</p>
<p>空欄 a の選択肢を見ると、どれも Dst[] の格納先である Didx が含まれています。 想定した場面では、</p>
<p>  Didx = 13<br />
  TabGap = 4</p>
<p>なので、選択肢ア～エの値は、以下になります。</p>
<p>整数の割り算では、小数点以下がカットされることに注意してください。</p>
<dl class="background c-round inline">
a に関する解答群</p>
<dt>ア</dt>
<dd>Didx + 1 = 12 + 1 = 13</dd>
<dt>イ</dt>
<dd>Didx = 1 = 12 = 1 = 11</dd>
<dt>ウ</dt>
<dd>Didx + TabGap + 1 = 12 + 4 + 1 = 17</dd>
<dt>エ</dt>
<dd>Didx + TabGap = 1 = 12 + 4 = 1 = 15</dd>
</dl>
<p>この 13, 11, 17, 15 をプログラムの空欄 a に入れて、 TabPos を求めると以下になります。</p>
<pre>
選択肢ア
  N ← (13) ÷ 4 ・・・ N は 3 になる。
  TabPos ← 4 × N + 1 ・・・ TabPos は 13 になる。

選択肢イ
  N ← (11) ÷ 4 ・・・ N は 2 になる。
  TabPos ← 4 × N + 1 ・・・ TabPos は 9 になる。

選択肢ウ
  N ← (17) ÷ 4 ・・・ N は 4 になる。
  TabPos ← 4 × N + 1 ・・・ TabPos は 17 になる。

選択肢エ
  N ← (15) ÷ 4 ・・・ N は 3 になる。
  TabPos ← 4 × N + 1 ・・・ TabPos は 13 になる。
</pre>
<p>ここでは、 TabPos が 17 になればよいので、選択肢ウが正解です。 やはり、注意書きが答えを見出すポイントでした。</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － ウ, b － ア, c － イ</p>
<div class="divider mag_tp50 mag_bt30"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。 アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/partitioning_program/">プログラムを分割するコツがわかる練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>手順をヒントにトレースする練習問題｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/trace_with_steps/</link>
		<pubDate>Thu, 09 Jul 2020 06:45:08 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[トレースのコツ]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4316</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/trace_with_steps/">手順をヒントにトレースする練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,pre{font-family:consolas,'Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important}pre{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;margin:1em -7.5%;padding:1em 7.5%}.card-panel>pre{margin:1em -24px;padding:1em 24px}ol.style-alpha li{list-style-type:lower-alpha}@media only screen and (max-width:600px){ol{padding-left:1.5em}}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 4　「挿入ソートで昇順に整列するプログラム」（平成 19 年度 春期 午後）を一部改変</p>
<p>　手続 InsertSort は、引数で与えられた配列 A[] を、挿入ソートで昇順に整列する。配列 A[] の添字は 0 から始まり、要素数は引数 N で与えられる。挿入ソートの手順は、次のとおりである。</p>
<ol>
<li>まず、 A[0] と A[1] を整列し、次に A[0] から A[2] までを整列し、その次に A[0] から A[3] までというように、整列する区間の要素を一つずつ増やしていき、最終的に A[0] から A[N &#8211; 1] までを整列する。</li>
<li>整列する区間が A[0] から A[M]（ 1 ≦ M &lt; N ）までのとき、 A[M] を既に整列された列 A[0] , <i class="material-icons">more_horiz</i>, A[M &#8211; 1] 中の適切な位置に挿入する。その手順は次のとおりである。
<ol class="style-alpha mag_h20">
<li>A[M] の値を、作業領域 Tmp に格納する。</li>
<li>A[M &#8211; 1] から A[0] に向かって Tmp と比較し、 Tmp よりも大きな値を順次隣（要素番号の大きい方）に移動する。</li>
<li>b. で最後に移動した値の入っていた配列要素に Tmp の値を格納する。 b. で移動がなかった場合には A[M] に格納する。</li>
</ol>
</li>
</ol>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>プログラムは横スクロールできます</p>
<p>［プログラム］</p>
<pre>
◯InsertSort(整数型の配列: A, 整数型: N)
  整数型: Idx1, Idx2, Tmp
  論理型: Loop

  for (Idx1 を 1 から N より小さい間 1 つずつ増やす)
    Tmp ← A[Idx1]
    Idx2 ← <span class="blank">a</span>
    Loop ← true

    while (Idx2 が 0 以上でかつ Loop が true)
      if (A[Idx2] が Tmp より大きい)
        <span class="blank">b</span>
        Idx2 ← Idx2 - 1
      else
        Loop ← false
      endif
    endwhile

    A[Idx2 + 1] ← Tmp
  endfor
</pre>
<p>設問　プログラム中の<span class="blank"></span>に入れる正しい答えを、解答群の中から選べ。</p>
<p>a に関する解答群<br />
ア　Idx1<br />
イ　Idx1 + 1<br />
ウ　Idx1 &#8211; 1<br />
エ　1 &#8211; Idx1</p>
<p>b に関する解答群<br />
ア　A[Idx2] ← A[Idx2 + 1]<br />
イ　A[Idx2] ← A[Idx2 &#8211; 1]<br />
ウ　A[Idx2 + 1] ← A[Idx2]<br />
エ　A[Idx2 &#8211; 1] ← A[Idx2]
</p></div>
<h2>ポイント1: 手順の説明とプログラムを対応付ける（その1）</h2>
<p>この問題のように、<span class="u">問題文に手順が詳しく示されている場合は、手順の説明とプログラムを対応付けることで、空欄で行う処理がわかる</span>場合がよくあります。</p>
<p>以下は、手順の説明とプログラムを対応付けた例です。ここでは、手順の説明を<span class="light-blue-text">青色の文字</span>でコメントとして追加しています。実際の試験では、これを頭の中でやってください。</p>
<figure><figcaption>図　手順の説明とプログラムを対応付けた例</figcaption>［プログラム］</p>
<pre>
◯InsertSort(整数型の配列: A, 整数型: N)
  整数型: Idx1, Idx2, Tmp
  論理型: Loop

  <span class="light-blue-text">/* 1. まず、 A[0] と A[1] を整列し、次に A[0] から A[2] までを整列し、*/</span>
  <span class="light-blue-text">/* その次に A[0] から A[3] までというように、整列する区間の要素を一つ */</span>
  <span class="light-blue-text">/* ずつ増やしていき、最終的に A[0] から A[N - 1] までを整列する。 */</span>
  for (Idx1 を 1 から N より小さい間 1 つずつ増やす)
    <span class="light-blue-text">/* 2. 整列する区間が A[0] から A[M] ( 1 ≦ M &lt; N ) までのとき、A[M] を */</span>
    <span class="light-blue-text">/* 既に整列された列 A[0], <i class="material-icons">more_horiz</i>, A[M - 1] 中の適切な位置に挿入する。 */</span>
    <span class="light-blue-text">/* その手順は次のとおりである。 */</span>
    <span class="light-blue-text">/*  a. A[M] の値を、作業領域 Tmp に格納する。 */</span>
    Tmp ← A[Idx1]
    <span class="light-blue-text">/*  b. A[M - 1] から A[0] に向かって */</span>
    Idx2 ← <span class="blank">a</span>
    Loop ← true

    while (Idx2 が 0 以上でかつ Loop が true)
      <span class="light-blue-text">/* Tmp と比較し、Tmp よりも大きな値を */</span>
      if (A[Idx2] が Tmp より大きい)
        <span class="light-blue-text">/* 順次隣（要素番号の大きい方）に移動する。 */</span>
        <span class="blank">b</span>
        Idx2 ← Idx2 - 1
      else
        Loop ← false
      endif
    endwhile

    <span class="light-blue-text">/* c. b. で最後に移動した値の入っていた配列要素に Tmp の値を格納する。 */</span>
    <span class="light-blue-text">/* b. で移動がなかった場合には A[M] に格納する。 */</span>
    A[Idx2 + 1] ← Tmp
  endfor
</pre>
</figure>
<h2>ポイント2: 手順の説明とプログラムを対応付ける（その2）</h2>
<p>手順の説明とプログラムを対応付けたことで、以下がわかります。</p>
<pre>
  <span class="light-blue-text">/*  a. A[M] の値を、作業領域 Tmp に格納する。 */</span>
  Tmp ← A[Idx1]
</pre>
<p>手順の説明で M と呼んでいる変数は、プログラムでは Idx1 です。</p>
<pre>
  <span class="light-blue-text">/*  b. A[M - 1] から A[0] に向かって */</span>
  Idx2 ← <span class="blank">a</span>
  Loop ← true

  while (Idx2 が 0 以上でかつ Loop が true)
</pre>
<blockquote class="mag_h10">
<p class="grey-text"> A[M &#8211; 1] から A[0] に向かって</p>
</blockquote>
<p>を A[Idx2] で示すので、空欄 a で Idx2 に設定する初期値は M &#8211; 1 です。説明の M がプログラムでは Idx1 なので、空欄 a は Idx1 &#8211; 1 であり、選択肢ウが正解です。</p>
<h2>ポイント3: 手順の説明とプログラムを対応付ける（その3）</h2>
<p>空欄 b がある分岐では、</p>
<pre>
  <span class="light-blue-text">/* Tmp と比較し、Tmp よりも大きな値を */</span>
  if (A[Idx2] が Tmp より大きい)
    <span class="light-blue-text">/* 順次隣（要素番号の大きい方）に移動する。 */</span>
    <span class="blank">b</span>
    Idx2 ← Idx2 - 1
</pre>
<blockquote class="mag_h10">
<p class="grey-text">Tmp と比較し、 Tmp よりも大きな値を順次隣（要素番号の大きい方）に移動する。</p>
</blockquote>
<p>という処理を行っています。</p>
<pre>A[Idx2] が Tmp より大きい</pre>
<p>なのですから、 Tmp より大きな値は A[Idx2] であり、この値を順次隣（要素番号の大きい方）に移動するのですから、 A[Idx2 + 1] ← A[Idx2] が適切であり、選択肢ウが正解です。</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － ウ, b － ウ</p>
<div class="divider mag_tp50 mag_bt30"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/trace_with_steps/">手順をヒントにトレースする練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>トレースのテクニックが身につく練習問題｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/technique_trace/</link>
		<pubDate>Wed, 08 Jul 2020 08:06:19 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[スタック]]></category>
		<category><![CDATA[テクニック 具体的な値を想定]]></category>
		<category><![CDATA[トレースのコツ]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4292</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/technique_trace/">トレースのテクニックが身につく練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,pre{font-family:consolas,'Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important}pre{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;margin:1em -7.5%;padding:1em 7.5%}.card-panel>pre{margin:1em -24px;padding:1em 24px}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 4　「スタックを使って整数値を 10 進数字列に変換するプログラム」（平成 19 年度 秋期 午後）を一部改変</p>
<p>　スタックを使って整数値を 10 進数字列（文字列）に変換する IntFormat 関数である。 IntFormat 関数は、引数 Int で指定された整数値を 10 進数字列に変換し、その先頭の数字（文字）から 1 文字ずつ順に引数 Out[] に格納し、格納した文字数を引数 Len に格納する。整数値を 10 進数字列に変換する手順は、次のとおりである。</p>
<ol class="mag_h30">
<li>Int の値がゼロの場合は、 Out[0] に &#8220;0&#8221; を、 Len に 1 を格納して、関数を終了する。</li>
<li>Int の値が負の場合は、負符号を表す &#8220;-&#8221; を Out[] に格納し、 Int の値を正数に変換する。</li>
<li>Int の 1 の位から上位に向かって、 1 けたずつ 10 進数字に変換し、 Push 関数でスタックに積む。</li>
<li>スタックに積み終わったら、スタックに積んだ文字を順番に Pop 関数で取り出して Out[] に格納することによって、変換後の 10 進数字を正しい順序に並び替える。</li>
<li>Len に Out[] に格納した文字数を設定して、関数を終了する。</li>
</ol>
<p>　引数の値をスタックに積む Push 関数と、スタックから取り出した値を戻り値として返す Pop 関数は、あらかじめ用意されているとする。配列の添字は 0 から始まり、 Out[] の要素数は十分に大きいものとする。プログラム中の各演算で、あふれは生じないものとする。 IntFormat 関数の変換例を下図に示す。</p>
<figure><figcaption class="mag_h10 small-text center grey-text">図　IntFormat 関数の変換例</figcaption><img class="materialboxed hoverable z-depth-5 responsive-width" data-caption="図　IntFormat 関数の変換例" src="../../wp-content/uploads/2020/07/q4_figure.jpg" loading:"lazy"><br />
</figure>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>アルゴリズムは横スクロールできます</p>
<p>［プログラム］</p>
<pre>
◯IntFormat(整数型: Int, 文字型の配列: Out, 整数型: Len)
  整数型: L, I, Idx
  文字型の配列: Chr ← {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
  文字型: T

  L ← 0

  /* 引数 Int がゼロの場合の処理 */
  if (Int が 0 )
    Out[L] ← Chr[Int]
    L ← L + 1
    Len ← L
    return
  endif

  /* 符号の処理 */
  if (Int が 0 より小さい)
    I ← -Int
    Out[L] ← "-"
    L ← 1 + 1
  else
    I ← Int
  endif

  /* 数値を 1 けたずつ数字に変換してスタックに格納する処理 */
  Push("#")     /* スタックに番兵として "#" を積む */

  while (I が 0 より大きい)
    Idx ← I - (I ÷ 10) × 10
    Push(Chr[Idx])
    I ← <span class="blank">a</span>
  endwhile

  /* スタックから取り出す処理 */
  T ← Pop()

  while (T が "#" でない)
    Out[L] ← T
    <span class="blank">b</span>
    T ← Pop()
  endwhile

  Len ← L
  return
</pre>
<p>設問　プログラム中の<span class="blank"></span>に入れる正しい答えを、解答群の中から選べ。</p>
<p>a に関する解答群<br />
ア　I &#8211; 10<br />
イ　I &#8211; I ÷ 10<br />
ウ　I &#8211; ( I ÷ 10 ) × 10<br />
エ　I ÷ 10</p>
<p>b に関する解答群<br />
ア　L ← L + 1<br />
イ　L ← L &#8211; 1<br />
ウ　I ← I + 1<br />
エ　I ← I &#8211; 1
</p></div>
<h2>ポイント1：数値と数字の違いを知る</h2>
<p>数値と数字は、異なるものです。たとえば、 123 は、 1 つの数値です。これを画面に表示するときは、 &#8220;1&#8221;, &#8220;2&#8221;, &#8220;3&#8221; という 3 つの文字を表示することになります。</p>
<p><span class="u">このように数値の 1 けたずつを 1 つの文字にしたものが数字です。</span></p>
<p>問題に示された IntFormat 関数の変換例を見てください。 IntFormat 関数は、引数 Int に指定された 123 という数値を、 &#8220;1&#8221;、&#8221;2&#8243;、&#8221;3&#8243; という数字に変換して引数 Out[] に格納し、その文字数の 3 を引数 Len に格納するのです。</p>
<p>&nbsp;</p>
<p>コンピュータの内部では、あらゆる情報を数値で表しています。したがって、 &#8220;1&#8221;, &#8220;2&#8221;, &#8220;3&#8221; という数字も、その<span class="u">実体は、それぞれの数字に割り当てられた文字コードの数値</span>です。</p>
<p>何という数値が割り当てられるかは、使用する文字コード体系によって異なりますが、たとえば JIS X 0201 という文字コード体系では、<br />
&#8220;1&#8221; は 49、<br />
&#8220;2&#8221; は 50、<br />
&#8220;3&#8221; は 51<br />
です。 49 、50 、51 を文字型として画面に出力すると、それぞれに対応した &#8220;1&#8221;, &#8220;2&#8221;, &#8220;3&#8221; という数字が表示されるのです。</p>
<p>&nbsp;</p>
<p>この問題では、文字コードは示されていません。その代わりに、</p>
<pre>文字型の配列: Chr ← {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}</pre>
<p>という文字の配列を用意しています。</p>
<p>配列の添字が 0 から始まるとしているので、 Chr[0] ～ Chr[9] は、 0 から 9 の数値に対応する &#8220;0&#8221; ～ &#8220;9&#8221; という数字になります。</p>
<p>たとえば、<span class="u">変数 Idx の値が 5 なら、 Char[Idx] は、数値 5 に対応する &#8220;5&#8221; という数字</span>になります。</p>
<h2>ポイント2： コメントをヒントにして、問題文の説明とプログラムを対応付ける</h2>
<p>この問題のように、<span class="bold">処理の手順が示されている場合は、手順とプログラムを対応付けることで、空欄で行う処理がわかる</span>場合がよくあります。</p>
<p>その際に、<span class="u">プログラムの中にあるコメントも大いに参考にしてください。</span>試験問題のプログラムのコメントは、<span class="bold">コメント（注釈）というよりは、ヒント</span>だからです。</p>
<p>&nbsp;</p>
<p>手順の説明の (1) は、プログラムで </p>
<pre>/* 引数 Int がゼロの場合の処理 */</pre>
<p>というコメントに対応した処理です。</p>
<p>ここには、空欄がないので (1) に示されている</p>
<blockquote>
<p class="grey-text"> Int の値がゼロの場合は、 Out[0] に &#8220;0&#8221; を、 Len に 1 を格納して、関数を終了する</p>
</blockquote>
<p>という処理をやっているのだ、と考えるだけで OK です。<span class="u">プログラムの内容を詳しく見る必要はありません。</span></p>
<p>&nbsp;</p>
<p>同様に、手順の説明の (2) は、プログラムの </p>
<pre>/* 符号の処理 */</pre>
<p>の部分に対応し、ここにも空欄がないので、プログラムの内容を詳しく見る必要はありません。</p>
<h2>ポイント3： 具体的な数値を想定して処理の流れをトレースする</h2>
<p>手順の説明の (3) は、プログラムの</p>
<pre>/* 数値を1けたずつ数字に変換してスタックに格納する処理 */</pre>
<p>に対応し、ここには空欄 a があるので、</p>
<blockquote>
<p class="grey-text">Int の 1 の位から上位に向かって、 1 けたずつ 10 進数字に変換し、 Push 関数でスタックに積む</p>
</blockquote>
<p>という説明と対応付けて、プログラムの内容を詳しく見てみましょう。</p>
<p>以下に、該当するプログラムの部分を示します。</p>
<pre>
  /* 数値を 1 けたずつ数字に変換してスタックに格納する処理 */
  Push("#")     /* スタックに番兵として "#" を積む */

  while (I が 0 より大きい)
    Idx ← I - (I ÷ 10) × 10
    Push(Chr[Idx])
    I ← <span class="blank">a</span>
  endwhile
</pre>
<p><span class="bold">プログラムを見る（読み取る）コツは、わかりやすい具体例を想定すること</span>です。</p>
<p>ここでは、変換する数値を格納している変数 I に 123 が格納されていることを想定してみましょう。</p>
<blockquote>
<p class="grey-text"> Int の 1 の位から上位に向かって、 1 けたずつ 10 進数字に変換し、 Push 関数でスタックに積む</p>
</blockquote>
<p>という説明なので、 123 という数値を、 3, 2, 1 の順に、 &#8220;3&#8221;, &#8220;2&#8221;, &#8220;1&#8221; という数字に変換して、 Push 関数でスタックに積みます。</p>
<p>スタックに積むのは、&#8221;3&#8243;, &#8220;2&#8221;, &#8220;1&#8221; の順に変換しただけでは順序が逆だからです。<br />
&#8220;1&#8221;<br />
&#8220;2&#8221;<br />
&#8220;3&#8221;<br />
の順に変換してスタックに積み、それをスタックから取り出すと<br />
&#8220;1&#8221;, &#8220;2&#8221;, &#8220;3&#8221;<br />
という正しい順序にできます。<span class="bold">スタックでは、積んだときと逆の順序で取り出すことになる</span>からです。</p>
<p>それでは、プログラムを見てみましょう。</p>
<p>まず、</p>
<pre>|・Idx ← I - (I ÷ 10) × 10</pre>
<p>という処理の I に 123 を想定すると、</p>
<pre>|・Idx ← 123 - (123 ÷ 10) × 10</pre>
<p>になります。</p>
<p>123 ÷ 10 は、整数同士の割り算なので、<span class="u">小数点以下がカットされて（これは、とっても重要なことなので必ず覚えておいてください）</span>、 12 になります。<br />
× 10 で、それを 10 倍するので、<br />
(123 ÷ 10) × 10 は、 120 になります。</p>
<p>したがって、</p>
<pre>123 - (123 ÷ 10) × 10</pre>
<p>は、 123 &#8211; 120 = 3 になって、変数 Idx には、 123 の最下位けたの 3 が得られます。</p>
<p>次に、</p>
<pre>Push(Chr[Idx])</pre>
<p>という処理の Idx に 3 を想定すると、</p>
<pre>Push(Chr[3])</pre>
<p>となります。 Chr[3] は &#8220;3&#8221; なので、これによって 3 という数値が &#8220;3&#8221; という数字に変換されて、スタックにプッシュされます。</p>
<p>次に、</p>
<pre>I ← <span class="blank">a</span></pre>
<p>という処理に空欄 a があります。これは、次に同じ処理（最下位けたの数値を取り出して、それを数字に変換してスタックに積む）に合わせて、変数 I の値を更新する処理です。</p>
<p>この処理の前で、変数 I の値は 120 になっています。これを 12 に変換すれば、最下位けたが 2 になります。さあ、空欄 a では、どのような処理を行えばよいのでしょう？</p>
<div class="grey lighten-5 c-round pad_20">
<i class="material-icons light-blue-text">search</i><span class="blue-grey-text mag_w05">タグで関連記事をチェック</span><a href="../../tag/スタック" class="tag">スタック</a><a class="tag" href="../../tag/テクニック-具体的な値を想定/">テクニック 具体的な値を想定</a>
</div>
<h2>ポイント4： 選択肢の変数に具体的な値を設定する</h2>
<p>こういうことは、空欄を眺めて腕を組んで考えることではありません。基本情報技術者試験の問題は、すべて選択問題なのですから、必ず選択肢を見て考えてください。</p>
<p>以下に、空欄 a の選択肢を示します。</p>
<blockquote class="mag_h30">
<p class="grey-text">a に関する解答群<br />
ア　I &#8211; 10<br />
イ　I &#8211; I ÷ 10<br />
ウ　I &#8211; ( I ÷ 10 ) × 10<br />
エ　I ÷ 10</p>
</blockquote>
<p>現時点で、変数 I は 120 です。これを 12 にしたいのですから、選択肢の変数 I に 120 を代入して、 12 になるものが正解です。</p>
<p>以下のように、選択肢エが正解です。繰り返しますが、整数の割り算では、小数点以下がカットされることに注意してください。</p>
<div class="background c-round">
a に関する解答群<br />
ア　120 &#8211; 10 = 110<br />
イ　120 &#8211; 120 ÷ 10 = 120 &#8211; 12 = 108<br />
ウ　120 &#8211; (120 ÷ 10) × 10 = 120 &#8211; 120 = 0<br />
エ　120 ÷ 10 = 12
</div>
<h2>ポイント5： 同様の処理をしている部分と見比べる</h2>
<p>手順の説明の（4）は、プログラムの</p>
<pre>/* スタックから取り出す処理 */</pre>
<p>に対応し、ここには空欄 b があるので、</p>
<blockquote>
<p class="grey-text">スタックに積み終わったら、スタックに積んだ文字を順番に Pop 関数で取り出して Out[] に格納することによって、変換後の 10 進数字を正しい順序に並び替える</p>
</blockquote>
<p>という説明と対応付けて、プログラムの内容を詳しく見てみましょう。</p>
<p>以下に、該当するプログラムの部分を示します。</p>
<pre>
  /* スタックから取り出す処理 */
  T ← Pop()

  while (T が "#" でない)
    Out[L] ← T
    <span class="blank">b</span>
    T ← Pop()
  endwhile
</pre>
<p>まず、</p>
<pre>T ← Pop()</pre>
<p>の部分でスタックから取り出した数字を変数 T に格納しています。</p>
<p>次に、</p>
<pre>while (T が "#" でない)</pre>
<p>は、スタックの末尾を示す番兵（目印となるデータのことで、ここでは &#8220;#&#8221; という文字です）を取り出すまで繰り返す、つまりスタックに積まれたデータをすべて取り出すまで繰り返すということです。</p>
<p>次に、</p>
<pre>Out[L] ← T</pre>
<p>で、取り出した数字 T を Out[L] に格納しています。</p>
<p>次に、</p>
<pre><span class="blank">b</span></pre>
<p>という空欄 b があります。</p>
<p>空欄bの穴埋めは、以下の解答群から選びます。さあ、どれでしょう？</p>
<blockquote class="mag_h30">
<p class="grey-text">b に関する解答群<br />
ア　L ← L + 1<br />
イ　L ← L &#8211; 1<br />
ウ　I ← I + 1<br />
エ　I ← I &#8211; 1</p>
</blockquote>
<p>ここでは、プログラムの中で、同様の処理をしている部分と見比べる、ということをしてみましょう。</p>
<p>以下のオレンジ色文字の部分で、同様の処理をしています。</p>
<pre>
  /* 引数 Int がゼロの場合の処理 */
  if (Int が 0 )
    <span class="amber-text">Out[L] ← Chr[Int]</span>
    <span class="amber-text">L ← L + 1</span>
    Len ← L
    return
  endif
</pre>
<pre>
  /* 符号の処理 */
  if (Int が 0 より小さい)
    I ← -Int
    <span class="amber-text">Out[L] ← "-"</span>
    <span class="amber-text">L ← 1 + 1</span>
  else
    I ← Int
  endif
</pre>
<p>これらを見ると、 Out[L] にデータを格納したら、次の格納に備えて L の値を 1 増やす処理をしていることがわかります。空欄 b も同じはずです。</p>
<p>したがって、選択肢アの L ← L + 1 が正解です。</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － エ, b － ア</p>
<div class="divider mag_h50"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/technique_trace/">トレースのテクニックが身につく練習問題｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>2進数を掛け算するプログラム &#124; アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/multiply_binary/</link>
		<pubDate>Tue, 07 Jul 2020 04:18:22 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[2進数]]></category>
		<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4265</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/multiply_binary/">2進数を掛け算するプログラム | アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。 とても短い問題ですので、気軽に取り組んでください。</p>
<style>pre{font-family:'consolas','Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important;background:#263238;color:#eceff1;font-size:1em;line-height:1.8;margin:auto -7.5%;padding:1em 7.5%}.number{position:absolute;left:1%;font-size:2em;color:white;}.card-panel>pre{margin:1em -24px;padding:1em 24px}.border{padding:.2em 2em;border:.2em solid #3f51b5;margin:0 .4em}@media screen and (min-width:601px){.responsive-width{width:50%}}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 8 「符号付き 2 進数の乗算」（平成 22 年度 秋期 午後）を一部改変</p>
<p>　関数 MUL は、二つの整数 M 、 N を受け取り、その積 M × N を返す。 積は、加算とシフト演算を使って求める。 M 、 N 及び求めた積は、いずれも符号付き 2 進数の整数で、負数は 2 の補数で表現する。</p>
<p>　関数 MUL が受け取る M 、 N は、いずれも 4 ビットで、各値の範囲は -8 ～ 7 である。 求めた積 M × N は、 8 ビットで返す。 ただし、プログラム中では、 M を 5 ビットに、 N を 8 ビットに拡張して処理を行う。</p>
<p>　R は、 13 ビットの作業用変数であり、最下位から順にビット番号を 0, 1, ・・・とし、最上位（符号ビット）のビット番号を 12 とする。 R は、指定した一部の範囲（例えば、ビット番号 12 ～ 8 の上位 5 ビット）だけを符号付き 2 進数とみなして部分的な算術演算ができる。 また、値の検査のために指定したビット番号の内容を取り出すこともできる。</p>
<p>　M = -5 、N = 3 の場合の処理過程を、図に示す。 図中の記号 ① ～ ⑧ は、プログラムの ① ～ ⑧ の行の処理と対応している。 なお、 ⑥ の行の加算では、けたあふれが起きても無視する。</p>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>アルゴリズムは横スクロールできます</p>
<p>［プログラム］</p>
<pre style="position: relative;">
◯整数型: MUL(M, N)
  符号付き 2 進整数型: M, N, R
  整数型: L
  M を 5 ビットの符号付き 2 進数に拡張
  N を 8 ビットの符号付き 2 進数に拡張
  R のビット番号 7 ～ 0 に N を複写
  R のビット番号 12 ～ 8 を 0 で初期化
  for (L を 1 から 8 以下まで 1 つずつ増やす)
    if (R のビット番号 0 のビットが 1)
      R のビット番号 12 ～ 8 の内容に M の値を加算
    endif
    R の全 13 ビットを右に 1 ビット算術シフト	/* 空いたビット位置には符号と同じものが入る */
  endfor
  return (R のビット番号 7 ～ 0 の内容)      /* 返却値（括弧内）を返す */<span class="number" style="top:2.7em;">&#10102;</span><span class="number" style="top:3.6em;">&#10103;</span><span class="number" style="top:4.5em;">&#10104;</span><span class="number" style="top:5.4em;">&#10105;</span><span class="number" style="top:7.2em;">&#10106;</span><span class="number" style="top:8.1em;">&#10107;</span><span class="number" style="top:9.9em;">&#10108;</span><span class="number" style="top:11.7em;">&#10109;</span>
</pre>
<figure><figcaption>図　プログラムの実行例（ M = -5, N = 3 ）</figcaption><figcaption>注　網掛けの部分は、表示していない。 </figcaption><img class="materialboxed hoverable z-depth-5 responsive-width" data-caption="図　プログラムの実行例（ M = -5, N = 3 ）" src="../../wp-content/uploads/2020/07/h22a_q8_figure.jpg" loading="lazy" /><br />
</figure>
<p>設問　プログラム中の<span class="border"></span>に入れる正しい答えを、解答群の中から選べ。</p>
<p>a に関する解答群<br />
ア　<img src="../../wp-content/uploads/2020/07/q8_a_option_a.jpg" style="vertical-align:middle;" loading="lazy">　<br class="hide-on-med-and-up">イ　<img src="../../wp-content/uploads/2020/07/q8_a_option_i.jpg" style="vertical-align:middle;" loading="lazy"><br />
ウ　<img src="../../wp-content/uploads/2020/07/q8_a_option_u.jpg" style="vertical-align:middle;" loading="lazy">　<br class="hide-on-med-and-up">エ　<img src="../../wp-content/uploads/2020/07/q8_a_option_e.jpg" style="vertical-align:middle;" loading="lazy"></p>
<p>b に関する解答群<br />
ア　<img src="../../wp-content/uploads/2020/07/q8_bc_option_a.jpg" style="vertical-align:middle;" loading="lazy">　<br class="hide-on-med-and-up">イ　<img src="../../wp-content/uploads/2020/07/q8_bc_option_i.jpg" style="vertical-align:middle;" loading="lazy"><br />
ウ　<img src="../../wp-content/uploads/2020/07/q8_bc_option_u.jpg" style="vertical-align:middle;" loading="lazy">　<br class="hide-on-med-and-up">エ　<img src="../../wp-content/uploads/2020/07/q8_bc_option_e.jpg" style="vertical-align:middle;" loading="lazy"><br />
オ　<img src="../../wp-content/uploads/2020/07/q8_bc_option_o.jpg" style="vertical-align:middle;" loading="lazy">　<br class="hide-on-med-and-up">カ　<img src="../../wp-content/uploads/2020/07/q8_bc_option_k.jpg" style="vertical-align:middle;" loading="lazy">
</div>
<h2>ポイント1：2進数の取り扱いに慣れておく</h2>
<p>2 進数が苦手な人は、この問題を見て「すご～く難しそう！」と感じたでしょう。 それなら、この機会に、 2 進数の取り扱いに慣れておきましょう。</p>
<p>基本情報技術者試験の旧午後試験のアルゴリズム問題では、それほど頻度は多くありませんが、 2 進数を取り扱う問題が出ることがあったからです。 お手元の教材（きっと何らかの教材をお持ちでしょう）に示された 2 進数に関する知識を、丁寧に学習してください。</p>
<p>この問題を解くには、以下の知識が必要になります。 どれも基礎知識ですので、しっかりマスターしておいてください。</p>
<ul class="background c-round">
<li>10 進数と 2 進数の変換</li>
<li>2 進数の加算</li>
<li>2 の補数表現</li>
<li>符号ビット</li>
<li>算術右シフト</li>
<li>符号拡張</li>
</ul>
<div class="divider mag_bt30"></div>
<p><i class="material-icons light-blue-text">search</i><span class="blue-grey-text mar_w10">タグで関連記事をチェック</span><a class="tag" href="../../tag/2進数">2 進数</a></p>
<h2>ポイント2：符号拡張は、同じ値のままビット数を増やす</h2>
<p>ちゃんと 2 進数の知識があれば、この問題は、決して難しくありません。 問題に示された数値を、問題に示された手順通りに、順番に処理していけばよいからです。</p>
<p>問題に示されたプログラムの内容は、プログラムというより、処理内容を説明した文書です。 それぞれの文書を読めば、処理内容がわかります。</p>
<p>プログラムの各行に付けられた ① ～ ⑧ は、穴埋めがある図に示された ① ～ ⑧ に対応しています。</p>
<p>それぞれに合わせて、問題に示された数値の変化を図の中に書き込んでいけば、穴埋めに入る数値がわかります。</p>
<p>&nbsp;</p>
<p>それでは、やってみましょう。</p>
<p>まず、 ① と ② です。 ここでは、符号拡張（問題文では「拡張」と呼んでいる）を行っています。 符号拡張とは、同じ値（符号も同じ）のままビット数を増やすことです。</p>
<p>ここでは、 2 の補数表現を使っているので、符号ビット（最上ビット）が<br />
0 ならプラスの値であり、<br />
1 ならマイナスの値です。</p>
<p>同じ値のままビット数を増やすには、増やした上位桁を、<br />
プラスの値なら 0 で満たし、<br />
マイナスの値なら 1 で満たします。</p>
<p>どちらの場合も、符号ビットを上位桁に「ぐい～ん」と拡張しているように見えるので、符号拡張と呼ぶのです。</p>
<figure>
<img class="hoverable z-depth-5 materialboxed pad_05 responsive-width" src="../../wp-content/uploads/2020/07/q8_explanation_1.png" loading="lazy"><br />
</figure>
<h2>ポイント3： 算術右シフトは、空いた上位桁に符号ビットと同じ値を入れる</h2>
<p>次に、空欄 a があるところまで、数値の変化を見ていきましょう。</p>
<p>③ では、 R の下位桁に N を複写しています。<br />
④ では、 R の上位桁を 0 で埋めています。<br />
⑤ では、 R の最下位桁が 1 であることをチェックしています。<br />
⑥ では、 R の上位桁に M を加算しています。</p>
<p>この時点では、 R の上位桁がすべて 0 なので、グレー表示になっている部分に、 M の値をそのまま入れれば OK です。 ここまでの手順には、特に難しいことはないでしょう。</p>
<figure>
<img class="hoverable z-depth-5 materialboxed responsive-width pad_05" src="../../wp-content/uploads/2020/07/q8_explanation_2.png" loading="lazy"><br />
</figure>
<p>次の ⑦ では、 R の全ビットを右に 1 ビット算術シフトします。</p>
<p><span class="u">「算術」シフトであることに注意</span>してください。 右シフトすると、上位桁に空きができます。 算術シフトでは、ここに符号ビットと同じ値を入れます。 こうすることで、符号を変えずに、値を 1/2 にできます。</p>
<p>ここでは、シフト前の値が</p>
<pre>1101100000011</pre>
<p>なので、右に 1 ビット算術シフトすると、空いた上位桁に符号ビットと同じ値の 1 を入れて、 </p>
<pre>1110110000001</pre>
<p>になります。</p>
<p>したがって、空欄 a は、 111011 であり、選択肢エが正解です。</p>
<figure>
<img class="hoverable z-depth-5 materialboxed responsive-width pad_05" src="../../wp-content/uploads/2020/07/q8_explanation_3.png" loading="lazy"><br />
</figure>
<h2>ポイント4：2進数の加算は、2で桁上がりする</h2>
<p>次の ⑥ では、 11101 と 11011 を加算します。</p>
<p>ここでは、 2 進数の加算なので、下位桁から加算を行って、結果が 2 になったら桁上がりすることに注意してください。</p>
<p>問題文に、最上位桁からの桁あふれは無視するとあるので、以下のように計算して、結果は 11000 になります。</p>
<pre>
    11101
+   11011
---------
    11000
</pre>
<p>この 11000 を ⑥ の下のグレー表示になっている部分に入れ、次の ⑦ で右に 1 ビット算術シフトします。</p>
<p>先ほどと同様に、ここでも最上位桁の符号ビットが 1 なので、空いた上位桁に符号ビットと同じ 1 を入れて、空欄 b は、 1110001 になります。 正解は、選択肢オです。</p>
<figure>
<img class="hoverable z-depth-5 materialboxed responsive-width" src="../../wp-content/uploads/2020/07/q8_explanation_4.png" loading="lazy"><br />
</figure>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － エ, b － オ</p>
<div class="divider mag_h50"></div>
<p><strong>「習うより慣れろ」</strong>ということわざがあります。 アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/multiply_binary/">2進数を掛け算するプログラム | アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>ヒープを配列で実現するプログラム｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/heap/</link>
		<pubDate>Tue, 23 Jun 2020 06:22:10 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4223</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/heap/">ヒープを配列で実現するプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。 とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,article pre{font-family:consolas,'Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important}pre{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;margin:1em -7.5%;padding:1em 7.5%}.card-panel>pre{margin:1em -24px;padding:1em 24px}pre{scrollbar-width:thin;}dl.background dt{font-weight:700;margin:1em auto}dd .chip{background:#3f51b5;color:#fff;margin:.5em}.amber-border{border:solid .2em #ffc107;}@media only screen and (max-width:600px){dl dd,dl.background dd{margin-left:0}}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 8  (平成 30 年度 春期 午後）を一部改変</p>
<p>手続 makeHeap は、配列 data に格納されている hnum 個（ hnum > 0 ）のデータを、次の (1) ～ (3) の規則で配列 heap に格納して、ヒープを配列で実現する。 配列の添字は、 0 から始まる。</p>
<dl class="inline">
<dt>(1)</dt>
<dd>heap[i] ( i = 0, 1, 2, ・・・) は、ヒープの節に対応する。</dd>
<dt>(2)</dt>
<dd>heap[0] は、根に対応する。</dd>
<dt>(3)</dt>
<dd>heap[i] ( i = 0, 1, 2, ・・・) に対応する節の左側の子は heap[2 × i + 1] に対応し、右側の子は heap[2 × i + 2] に対応する。 子が一つの場合、左側の子として扱う。</dd>
</dl>
<p>ヒープの例を図 1 に、図 1 に対応する配列 heap の例を図 2 に示す。</p>
<figure class="mag_h30 mag_w00"><figcaption class="mag_h10 grey-text center">図 1　ヒープの例</figcaption><img data-caption="図 1　ヒープの例" class="hoverable z-depth-5 materialboxed responsive-width pad_05" src="../../wp-content/uploads/2020/06/q8_figure_1.jpg" loading="lazy" /><br />
</figure>
<figure class="mag_h30 mag_w00"><figcaption class="mag_h10 grey-text center">図 2　図 1 のヒープの例に対応した配列 heap の内容</figcaption><img data-caption="図 2　図 1 のヒープの例に対応した配列 heap の内容" class="hoverable z-depth-5 materialboxed responsive-width pad_05" src="../../wp-content/uploads/2020/06/q8_figure_2.jpg" loading="lazy" /><br />
</figure>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>アルゴリズムは横スクロールできます</p>
<p>［プログラム］</p>
<pre>
◯makeHeap(整数型の配列: data, 整数型の配列: heap, 整数型: hnum)
  整数型: i, k

  for (i が 0 から hnum より小さい間 1 ずつ増やす)
    heap[i] ← data[i]	/* heap にデータを追加 */
    k ← i

    while ( k が 0 より大きい)
      if ( <span class="blank">a</span> )
        swap(heap, k, <span class="blank">b</span> )
        k ← parent(k)
      elseif
        break		/* 内側の繰り返し処理から抜ける */
      endif
    endwhile
  endfor
</pre>
<p class="bold mag_tp30">設問</p>
<p>プログラム中の<span class="blank"></span>に入れる正しい答えを、解答群の中から選べ。</p>
<ul class="background c-round">
<li>プログラムおよび解答群の中で使われている関数 lchild( 整数型: k ) は、添字 k の配列要素に対応する節の左側の子の添字 2 × k + 1 を戻り値として返す。 </li>
<li>関数 rchild( 整数型: k ) は、添字 k の配列要素に対応する節の右側の子の添字 2 × k + 2 を戻り値として返す。 </li>
<li>関数 parent( 整数型: k ) 関数は、添字 k の配列要素に対応する親の添字 ( k &#8211; 1 ) ÷ 2 （小数点以下切捨て）を戻り値として返す。 </li>
<li>関数 swap( 整数型: heap[], 整数型: i, 整数型: j ) は、 heap[i] と heap[j] の値を交換する。 </li>
</ul>
<p>a に関する解答群</p>
<dl class="inline">
<dt>ア</dt>
<dd>heap[k] が heap[lchild(k)] より大きい</dd>
<dt>イ</dt>
<dd>heap[k] が heap[parent(k)] より大きい</dd>
<dt>ウ</dt>
<dd>heap[k] が heap[rchild(k)] より大きい</dd>
<dt>エ</dt>
<dd>heap[k] が heap[lchild(k)] より小さい</dd>
<dt>オ</dt>
<dd>heap[k] が heap[parent(k)] より小さい</dd>
<dt>カ</dt>
<dd>heap[k] が heap[rchild(k)] より小さい</dd>
</dl>
<p>b に関する解答群</p>
<pre>
ア　heap[hnum - 1]
イ　heap[k]
ウ　parent(hnum - 1)
エ　parent(k)
</pre>
</div>
<h2>ポイント1: シラバスに示されたアルゴリズムとデータ構造を知っておこう</h2>
<p>この問題を見て「ヒープって何だろう？」と思った人は、試験の出題範囲の学習が不足しています。  IPA（情報処理推進機構）の Web ページから試験の出題範囲の細目を示した <a href="https://www.jitec.ipa.go.jp/1_13download/syllabus_fe_ver8_0_yotei.pdf#page=12" rel="noopener" target="_blank">シラバス</a> という資料を入手できます。</p>
<p>これを見ると、「代表的なアルゴリズム」および「データ構造の種類」として、以下が出題範囲であることが示されています。 ここには、ちゃんと「ヒープ」という言葉があります。</p>
<dl class="background c-round">
<span class="bold">【代表的なアルゴリズム】</span></p>
<dt><i class="material-icons">looks_one</i> 整列・併合・探索のアルゴリズム</dt>
<dd>整列のアルゴリズム、併合のアルゴリズム、探索のアルゴリズムの基本的な設計方法を理解する。</dd>
<dd><span class="chip">用語例</span>選択ソート、バブルソート、マージソート、挿入ソート、シェルソート、クイックソート、ヒープソート、線形探索法、 2 分探索法、ハッシュ表探索法</p>
<dd>
<dt><i class="material-icons">looks_two</i> 再帰のアルゴリズム</dt>
<dd>再帰的アルゴリズムの基本を理解する。</dd>
<dt><i class="material-icons">looks_3</i> グラフのアルゴリズム</dt>
<dd>グラフのアルゴリズムの基本を理解する。</dd>
<dd><span class="chip">用語例</span>深さ優先探索、幅優先探索、最短経路探索</p>
<dd>
<dt><i class="material-icons">looks_4</i> 文字列処理のアルゴリズム</dt>
<dd>文字列処理のアルゴリズムの基本を理解する。</dd>
<dd><span class="chip">用語例</span>文字列照合</p>
<dd>
<dt><i class="material-icons">looks_5</i> ファイル処理のアルゴリズム</dt>
<dd>バッチ処理などで用いる整列処理、併合処理、コントロールブレーク処理、編集処理の基本を理解する。</dd>
<p><span class="bold indigo-text">【データ構造の種類】</span></p>
<dt><i class="material-icons">looks_one</i> 配列</dt>
<dd>配列の特徴、基本的な操作を理解する。</dd>
<dd><span class="chip">用語例</span>多次元配列、静的配列、動的配列</p>
<dd>
<dt><i class="material-icons">looks_two</i> リスト</dt>
<dd>リストの基本的な考え方、その操作を理解する。</dd>
<dd><span class="chip">用語例</span>線形リスト、単方向リスト、双方向リスト、環状リスト</p>
<dd>
<dt><i class="material-icons">looks_3</i> スタックとキュー</dt>
<dd>スタックとキューの特徴、基本的な操作を理解する。</dd>
<dd><span class="chip">用語例</span>FIFO 、LIFO 、プッシュ、ポップ</p>
<dd>
<dt><i class="material-icons">looks_4</i> 木構造</dt>
<dd>木構造の種類と特徴、木の巡回法、節の追加や削除、ヒープの再構成などを理解する。</dd>
<dd><span class="chip">用語例</span>根、葉、枝、 2 分木、完全 2 分木、バランス木、順序木、多分木、探索木、 2 分探索木、深さ優先探索、幅優先探索、先行順、後行順、中間順</p>
<dd>
</dl>
<p>アルゴリズムに「ヒープソート」があり、データ構造に「ヒープ」があるからこそ、この問題が出題されたのです。</p>
<p>ヒープに限らず、<span class="u">もしもシラバスの中に知らないアルゴリズムやデータ構造があったら、教材（きっと何らかの教材をお持ちでしょう）で学習してください。 </span></p>
<p>すべてを詳細に理解する必要はありませんが、少なくとも、それが何であるかは、わかるようにしておきましょう。</p>
<h2>ポイント2: ヒープのデータ構造を知っておこう</h2>
<p>ヒープは、1 つのデータが枝分かれして 2 つのデータにつながる 2 分木の一種です。</p>
<p>ヒープを図示するときには、慣例として、データを円で囲んで示し、円を線で結んでデータのつながりを示します。</p>
<p>データを「節（ノード）」と呼び、線を「枝（ブランチ）」と呼びます。<br />
枝分かれの元にある節を「親」と呼び、枝分かれの先にある節を「子」と呼びます。<br />
最上部にある節を「根（ルート）」と呼びます。<br />
最下部にあり枝がない節を「葉（リーフ）」と呼ぶこともあります。</p>
<p>どれも、自然界の木の構成要素を示す名称と同じです。</p>
<figure class="mag_h30 mag_w00"><figcaption class="grey-text mag_h10 center">ヒープの構成要素</figcaption><img data-caption="ヒープの構成要素" class="hoverable z-depth-5 materialboxed responsive-width pad_05" src="../../wp-content/uploads/2020/06/q8_figure_heap.jpg" loading="lazy" /><br />
</figure>
<p>ヒープでは、<br />
「左右に関係なく、親の値が子の値より小さい」とする場合と、<br />
「左右に関係なく、親の値が子の値より大きい」とする場合があります。</p>
<p>この問題では、後者になっています。</p>
<figure class="mag_h30 mag_w00">
<img class="hoverable z-depth-5 materialboxed responsive-width pad_05" src="../../wp-content/uploads/2020/06/q8_figure_heap_1.jpg" loading="lazy" /><br />
</figure>
<p>ヒープに限らず、どのようなデータ構造でも、それをプログラムで実現するときには、<span class="bold">配列</span>が使われます。</p>
<p>ここでは、問題に示された (1) ～ (3) の規則で、ヒープを配列で実現しています。</p>
<figure class="mag_h30 mag_w00">
<img class="hoverable z-depth-5 materialboxed responsive-width pad_05" src="../../wp-content/uploads/2020/06/q8_figure_heap_2.jpg" loading="lazy" /><br />
</figure>
<h2>ポイント3: ヒープを作成する手順を知っておこう</h2>
<p>この問題を解くには、ヒープのデータ構造だけでなく、ヒープを作成する手順を知っていなければなりません。 問題に示された手続 makeHeap は、配列 data に格納された hnum 個の要素を、ヒープの形式で配列 heap に格納するものだからです。</p>
<p>ヒープは、以下の (1) ～ (3) の手順で作成できます。</p>
<p>ここでは、かなり大雑把に手順を示しています。 <span class="u">新たな要素を仮に格納してから、要素を交換して、適切な位置に移動させることがポイント</span>です。</p>
<ol class="background c-round">
<li>配列 data の要素を先頭から 1 つずつ順番に取り出し、それを配列 heap の同じ位置に仮に格納する。 </li>
<li>配列 heap に新たに格納した要素が、親の要素より大きいなら、両者を交換することを根に達するまで繰り返す（親の要素より大きくない時点で、繰り返しを途中終了することもある）。 </li>
<li>1. と 2. を配列要素の末尾まで繰り返す。 </li>
</ol>
<p>ヒープを作成する手順がわかったら、問題の穴埋めができます。</p>
<p>以下は、手順に合わせたコメントをプログラムに追加したものです。 コメントは、 <span class="blank">a</span>と<span class="blank">b</span>がある部分まで付けています。</p>
<pre>
◯makeHeap(整数型の配列: data, 整数型の配列: heap, 整数型: hnum)
  整数型: i, k

  for (i が 0 から hnum より小さい間 1 ずつ増やす) <span class="amber-text">/* 配列 data の要素を先頭から末尾まで処理する */</span>
    heap[i] ← data[i]                           <span class="amber-text">/* 配列 data の要素を、配列 heap の同じ位置に仮に格納する */</span>
    k ← i                                       <span class="amber-text">/* 新たに格納した要素の添字を k に格納する */</span>

    while ( k が 0 より大きい)                    <span class="amber-text">/* k が 0 （根）にたどり着くまで繰り返す */</span>
      if ( <span class="blank">a</span> )                         <span class="amber-text">/* <span class="blank amber-border">a</span>が真なら関数 swap で交換処理をする */</span>
        swap(heap, k, <span class="blank">b</span> )              <span class="amber-text">/* heap[k] と heap[<span class="blank amber-border">b</span>] を交換する */</span>
        k ← parent(k)
      elseif
        break
      endif
    endwhile
  endfor
</pre>
<p>関数 swap で交換処理をするのは「子が親より大きい」という条件が真の場合です。</p>
<p>ここでは、子が heap[k] であり、その親の添字は関数 parent(k) で求められるので、「子が親より大きい」という条件は、</p>
<pre>heap[k] が heap[parent(k)] より大きい</pre>
<p>になります。 したがって、<span class="blank">a</span>は選択肢イが正解です。</p>
<p>関数 swap で交換するのは、 heap[k] と heap[parent(k)] です。 関数 swap の引数には、交換する要素の添字を指定するので、<span class="blank">b</span>は parent(k) であり、選択肢エが正解です。</p>
<p>&nbsp;</p>
<p>いかがでしょうか？</p>
<p>ヒープのデータ構造と、ヒープの作成方法を知っていれば、とっても簡単な穴埋め問題だったはずです。 繰り返しアドバイスしますが、もしもシラバスの中に知らないアルゴリズムやデータ構造があったなら、教材で学習してください。</p>
<p>シラバスに示されていることは「知っているよね！」というノリで出題されるからです。</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a &#8211; イ, b &#8211; エ</p>
<div class="divider mag_tp50 mag_bt30"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。 アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/heap/">ヒープを配列で実現するプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>ルールに従って検査文字（チェックディジット）を求めるプログラム｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/check_digit/</link>
		<pubDate>Fri, 12 Jun 2020 06:14:10 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4189</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/check_digit/">ルールに従って検査文字（チェックディジット）を求めるプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、実際の試験問題の一部をアレンジした練習問題を作りました。とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,article pre{font-family:consolas,'Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important}pre{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;margin:1em -7.5%;padding:1em 7.5%}.card-panel>pre{margin:1em -24px;padding:1em 24px}table{font-size:.85em;}dl.background dt{font-weight:700;margin:1em auto}.img-margin-height{margin:1em auto}table.border-right td,table.border-right th{border-right:1px solid #d0d0d0}@media only screen and (max-width:600px){dl dd,dl.background dd{margin-left:0}}blockquote p{color:#9e9e9e!important}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 8  (平成 29 年度 春期 午後）を一部改変</p>
<p>　関数 calcCheckCharacter は、引数 input[] で指定された文字列の誤りを検出するための検査文字を返す。文字列は、以下に示した N 種類 (ここでは N = 30 ）の文字から構成され、それぞれに数値が割り当てられている。空白文字は &#8220;△&#8221; と表記する。文字列の長さは、引数 len( 1 以上とする）で指定される。</p>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>表やプログラムは横スクロールできます</p>
<div class="table-container mag_h30">
<table class="bordered centered border-right responsive-width">
<tr>
<th>文字</th>
<td>△</td>
<td>.</td>
<td>,</td>
<td>?</td>
<td>a</td>
<td>b</td>
<td>c</td>
<td>d</td>
<td>e</td>
<td>f</td>
<td>g</td>
<td>h</td>
<td>i</td>
<td>j</td>
<td>k</td>
</tr>
<tr>
<th>数値</th>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
<td>13</td>
<td>14</td>
</tr>
<tr>
<th>文字</th>
<td>l</td>
<td>m</td>
<td>n</td>
<td>o</td>
<td>p</td>
<td>q</td>
<td>r</td>
<td>s</td>
<td>t</td>
<td>u</td>
<td>v</td>
<td>w</td>
<td>x</td>
<td>y</td>
<td>z</td>
</tr>
<tr>
<th>数値</th>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
<td>1</td>
<td> 20</td>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
<td>26</td>
<td>27</td>
<td>28</td>
<td>29</td>
</tr>
</table>
</div>
<dl class="mag_h30">
<dt>［検査文字の生成の手順］</dt>
<dd><i class="material-icons">looks_one</i> 文字列の末尾の文字を 1 番目の文字とし、文字列の先頭に向かって奇数番目の文字に割り当てた数値を 2 倍して N で割り、商と余りの和を求め、全て足し合わせる。</dd>
<dd><i class="material-icons">looks_two</i> 偶数番目の文字に割り当てた数値は、そのまま全て足し合わせる。</dd>
<dd><i class="material-icons">looks_3</i> <i class="material-icons">looks_one</i> と <i class="material-icons">looks_two</i> の結果を足し合わせる。</dd>
<dd><i class="material-icons">looks_4</i>  N から、 <i class="material-icons">looks_3</i> で求めた総和を N で割った余りを引く。さらにその結果を、 N で割り、余りを求める。求めた数値に対応する文字を検査文字とする。</dd>
<dt>［検査文字の生成例］</dt>
<dd>文字列 &#8220;ipa△△&#8221; に対し、生成される検査文字は &#8220;f&#8221; である。</dd>
</dl>
<p>　プログラム中の <span class="blank"></span> に入れる正しい答えを、解答群の中から選べ。ここで、 a1 と a2 に入れる答えは、 a に関する解答群の中から組合せとして正しいものを選ぶものとする。関数 caclCheckCharacter の中で使われている関数 getValue は、引数に与えられた文字に割り当てられた数値を返し、関数 getChar は、引数に与えられた数値に対応する文字を返す。配列の添字は、 1 から始まるとする。</p>
<p>［プログラム］</p>
<pre>
◯文字型: calcCheckCharacter(文字型の配列: input, 整数型: len)
  整数型: N, sum, i, value, check_value
  論理型: is_even

  N ← 30
  sum ← 0
  is_even ← <span class="blank">a1</span>

  for (i を len から 0 より大きい間 -1 ずつ減らす )
    value ← getValue(input[i])

    if ( is_even が <span class="blank">a2</span> と一致)
      sum ← sum + value
    else
      sum ← sum + (value × 2) ÷ N + (value × 2) mod N
    endif

    is_even ← not is_even
  endfor

  check_value ← <span class="blank">b</span>
  return getChar(check_value)
</pre>
<p>a に関する解答群</p>
<table class="bordered centered responsive-width">
<thead>
<tr>
<th>　</th>
<th>a1</th>
<th>a2</th>
</tr>
<tbody>
<tr>
<td>ア</td>
<td>false</td>
<td>false</td>
</tr>
<tr>
<td>イ</td>
<td>false</td>
<td>true</td>
</tr>
<tr>
<td>ウ</td>
<td>true</td>
<td>false</td>
</tr>
<tr>
<td>エ</td>
<td>true</td>
<td>true</td>
</tr>
</table>
<p>b に関する解答群</p>
<pre>
ア　N - sum mod N
イ　sum mod N
ウ　( N - sum mod N ) mod N
エ　( sum - N ) mod N
</pre>
</div>
<h2>ポイント1: 問題に示された具体例で自分の解釈が正しいことを確認する</h2>
<p>この問題を解くには「検査文字の生成の手順」を正しく解釈できなければなりません。もしも「自分の解釈が正しいのだろうか？」と心配になったら、問題に「検査文字の生成例」が示されているので、それを使って確認してください。</p>
<p>この例では、文字列 &#8220;ipa△△&#8221; に対し、生成される検査文字は &#8220;f&#8221; です。自分の解釈で検査文字を求めて、例と同じ結果が得られれば OK です。筆者は、以下のように解釈しました。</p>
<dl class="mag_tp30 background c-round">
<dt class="chip">手順<i class="material-icons">looks_one</i></dt>
<dd>文字列の末尾の文字を 1 番目の文字とし、文字列の先頭に向かって奇数番目の文字に割り当てた数値を 2 倍して N で割り、商と余りの和を求め、全て足し合わせる。</dd>
<dt class="chip">解釈</dt>
<dd>末尾を 1 番目として &#8220;ipa△△&#8221; の奇数番目の文字は、 &#8220;△&#8221; , &#8220;a&#8221; , &#8220;i&#8221; です。これらに割り当てた数値は、0, 4, 12 です。これらを 2 倍すると、0, 8, 24 です。 N = 30 で割った商と余りは、 0 と 0 、 0 と 8 、0 と 24 です。商と余りの和は、 0, 8, 24 です。全て足し合わせると、32 です。</dd>
</dl>
<dl class="background c-round">
<dt class="chip">手順<i class="material-icons">looks_two</i></dt>
<dd>偶数番目の文字に割り当てた数値は、そのまま全て足し合わせる。</dd>
<dt class="chip">解釈</dt>
<dd>&#8220;ipa△△&#8221; の奇数番目の文字は、 &#8220;△&#8221; , &#8220;p&#8221; です。これらに割り当てた数値は、 0, 19 です。そのまま足し合わせると、 19 です。</dd>
</dl>
<dl class="background c-round">
<dt class="chip">手順<i class="material-icons">looks_3</i></dt>
<dd><i class="material-icons">looks_one</i> と<i class="material-icons">looks_two</i> の結果を足し合わせる。</dd>
<dt class="chip">解釈</dt>
<dd><i class="material-icons">looks_one</i> の 32 と <i class="material-icons">looks_two</i> の 19 を足し合わせると、51 です。</dd>
</dl>
<dl class="background mag_bt30 c-round">
<dt class="chip">手順<i class="material-icons">looks_4</i></dt>
<dd>N から、<i class="material-icons">looks_3</i> で求めた総和を N で割った余りを引く。さらにその結果を、 N で割り、余りを求める。求めた数値に対応する文字を検査文字とする。</dd>
<dt class="chip">解釈</dt>
<dd>N = 30 から、<i class="material-icons">looks_3</i> で求めた 51 を N = 30 で割った余りの 21 を引くと、 9 です。さらに 9 を N = 30 で割った余りを求めると、9 です。 9 に対応する検査文字は、 &#8220;f&#8221; です。</dd>
</dl>
<p>例に示された &#8220;f&#8221; と同じ &#8220;f&#8221; という結果が得られたので、筆者の解釈は正しいようです。</p>
<p>もしも、同じ結果が得られなかった場合は、どこかに解釈の間違いがあるので、手順をよく見直してください。「あっ！ そういう意味だったのか」と気付くはずです。</p>
<h2>ポイント2: 変数名をヒントにして変数の役割を見出す</h2>
<p><span class="blank">a1</span>と<span class="blank">a2</span>は、変数 is_even への代入と比較です。<br />
<span class="blank">b</span>は、変数 check_value への代入です。</p>
<p>これらの穴埋めをするには、変数の役割がわからなければなりません。</p>
<p>これらの変数の役割は、問題文に示されていませんが、変数名をヒントにすればわかるでしょう。</p>
<p>&nbsp;</p>
<p>is_even の、 <span class="bold">even は偶数</span>という意味です。<br />
is は「 is this a pen ? (これはペンですか？) 」という<span class="bold">疑問文の is であり、「～ですか？」という意味</span>です。</p>
<p>つまり、is_even は「偶数ですか？」を意味する変数であり、論理型で定義されているので、値が true なら偶数であり、 false なら奇数です。</p>
<p>&nbsp;</p>
<p>「 even が偶数なんて知らない！」という人は、<span class="u">プログラムに登場する変数名や関数名で使われる英単語の意味を覚える習慣を持ってください。</span></p>
<p>筆者は、英語が得意なわけではありません。英検が 3 級で、 TOEIC が 400 点台という、英語のできない典型的な日本人です。そうであっても、プログラムに登場する変数名や関数名で使われる英単語は、意味を覚えるようにしています。</p>
<p>even が「偶数」で、 <span class="bold">odd が「奇数」</span> であることは、かつて何らかのプログラムで見たときに覚えました。</p>
<p>プログラムには、難しい英単語は登場しません。もしも、変数名や関数名にわからない英単語が登場したら、面倒くさがらずに意味を調べてください。</p>
<p>&nbsp;</p>
<p>check_value の意味は、調べなくてもわかるでしょう。</p>
<p>check は「検査」で、 value は「値」です。 calcCheckCharacter 関数は、戻り値として検査文字を返すので、プログラムの最後の処理が、 </p>
<pre>return getChar(check_value)</pre>
<p>になっています。</p>
<p>「検査値」の check_value を、 getChar 関数で文字 (検査文字) に変換して返すのです。</p>
<h2>ポイント3: 問題に示された手順とプログラムを対応付ける</h2>
<p>この問題のように、手順が丁寧に示されている場合には、それぞれの手順とプログラムを対応付けると「この穴埋めで行う処理はこれだ！」とわかることがよくあります。</p>
<div class="background c-round">
<span class="blank">a1</span>は、変数 is_even に代入する初期値です。</p>
<blockquote><p>「 <i class="material-icons">looks_one</i> 文字列の末尾の文字を 1 番目の文字とし、文字列の先頭に向かって」</p></blockquote>
<p>とあるので、最初に処理する末尾の文字は 1 番目であり奇数です。したがって、変数 is_even (偶数ですか？) の初期値は、 false だとわかります。
</p></div>
<div class="background c-round">
変数 is_even が<span class="blank">a2</span>と等しいときに、sum ← sum + value という処理を行います。これは、</p>
<blockquote><p>「 <i class="material-icons">looks_two</i> 偶数番目の文字に割り当てた数値は、そのまま全て足し合わせる」</p></blockquote>
<p>に該当するので、変数 is_even (偶数ですか？) が true と等しいだとわかります。
</p></div>
<p><span class="blank">a1</span>が false で、<span class="blank">a2</span>が true なので、 a の正解はイです。</p>
<p>&nbsp;</p>
<div class="background c-round">
<span class="blank">b</span>は、最終的に得られる検査値を変数 check_value に代入しています。</p>
<p>その前までの処理で、変数 sum ( 変数名から「和」を意味することがわかります ) の値を集計しているので、ここでは</p>
<blockquote><p>「 <i class="material-icons">looks_4</i> N から、<i class="material-icons">looks_3</i> で求めた総和を N で割った余りを引く。さらにその結果を、N で割り、余りを求める」</p></blockquote>
<p>を行えばよいことがわかります。
</p></div>
<div class="background c-round">
<span class="blank">b</span>の選択肢を見てみましょう。</p>
<blockquote><p>
b に関する解答群</p>
<pre class="mag_w00">
ア　N - sum mod N
イ　sum mod N
ウ　( N - sum mod N ) mod N
エ　( sum - N ) mod N
</pre>
</blockquote>
<p>この手順に該当するのは、</p>
<blockquote><p>「 N から、<i class="material-icons">looks_3</i> で求めた総和を N で割った余りを引く」</p></blockquote>
<p>が</p>
<blockquote><p>「 N &#8211; sum mod  N」</p></blockquote>
<p>であり、</p>
<blockquote><p>「さらにその結果を、 N で割り、余りを求める」</p></blockquote>
<p>が</p>
<blockquote><p>「 ( N &#8211; sum mod N ) mod N 」</p></blockquote>
<p>なので、選択肢ウです。
</p></div>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － イ, b － ウ</p>
<div class="divider mag_tp50 mag_bt30"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/check_digit/">ルールに従って検査文字（チェックディジット）を求めるプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>配列のマッチング（突合せ）を行うプログラム｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/array_match/</link>
		<pubDate>Mon, 08 Jun 2020 08:04:09 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[科目 B]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4161</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/array_match/">配列のマッチング（突合せ）を行うプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、旧制度の午後試験のアルゴリズム過去問題の一部をアレンジした練習問題を作りました。 とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,article pre,code{font-family:consolas,'Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important}pre,code{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;}pre{margin:1em -7.5%!important;padding:1em 7.5%!important}.img-margin-height,dt{margin:1em auto}.card-panel>pre{margin:1em -24px!important;padding:1em 24px!important}dt{font-weight:700}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 8  (平成 25 年度 春期 午後）を一部改変</p>
<p class="pad_10 grey lighten-5 blue-text c-round">この問題では、配列名や変数名が日本語なので、わかりやすいように青色文字で示しています</p>
<p>　以下は、購入した商品の中から、値引きの対象となる商品を見つけて、その数量を求めるプログラムである。 購入した商品は、 <span class="blue-text">購入[ ]</span> という構造型（<span class="blue-text">品番</span>、<span class="blue-text">品名</span>、<span class="blue-text">数量</span>から構成されたデータ型）の配列に格納され、要素数は <span class="blue-text">購入行数</span> に格納されている。 値引きの対象となる商品は、 <span class="blue-text">対象[ ]</span> という構造型（<span class="blue-text">品番</span>、<span class="blue-text">数量</span>から構成されたデータ型）の配列に格納され、要素数は <span class="blue-text">対象行数</span> に格納されている。 ぞれぞれの配列は、 <span class="blue-text">品番</span> の昇順に整列されていて、 <span class="blue-text">品番</span> が一致した場合は、 <span class="blue-text">購入[ ]</span> の <span class="blue-text">数量</span> を、 <span class="blue-text">対象[ ]</span> の <span class="blue-text">数量</span> に格納する。  <span class="blue-text">購入[ ] </span> 、 <span class="blue-text">購入行数</span> 、 <span class="blue-text">対象[ ]</span> 、 <span class="blue-text">対象行数</span> は、以下に示したプログラムとは別の場所で宣言された大域的変数である。  <span class="blue-text">購入[ ]</span> と <span class="blue-text">対象[ ]</span> の添字は、 1 から始まる。 プログラム中の <span class="blank">a</span> <span class="blank">b</span> に入る正しい答えを、解答群の中から選べ。</p>
<figure><figcaption>［格納されたデータの例］</figcaption><img class="materialboxed hoverable responsive-width" src="../../wp-content/uploads/2020/06/q8_table_1-1.jpg" loading="lazy"><br />
<img class="materialboxed hoverable" style="margin:auto;" src="../../wp-content/uploads/2020/06/q8_table_2-2.jpg" loading="lazy"><br />
</figure>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>プログラムは横スクロールできます</p>
<p>［プログラム］</p>
<pre>整数型: K, T
K ← 1
T ← 1

while (k が購入行数以下でかつ T が対象行数以下)
  if (購入[K].品番と対象[T].品番が等しい)
    対象[T].数量 ← 購入[K].数量
    <span class="blank">a</span>
    <span class="blank">b</span>
  elseif (購入[K].品番が対象[T].品番より小さい)
    <span class="blank">a</span>
  else
    <span class="blank">b</span>
  endif
endwhile</pre>
<p>a と b の解答群</p>
<pre>
ア　K ← K + 1
イ　K ← 購入[K].品番 + 1
ウ　T ← T + 1
エ　T ← 対象[T].品番 + 1
</pre>
</div>
<h2>ポイント1: 構造型とは何かを知っておこう</h2>
<p>この問題には、科目 B サンプル問題に掲載された「共通に使用される擬似言語の記述形式」に説明がない「構造型（構造体、レコード型、ユーザー定義型とも呼ばれます）」が登場します。</p>
<p>擬似言語は、 C 言語によく似ていて、 C 言語には構造型があるので、「わかるよね！」というノリで出題されているのです。 しかし、 C 言語の経験がないなら「わかりません！」だと思いますので、この機会に構造型とは何かを知っておきましょう。</p>
<p>構造型は、複数のデータをまとめたデータ型です。  C 言語では、 <code class="language-clike">struct</code> というキーワードで構造型を定義します。 この問題に示された構造型を C 言語風に定義すると、以下のようになります。</p>
<pre>
<code class="language-clike">struct 購入構造型 {
  文字列型 品番;
  文字列型 品名;
  整数型 数量;
};

struct 対象構造型 {
  文字列型 品番;
  整数型 数量;
};</code>
</pre>
<p>構造型は、ユーザーが独自に定義したデータ型であり、変数や配列のデータ型として使います。</p>
<p>ここでは、構造型の名前を、購入構造型と対象構造型にしています。 構造体にまとめられた個々のデータを<span class="bold">メンバ</span>と呼びます。 購入構造体のメンバは、品番、品名、数量です。 対象構造体のメンバは、品番、数量です。</p>
<p>&nbsp;</p>
<p>この問題では、購入[ ] および 対象[ ] という配列のデータ型が、購入構造型および対象構造型になっています。 構造型の配列の個々の要素には、構造体のメンバ一式が入っています。</p>
<p>構造体の配列の個々の要素で、メンバを指定するときは、</p>
<pre><code class="language-clike">配列名[添字].メンバ名</code></pre>
<p>という表記を使います。 このドット（ <code class="language-clike">.</code> ）を「～の」と読むとわかりやすいでしょう。</p>
<p>たとえば <code class="language-clike">購入[1].品番</code> なら、「 購入[1] の品番」と読みます。 以下に例を示します。</p>
<figure>
<img class="materialboxed hoverable responsive-width" src="../../wp-content/uploads/2020/06/q8_struct_1.jpg" loading="lazy"><br />
</figure>
<p>構造体とは何かがわかったら、問題に示されたプログラムを見てみましょう（以下に示します）。</p>
<pre>購入[K].品番と対象[T].品番が等しい</pre>
<p> は、「購入[K] の品番と対象[T] の品番が一致する」という意味です。</p>
<pre>対象[T].数量 ← 購入[K].数量</pre>
<p>は、「対象[T] の数量に、購入[K] の数量を格納する」という意味です。</p>
<pre>購入[K].品番が対象[T].品番より小さい</pre>
<p>は、「購入[K] の品番が、対象[T] の品番より小さい」という意味です。</p>
<pre>
整数型: K, T
K ← 1
T ← 1

while (k が購入行数以下でかつ T が対象行数以下)
  <span class="amber-text">if (購入[K].品番と対象[T].品番が等しい)</span>
    <span class="amber-text">対象[T].数量 ← 購入[K].数量</span>
    <span class="blank">a</span>
    <span class="blank">b</span>
  <span class="amber-text">elseif (購入[K].品番が対象[T].品番より小さい)</span>
    <span class="blank">a</span>
  else
    <span class="blank">b</span>
  endif
endwhile
</pre>
<h2>ポイント2: 突合せのやり方を知っておこう</h2>
<p>この問題のテーマは、旧午後試験のソフトウェア設計の分野でよく出題された <span class="bold">突合せ</span> です。</p>
<p>突合せとは、「整列済みの 2 つのファイルの先頭から 1 件ずつデータを読み出し、一致したら特定の処理を行って両方を読み進め、不一致ならその先で一致する可能性がある方だけを読み進める」という処理です。</p>
<p>この問題では、 2 つのファイルではなく、 2 つの配列で突合せを行っていますが、やり方は同様です。 もしも、「ソフトウェア設計の突合せの問題をやったことがありません！」なら、この機会に突合せのやり方を知っておきましょう。</p>
<p>以下に、問題に示された 2 つの配列で突合せを行う手順を示します。</p>
<dl class="background c-round">
<dt>【手順 1 】</dt>
<dd><img class="materialboxed hoverable img-margin-height" src="../../wp-content/uploads/2020/06/q8_order_1.jpg" loading="lazy"></dd>
<dd>それぞれの先頭の要素を読み出して、品番を比べます。 <br />購入[1].品番 &lt; 対象[1].品番 なので、 購入[ ] だけを先に読み進めます。 <br />なぜなら、それぞれの配列は、品番の昇順に整列されているので、購入[ ]だけを先に読み進めれば、対象[ ]と品番が一致する要素が見つかる可能性があるからです。 </dd>
<dt>【手順 2 】</dt>
<dd><img class="materialboxed hoverable img-margin-height" src="../../wp-content/uploads/2020/06/q8_order_2.jpg" loading="lazy"></dd>
<dd>購入[2].品番 = 対象[1].品番 なので、 対象[1].数量 に 購入[2].数量 を格納して、 購入[ ] と 対象[ ] の両方を先に読み進めます。 <br />一致したら両方を読み進め、不一致なら一方だけを読み進めるのが、突合せのポイントです。 </dd>
<dt>【手順 3 】</dt>
<dd><img class="materialboxed hoverable img-margin-height" src="../../wp-content/uploads/2020/06/q8_order_3.jpg" loading="lazy"></dd>
<dd>購入[3].品番 > 対象[2].品番 なので、対象[ ] だけを先に読み進めます。 </dd>
<dt>【手順 4 】</dt>
<dd><img class="materialboxed hoverable img-margin-height" src="../../wp-content/uploads/2020/06/q8_order_4.jpg" loading="lazy"></dd>
<dd>購入[3].品番 = 対象[3].品番 なので、 対象[3].数量 に 購入[3].数量 を格納して、 購入[ ] と 対象[ ] の両方を先に読み進めます。 </dd>
<dt>【手順5】</dt>
<dd>この時点で、 対象[ ] が末尾を超えたので、突合せを終了します。 <br />突合せを繰り返す条件は、 「 購入[ ] が末尾を超えていない、かつ、 対象[ ] が末尾を超えていない」です。 </dd>
</dl>
<p>突合せのやり方がわかったら、問題の穴埋めができるでしょう。 以下に、もう一度、プログラムと解答群を示します。</p>
<pre>整数型: K, T
K ← 1
T ← 1

while (k が購入行数以下でかつ T が対象行数以下)
  if (購入[K].品番と対象[T].品番が等しい)
    対象[T].数量 ← 購入[K].数量
    <span class="blank">a</span>
    <span class="blank">b</span>
  elseif (購入[K].品番が対象[T].品番より小さい)
    <span class="blank">a</span>
  else
    <span class="blank">b</span>
  endif
endwhile</pre>
<p>a と b の解答群</p>
<pre>
ア　K ← K + 1
イ　K ← 購入[K].品番 + 1
ウ　T ← T + 1
エ　T ← 対象[T].品番 + 1
</pre>
<p><span class="blank">a</span> <span class="blank">b</span>は、 2 か所ずつあります。 上側にある </p>
<pre>購入[K].品番と対象[T].品番が等しい</pre>
<p>という条件で、 <span class="blank">a</span> と <span class="blank">b</span> の両方を行っています。 これは、どちらか一方が 購入[ ] を読み進める処理で、もう一方が 対象[ ] を読み進める処理です。</p>
<p>ここでは、どちらがどちらなのかを判断できません。</p>
<p>&nbsp;</p>
<p>下側にある </p>
<pre>購入[K].品番が対象[T].品番より小さい</pre>
<p>という条件で、 <span class="blank">a</span> を行っています。 これは、購入[ ] を読み進める処理です。</p>
<p>購入[ ] の添字は、 K で示されているので、選択肢の中では、 K の値を 1 つ増やす <code>K ← K + 1</code> （選択肢ア）が適切です。</p>
<p><span class="blank">a</span> が 購入[ ] を読み進める処理だとわかったので、 <span class="blank">b</span> は、対象[ ] を読み進める処理であることがわかります。</p>
<p>対象[ ] の添字は、 T で示されているので、選択肢の中では、 T の値を 1 つ増やす <code>T ← T + 1</code> （選択肢ウ）が適切です。</p>
<h2>ポイント3: 難しそうな選択肢を選ばない</h2>
<p>多くの受験者が、「旧午後試験では時間が足りない！」と言っていました。 科目 B 試験で出題数が変わったとは言え、 1 問平均 5 分で 16 問解答する必要があるため、この傾向は変わらないと予想されます。</p>
<p>そのため、「当てずっぽう」で選択肢を選ぶこともあるでしょう。 これは、仕方がないことだと思いますが、<span class="bold">「選択肢の内容が他より難しそうだから」という理由で選ばないでください。 </span></p>
<p>なぜなら、難しそうな選択肢は、間違いである場合が多いからです。 ここで、もう一度、今回の問題の選択肢を見てみましょう。</p>
<p>a と b の解答群</p>
<pre>
ア　K ← K + 1
イ　K ← 購入[K].品番 + 1
ウ　T ← T + 1
エ　T ← 対象[T].品番 + 1
</pre>
<p>選択肢アとイは K に代入を行い、ウとエは T に代入を行っています。 アとウより、イとエの方が難しそうなことをしているので、「難しそうな方が正解かな？」と思うかもしれませんが、実際の正解はアとウです。</p>
<p>これは、「簡単そうな方を選べ」ということではありません。 「当てずっぽう」で選択肢を選ぶときには、「選択肢の内容を気にしないで選べ」ということです。</p>
<p>ただし、すべての選択肢から当てずっぽうに選ぶのではなく、<span class="u">「これは絶対に正解ではない」という選択肢を消して、残ったものの中から選んでください。 </span>そうすれば、当てずっぽうが当たる確率が上がり、残った選択肢を見て「あっ、そうか！」と正解に気付くこともあります。</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － ア, b － ウ</p>
<div class="divider mag_mag_tp50 mag_bt30"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。 アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/array_match/">配列のマッチング（突合せ）を行うプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
		<item>
		<title>2進数の知識が必要なプログラム｜アルゴリズムとプログラミング問題を解くコツ</title>
		<link>https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/if_else/</link>
		<pubDate>Mon, 25 May 2020 06:27:15 +0000</pubDate>
		<dc:creator><![CDATA[矢沢 久雄]]></dc:creator>
				<category><![CDATA[2進数]]></category>
		<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[科目 B]]></category>
		<category><![CDATA[論理回路]]></category>

		<guid isPermaLink="false">https://www.seplus.jp/dokushuzemi/fe/fenavi/?post_type=patterns_algorithms&#038;p=4092</guid>
		<description><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。 苦手を克服するには [&#8230;]</p>
<p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/if_else/">2進数の知識が必要なプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></description>
				<content:encoded><![CDATA[<p>この連載では、基本情報技術者試験で、多くの受験者が苦手意識を持っている科目 B 試験 アルゴリズムとプログラミング分野の「アルゴリズム穴埋め問題」に的を絞って、正解を見出すポイントを詳しく説明します。</p>
<p>苦手を克服するには、短いプログラムを何度も練習して、穴埋めに慣れることが重要です。</p>
<p>そのために、旧制度の午後試験のアルゴリズム過去問題の一部をアレンジした練習問題を作りました。 とても短い問題ですので、気軽に取り組んでください。</p>
<style>article,article pre{font-family:'consolas','Courier New',"HCo Gotham SSm",Gotham,"ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic ProN","Hiragino Sans","BIZ UDPGothic",Meiryo,sans-serif!important;}pre{background:#263238;color:#eceff1;font-size:1em;line-height:1.8;margin:1em -7.5%;padding:1em 7.5%}table{font-size:.85em;}.card-panel>pre{margin:1em -24px}.background p{color:#3f51b5}ul.options>li{list-style-type:none!important;counter-increment:kana;}ul.options>li::before{content:counter(kana, katakana);margin-right:1em;}dl.inline dd{margin-left:6em}@media only screen and (max-width:600px){.col.m6.on-mobile-float-none{float:none}}.table-container table{line-height:.5}ul.checkbox li{list-style-type:unset}ul.checkbox li::before{font-family:'Material Icons';content:"\e835";margin-right:.5em}</style>
<h2>練習問題</h2>
<div class="card-panel">
問 8  (平成 24 年度 春期 午後）を一部改変</p>
<p>関数 BitTest は、 8 ビットのデータ中の指定したビット位置の値を検査し、その結果を返す。 検査される 8 ビットのデータは引数 Data に、検査するビット位置は引数 Mask に、それぞれ格納される。 Mask 中のビットの値が 1 であるビット位置に対応した Data 中のビットを検査し、返却値として、検査した全てのビットが 0 なら 0 を、検査したビット中に 0 と 1 が混在しているなら 1 を、検査した全てのビットが 1 なら 2 を、それぞれ返す。</p>
<p class="grey-text hide-on-med-and-up mag_h10 small-text"><i class="material-icons light-blue-text mag_rt05">swipe</i>アルゴリズムや表は横スクロールできます</p>
<div class="row">
<div class="col m6 on-mobile-float-none grey lighten-5 c-round table-container">
    <span class="chip">例 1</span></p>
<table>
<tr>
<td>ビット番号</td>
<td> 7 6 5 4 3 2 1 0</td>
</tr>
<tr>
<td>Data</td>
<td> 0 1 0 1 0 1 0 1</td>
</tr>
<tr>
<td>Mask</td>
<td> 1 1 1 0 0 0 0 0</td>
</tr>
<tr>
<td>返却値</td>
<td> 1</td>
</tr>
</table></div>
<div class="col m6 on-mobile-float-none grey lighten-5 c-round table-container">
    <span class="chip">例 2</span></p>
<table>
<tr>
<td>ビット番号</td>
<td> 7 6 5 4 3 2 1 0</td>
</tr>
<tr>
<td>Data</td>
<td> 0 0 1 1 0 0 1 1</td>
</tr>
<tr>
<td>Mask</td>
<td> 0 0 0 1 0 0 0 1</td>
</tr>
<tr>
<td>返却値</td>
<td> 2</td>
</tr>
</table></div>
</div>
<p>プログラム中の<span class="blank">a</span><span class="blank">b</span>に入る正しい答えを、解答群の中から選べ。 なお、本問において、演算子 <code class="language-none">"&"</code> 、 <code class="language-none">"|"</code> は、AND および OR のビット演算を求めるもとのし、 <code class="language-none">"～"B</code> という表記は、 8 ビット論理型定数（ 8 ビットの 2 進数）を表す。 Mask 中には、 1 のビットが 1 個以上あるものとする。</p>
<p>［プログラム］</p>
<pre>◯整数型: BitTest( 8 ビット論理型: Data, 8 ビット論理型: Mask)
  整数型: RC		/* 返却値 */

  if ( <span class="blank">a</span> )
    RC ← 2		/* 返却値は 2 */
  elseif ( <span class="blank">b</span> )
    RC ← 0		/* 返却値は 0 */
  else
    RC ← 1		/* 返却値は 1 */
  endif

  return RC		/* RC を返却値として返す */</pre>
<p>a と b の解答群</p>
<ul class="options">
<li>Data と Mask の値がどちらも &#8220;00000000&#8221;B</li>
<li>Data と Mask の値がどちらも Data</li>
<li>Data と Mask の値がどちらも Mask</li>
<li>Data と Mask の値がどちらか &#8220;00000000&#8221;B</li>
<li>Data と Mask の値がどちらか Mask</li>
</ul>
</div>
<h2>ポイント1: 問題に示された具体例から問題の意味を理解する</h2>
<p>この問題は、問題文の説明を読んだだけでは、何をするプログラムかよくわからないでしょう。 どうやら出題者も、そう思ったようで、具体例を 2 つ示しています。</p>
<p>このような場合には、具体例を見れば、問題の意味を理解できるようになっているはずです。</p>
<div class="row mag_h30" style="position: relative;">
<span class="chip">例 1</span></p>
<dl class="inline">
<dt>ビット番号</dt>
<dd> 7 6 5 4 3 2 1 0</dd>
<dt>Data</dt>
<dd><span style="border: .1em dashed blue"> 0 1 0 </span>1 0 1 0 1</dd>
<dt>Mask</dt>
<dd><span style="border: .1em dashed red"> 1 1 1 </span>0 0 0 0 0</dd>
<dt>返却値</dt>
<dd> 1</dd>
</dl>
<div class="pad_10 z-depth-1 blue-text blank" style="font-size: .9em; position: absolute; top: 3.5em; left: 10em;background:#ffffffc4;">0 と 1 が混在</div>
<div class="pad_10 z-depth-1 red-text blank" style="font-size: .9em; position: absolute; bottom: .5em; left: 10em;background:#ffffffc4;border:#F44336 solid .2em">検査位置</div>
</div>
<div class="background c-round">
例 1 では 11100000 という Mask の 1 の位置（ビット番号 7 、 6 、 5 ）が検査位置です。<br />
Data では、この検査位置が 0 、 1 、 0 なので、 0 と 1 が混在しています。<br />
したがって、返却値は 1 になります。</p>
<p>つまり、 Mask 中で 1 になっている部分で検査位置を指定し、 Data 中でその位置が 0 だけなのか、 0 と 1 が混在しているのか、 1 だけなのかを返却値 0 、 1 、 2 で知らせるプログラムなのです。
</p></div>
<p>もうひとつ例があるので、この解釈が合っているかどうかを確認しておきましょう。</p>
<div class="row mag_h30" style="position: relative;">
<span class="chip">例 2</span></p>
<dl class="inline">
<dt>ビット番号</dt>
<dd> 7 6 5 4 3 2 1 0</dd>
<dt>Data</dt>
<dd> 0 0 1<span style="border: .1em dashed blue"> 1 </span>0 0 1<span style="border: .1em dashed blue"> 1 </span></dd>
<dt>Mask</dt>
<dd> 0 0 0<span style="border: .1em dashed red"> 1 </span>0 0 0<span style="border: .1em dashed red"> 1 </span></dd>
<dt>返却値</dt>
<dd> 2</dd>
</dl>
<div class="pad_10 z-depth-1 blue-text blank" style="font-size: .9em; position: absolute; top: 2.5em; left: 10.5em;background:#ffffffc4;">すべて 1</div>
<div class="pad_10 z-depth-1 red-text blank" style="font-size: .9em; position: absolute; bottom: 0em; left: 10.5em;background:#ffffffc4;border:#F44336 solid .2em">検査位置</div>
</div>
<div class="background c-round">
例 2 では 00010001 という Mask の 1 の位置（ビット番号 4 、 0 ）が検査位置です。<br />
Data では、この検査位置が 1 、 1 なので、全てが 1 です。<br />
したがって、返却値は 2 になります。
</div>
<p>これで、解釈が合っていることを確認できました。</p>
<h2>ポイント2: 事前に 2 進数の知識を習得しておく</h2>
<p>それほど頻度は多くないのですが、基本情報技術者試験の旧午後試験のアルゴリズム問題では、 2 進数の知識が必要なプログラムが出ることがありました。</p>
<p>以下の知識をきちんと習得できているかどうか確認してください。 ここでは、それぞれの知識を詳しく説明しませんが、もしも習得できていないことがあれば、お手元の教材（きっと何らかの教材をお持ちでしょう！）で学習してください。</p>
<p>今回の練習問題では、ビット演算の知識が必要です。</p>
<ul class="checkbox background">
<li>2 進数を 10 進数に変換する</li>
<li>10 進数を 2 進数に変換する</li>
<li>2 進数を 16 進数に変換する</li>
<li>16 進数を 2 進数に変換する</li>
<li>2 の補数表現でマイナスの数を表す</li>
<li>論理シフトと算術シフトの違いがわかる</li>
<li>AND 、OR 、XOR のビット演算（ビットごとの論理演算）ができる</li>
</ul>
<h2>ポイント3: コメントをヒントにする</h2>
<p>実務で作成されるプログラムでは、プログラムの保守性を高めるために、数多くのコメントが入れてあります。 <span class="u">コメントを読めば、誰でもプログラムの内容を理解できるようにしているのです。 </span></p>
<p>ただし、もしも試験問題のプログラムに数多くのコメントを入れたら、問題がやさしくなり過ぎてしまいます。<br />
とはいえ、まったくコメントを入れなければ、制限時間内に問題を解けなくなってしまうでしょう。</p>
<p>&nbsp;</p>
<p>そこで、試験問題のプログラムには、少しだけコメントが入れてあります。</p>
<p>このコメントは、コメントというよりも<span class="bold">制限時間内に問題を解くためのヒント</span>です。 プログラムの中にコメントを見たら「ヒントだ！」と思って、大いに注目してください。</p>
<p>この問題でも、ヒントとしてコメントが入っています。 以下の <code class="language-none"> /* </code> と <code class="language-none"> */ </code> で囲まれた文字列がコメントです。</p>
<pre>◯整数型: BitTest( 8 ビット論理型: Data, 8 ビット論理型: Mask)
  整数型: RC		<span class="red-text bold">/* 返却値 */</span>

  if ( <span class="blank">a</span> )
    RC ← 2		<span class="red-text bold">/* 返却値は 2 */</span>
  elseif ( <span class="blank">b</span> )
    RC ← 0		<span class="red-text bold">/* 返却値は 0 */</span>
  else
    RC ← 1		<span class="red-text bold">/* 返却値は 1 */</span>
  endif</pre>
<p><span class="red-text bold">/* 返却値 */</span> というコメントから、 RC という変数が返却値を入れるものであることがわかります。</p>
<p><span class="red-text bold">/* 返却値は 2 */</span> というコメントから、<span class="blank">a</span>には返却値を 2 にする条件、つまり Mask で指定した Data のビット位置が全て 1 である条件が入ることがわかります。</p>
<p><span class="red-text bold">/* 返却値は 0 */</span> というコメントから、<span class="blank">b</span>には返却値を 0 にする条件、つまり Mask で指定した Data のビット位置が全て 0 である条件が入ることがわかります。</p>
<p>&nbsp;</p>
<p><span class="red-text bold">/* RC を返却値として返す */</span> というコメントから、 <code class="language-none"> return </code>という命令が、返却値を返すものであることがわかります。</p>
<p>C 言語、Java 、Python などのプログラミング言語の経験があれば、この return の意味がわかると思いますが、擬似言語仕様書には return が示されていません。 このプログラムでは、仕様書にない表現を使っているので、それをコメントで説明しているのです。 このようなコメントもよくあります。</p>
<h2>ポイント4: 選択肢の変数に具体的な数値を設定してみる</h2>
<p>それでは、プログラムの穴埋めをやってみましょう。</p>
<p>これまでの記事でも何度かポイントとして取り上げてきましたが、<span class="u">基本情報技術者試験の問題は、すべて選択問題なのですから、選択肢を見て答えを選んでください。 </span></p>
<p><span class="blank">a</span>には、 Mask で指定した Data のビット位置が全て 1 である条件が入ります。 これは、選択肢ア～オのどれでしょう。</p>
<blockquote>
<ul class="options blue-grey-text">
<li>Data と Mask の値がどちらも &#8220;00000000&#8221;B</li>
<li>Data と Mask の値がどちらも Data</li>
<li>Data と Mask の値がどちらも Mask</li>
<li>Data と Mask の値がどちらか &#8220;00000000&#8221;B</li>
<li>Data と Mask の値がどちらか Mask</li>
</ul>
</blockquote>
<p>もしも、「う～む？」と悩んでしまったら、選択肢の変数に具体的な数値を設定してみましょう。</p>
<p>「具体例！」そうです。 問題にも具体例が示されていました。 返却値が 2 になる具体例は、例 2 です。</p>
<blockquote class="row mag_h30">
<div class="col m6 on-mobile-float-none grey lighten-5 c-round table-container">
    <span class="chip">例 2</span></p>
<table class="blue-grey-text">
<tr>
<td>ビット番号</td>
<td> 7 6 5 4 3 2 1 0</td>
</tr>
<tr>
<td>Data</td>
<td> 0 0 1 1 0 0 1 1</td>
</tr>
<tr>
<td>Mask</td>
<td> 0 0 0 1 0 0 0 1</td>
</tr>
<tr>
<td>返却値</td>
<td> 2</td>
</tr>
</table></div>
</blockquote>
<p>それでは、例 2 の具体例を想定すると、どの選択肢が適切でしょう。</p>
<p>選択肢は、どれも左辺で Data と Mask の AND 演算（ &#038; ）か OR 演算（ | ）を行っています。</p>
<p>これも、「う～む？」と悩んでしまったら、実際に AND 演算と OR 演算をやってみればよいのです（ AND と OR のビット演算の知識が不安に感じた方は <a class="tag" href="../../tag/論理回路">論理回路</a> のタグがついた記事で練習してみましょう！ ）。</p>
<pre>
    0 0 1 1 0 0 1 1  Data
AND 0 0 0 1 0 0 0 1  Mask
--------------------
    0 0 0 1 0 0 0 1 演算結果・・・ Mask と同じ
</pre>
<pre>
    0 0 1 1 0 0 1 1  Data
OR  0 0 0 1 0 0 0 1  Mask
--------------------
    0 0 1 1 0 0 1 1 演算結果・・・ Data と同じ
</pre>
<p>以上のように、 AND 演算の結果は Mask と同じになります。 これは、選択肢ウです。 OR 演算の結果は Data と同じになります。 これは、選択肢にはありません。</p>
<p>したがって、選択肢にあるウが正解です。 できましたね！</p>
<p>&nbsp;</p>
<p><span class="blank">b</span>には、 Mask で指定した Data のビット位置が全て 0 である条件が入ります。</p>
<p>この具体例は、問題にありませんでしたが、例 1 と例 2 を参考にして、自分で作ってみましょう。</p>
<p>ここでは、 Data を 00110011 に、 Mask を 11001100 にしてみます。</p>
<pre>
    0 0 1 1 0 0 1 1  Data
AND 1 1 0 0 1 1 0 0  Mask
--------------------
    0 0 0 0 0 0 0 0 演算結果・・・ "00000000"B
</pre>
<pre>
    0 0 1 1 0 0 1 1  Data
OR  1 1 0 0 1 1 0 0  Mask
--------------------
    1 1 1 1 1 1 1 1 演算結果・・・ "11111111"B
</pre>
<p>以上のように、 AND 演算の結果は <code class="language-none">"00000000"B</code> になります。 これは、選択肢アです。</p>
<p>OR 演算の結果は <code class="language-none">"11111111"B</code> になります。 これは、選択肢にはありません。</p>
<p>したがって、選択肢にあるアが正解です。 できましたね！</p>
<p>&nbsp;</p>
<p><span class="chip mag_rt10">解答</span>a － ウ, b － ア</p>
<div class="divider mag_h50"></div>
<p><span class="bold">「習うより慣れろ」</span>ということわざがあります。 アルゴリズム穴埋め問題の克服に関しては、正にその通りでしょう。</p>
<p>この連載では、これからも短い練習問題を掲載していきますので、穴埋めに慣れることを目指してください。</p>
<p>正解を見出すポイントとして、同じことが示されることもあると思いますが、それは、多くの問題に共通したポイントがあるからです。</p>
<p>それでは、またお会いしましょう！</p><p>The post <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/patterns_algorithms/if_else/">2進数の知識が必要なプログラム｜アルゴリズムとプログラミング問題を解くコツ</a> first appeared on <a href="https://www.seplus.jp/dokushuzemi/ec/fe/fenavi">基本情報技術者試験 受験ナビ｜科目A・科目B対策から過去問解説まで 250本以上の記事を掲載</a>.</p>]]></content:encoded>
			</item>
	</channel>
</rss>
