Lecture 7 配列と文字列


【課題提出における注意】
  • すべてのプログラムは,必ずコンパイル&実行し,正しく機能することをチェックしてから提出すること.
  • プログラムは正しくインデントさせること.

Assingment(課題)7


    1. 英数字から成る文字列を入力すると, それぞれの文字コードが1ずつ大きい文字列に変換するプログラムを作りなさい. プログラム名を学籍番号10桁-07-1.cppとする.
      // 実行例
      文字列を入力 : abc123
      変換後の文字列: bcd234
      
      文字列を入力 : Meiji
      変換後の文字列: Nfjkj
      
      文字列を入力 : HAL   (<-映画 2001年宇宙の旅に出てきたコンピュータ) 
      変換後の文字列:        (<-上のコンピュータを製造したメーカ)
      

      コード例 A7-1.cpp

      解説

      hal9000という関数は,文字列をsourceからdestへコピーする関数ですが, コピーするときに,文字コードを一つだけ大きくします(7行目).つまり, sourceにある文字が'A'であれば’B'に,'H'なら'I'にするわけです.




    2. 三次元ベクトル(x,y,z)を一次元配列を使って以下のようにつくる.
      typedef float Vector[3];
      このとき,
      • 内積d = a・bを計算する関数 float dot(Vector a, Vector b);
      • 外積c = a X b を計算する関数 void cross(Vector c, Vector a, Vector b);
      をそれぞれ作成せよ. プログラム名を学籍番号10桁-07-2.cppとする.

      コード例 A7-2.cpp

      解説

      x,y,zの3つの実数からなる三次元ベクトルを表すのに,3つの要素をもつ配列を用いています. 配列の先頭から順に収めていくので,インデックス番号0がx, 1がy,2がzになります. 従って,インデックスを数字で直接書かないようにするために文字定数X=0, Y=1, Z=2をそれぞれ 定義しています.ここでは一連の文字定数を定義するのに便利な機能,enum (イニューメレイト) を用いています(5行目).enumではなく,#defineを用いても,const intを用いてもOKです.
      内積,外積はそれぞれ数学の定義をそのままコードにしています.




    3. 一次元配列に文字列が格納されています(キーボードから入力してもよい). この文字列を,降順(asciiコード番号の反対順)に並べる(ソートする) プログラムを作ってください. プログラム名を学籍番号10桁-07-3.cppとする.
      <実行例>
      ソート前:Meiji
      ソート後:jiieM
      

      コード例 A7-3.cpp

      解説

      文字(あるいは数値)を昇順(あるいは降順)にならべる「ソート」プログラムです. ソートのアルゴリズムには様々な方法がありますが,この例は最も単純な (そしておそらく最も効率の悪い)方法です. 配列の中の隣り合うデータを順に見ていって,もしも昇順になっていたら降順になるように 入れ替えています.これをすべての隣り合うデータについて,何度もチェックしていきます. 一連のチェックがすべてOKであれば終了します.




    4. 複数の単語からなる文を入力すると,各単語の先頭文字を大文字に変えて表示するプログラムを作成せよ. プログラム名を学籍番号10桁-07-4.cppとする.
      //実行例 
      Type a string: here is meiji university. 
      Here Is Meiji University.
      

      【ヒント】スペースを含む文字列を入力するには,以下のようなフォーマット指定子を使います
          const int SIZE = 128;
          char words[SIZE];
          printf("Type words: ");
          scanf("%[^\n]", words);	// 改行以外はすべて入力する,の意
      

      コード例 A7-4.cpp

      解説

      スペースの右隣の文字が単語の先頭なので,もしもそれが小文字であれば(11行目)大文字に変換します(12行目). この例では標準ライブラリ関数(isspace, islower, toupper等)を用いていますが,これらの関数を自分で 作るのは良い頭の体操になります.これらの関数は自力で作れるようにしておきましょう.




    5. int num_list[] = {1, 2, 3, 4, 5, 6, 7} の数字の並びを, 任意の回数ローテーションさせるプログラムを作成せよ.
      プログラム名を学籍番号10桁-07-5.cppとする.
      //実行例 
      ローテーションさせる回数:3 
      もとの並び 
      1 2 3 4 5 6 7 
      ローテーション後 
      5 6 7 1 2 3 4
      
      ローテーションさせる回数:-3 
      もとの並び 
      1 2 3 4 5 6 7 
      ローテーション後 
      4 5 6 7 1 2 3
      

      コード例 A7-5.cpp

      解説

      配列はアドレス番号順に一列にならんでいますが,終端が先頭につながるように 利用することがよくあります.このような状態を「Cyclic」といい,このような 記憶領域を「Ring buffer」または「FIFO buffer(ファイフォ,First-In, First-Out)」と呼びます. 本来は,データのコピーに関わるオーバーヘッド(余計な計算)をなくすために, データを物理的にコピーして回転するようなことはせず, データの先頭と終端を表すアドレスポインタを用いますが,非常に難しいので, ここでは物理的にデータをコピーすることで回転させることを行っています.