ささきのブログ

日記、技術メモ、勉強記録など。

コラム3データで決まるプログラムの構造 【珠玉のプログラミング】

自分の回答を載せる。

1

似た処理の繰り返しなのでまとめられそう。
例えば以下のようなイメージ?もっと効率的な構造がありそうだけど思いつかない。

  int th[n] = {0, 2200, 2700, 3200, 3700, ..., 102200};

  std::map<int, int> offset;
  offset[0] = 0;
  offset[2200] = 0;
  offset[2700] = 70;
  ...

  std::map<int, double> rate;
  rate[0] = 0;
  rate[2200] = 0.15;
  ...
 
  int i  = 0;
  while(1) {
    if(income >= th[i]) i++;
    else break;
  }

  double tax = offset[th[i]] + rate[th[i]] * (income - th[i]);

2

実装イメージ。疑似コード。

a[k] = {...};
c[k+1] = {...};
for(i = 1; i <= m; i++) {
  a_n = 0;
  for(j = 1; j <= k; j++) {
    a_n += c[j] * a[i - j];
  }
  a_n += c[k + 1];
  printf(a_n);
}

ある特定の5次線形漸化式だけを解くなら、ベタ書きするだけなので頭は使わずに済むので簡単?

将来的に次数が変わる可能性が少しでもあるなら一般化したほうがいい。

3

問題の意味が分からない。

4

とばした。

5

ざっくりとした実装イメージ。
用意されたルールの各文字列を反転して配列に格納する。 与えられた単語も反転する。
ルールの配列から1つずつ文字列を取り出す。
与えられた単語と各文字列を1文字ずつ比較する。ただしハイフンは飛ばしてその位置を記録。 文字が不一致したら配列の次の要素へ移る。
ルールの文字列の最後の文字まで一致したら、その文字列が与えられた単語のルールとなる。 配列の最後の要素まで不一致したら適合なし。
最後に、記録したハイフンの回数と位置に基づいて与えられた単語にハイフンを挿入する。

6

3.2の定型文プログラムと同様のプログラムを作成する。 テストのために雛形通りのレコードと雛形と一致しないレコードを与える。

7

単語の正しいスペルと韻を示す辞書:
単語のスペルをキー、韻をバリューにした連想配列にする。

整数列の辞書:
フィボナッチ数列。予めサイズnを決めておき、n番目までの解を計算し配列に入れて返す。

化学構造の辞書:
名前をキー、組成式をバリューにした連想配列をつくる。

歌の韻律の辞書:
1次元配列で表現できそう。

8

7セグに表示したい数字をキー、点灯状態をbitで表現したときの10進数の値をバリューとした連想配列を作る。 question8.cpp参照。

感想

今回の章にあった、見習いたい心構え。

"優秀なプログラマは、コードを書く前に、そのプログラムの入力、出力、中間のデータ構造を徹底的に理解するものだということです。" p.38

ソースコード

//question8.cpp
#include <iostream>
#include <map>
#include <array>

class SevenSegmentDisplay {
public:
  SevenSegmentDisplay() {
    this->segdict[0] = 125;
    this->segdict[1] =  80;
    this->segdict[2] =  55;
    this->segdict[3] =  87;
    this->segdict[4] =  90;
    this->segdict[5] =  79;
    this->segdict[6] = 111;
    this->segdict[7] =  92;
    this->segdict[8] = 127;
    this->segdict[9] =  94;
  }

  ~SevenSegmentDisplay(){}

  std::vector<int> convert(const unsigned short num);

private:
  std::map<unsigned char, unsigned char> segdict;
};

std::vector<int> SevenSegmentDisplay::convert(const unsigned short num) {
  std::vector<int> segdata(5);

  int d = 10000; 
  int n = 0, a = 0, _a = 0;

  for(int i = 0; i < 5; i++) {
    a = a;
    a = num / d;
    n = a - _a * 10;
    segdata[i] = segdict[n];
    d = d / 10;
  }

  return segdata;
}

int main() {

  SevenSegmentDisplay sd;

  std::vector<int> a = sd.convert(12345);

  return 0;
}