以下の課題を C, C++, Java 6(Java 1.4 は使わないこと)のどれかの言語を使っ て作りなさい。
注意: Windows の API は使用しないで作って下さい。
レポート締切日: 2007年12月5日20:00
提出先: レポートボックス
受験番号と点数が空白で区切られたようなファイルに対して、成績処理を行な うためのプログラムを作成したい。 以下の小問について答えなさい。
なお、この問題は早々に 2ch に投稿され、既に解答も寄せられています。 同じ掲示板に何度も同じ問題を投稿するのはマナー違反ですので、もう新たに 2ch にこの問題を投稿しないようにして下さい。
質問が多い箇所に関して加筆しました。(2007/11/28)
rand() の値は 0 から RAND_MAX までなので、 0 以上 1 未満の範囲の乱数を 得るには rand() を RAND_MAX で割るのではなく、 RAND_MAX+1 で割る必要が あります。 付録を訂正しておきます。 なお、レポートに関して、再提出の際は RAND_MAX+1.0 で割るようにしてくだ さい。 合格者に関しては評価を変えませんが、このような変更があったことは御留意 下さい。
99999 以下の整数の引数をとり、受験番号を C00001 から順に C00002 の ように引数の数だけ発生させ、 さらに各受験番号に対して乱数で発生させ た点数を組み合わせたテストファイルを作るプログラムを作りなさい。 但し、点数は、 0 点から 5 点までを乱数で 20 回発生させ和を取ること で求めなさい。 引数のとりかた、乱数の発生の仕方は付録を 参照のこと。
次に、作成したプログラムを利用して、 100 人分のテストファイルを作成 しなさい。
C:\work> .\kadai1-1.exe 100 > testfile C:\work> type testfile C00001 60 C00002 35 C00003 78 ...
C:\work> java Kadai11 100 > testfile C:\work> type testfile C00001 60 C00002 35 C00003 78 ...
作成した点数表に対して、手作業で合格最低人数を 20人、40人、60人とし たときの合格最低点と合格人数をそれぞれ求めなさい。 但し、合格最低点とは合格最低人数 20 人であれば、 20 位の点数のことであ る。また、合格人数とは合格最低点以上を得点している人数のこととする。
なお、手作業の代わりに、表計算ソフトを使用しても良い。但し、表計算ソフ トを使用した際は、必ず表の使用方法や、使用した関数の説明を行なうこと。
点数表を読み込み、点数の高い順に出力するプログラムを作成しなさい。 プログラムにおいて点数表の容量を制限してはいけない。コンピュータのメモ リが許す限り大きな点数表も表示できること。
次に、作成した点数表に対し、実行した結果を示しなさい。
C:\work> .\kadai1-3.exe < testfile C00003 78 C00001 60 C00002 35 ...
C:\work> java Kadai13 < testfile C00003 78 C00001 60 C00002 35 ...
合格最低人数を引数にして合格最低点を求めるプログラムを作成しなさい。 但し、引数のとりかたは付録を参照すること。
そして、プログラムに対して、作成した点数表と、合格最低人数として、 20 人、40人、60人 をそれぞれ与え、合格最低点を求めなさい。
C:\work> .\kadai1-4.exe 20 < testfile 65 C:\work> .\kadai1-4.exe 40 < testfile 60 C:\work> .\kadai1-4.exe 60 < testfile 53
C:\work> java Kadai14 20 < testfile 65 C:\work> java Kadai14 40 < testfile 60 C:\work> java Kadai14 60 < testfile 53
合格最低点を引数に取り、受験番号順に合格者リストを表示するプログラ ムを作りなさい。
そして、 1-4 で得られた 3 種類の合格最低点をそれぞれ与 え、合格者リストを作成しなさい。
C:\work> .\kadai1-5.exe 65 < testfile C00003 ... C:\work> .\kadai1-5.exe 60 < testfile C00001 C00003 ... C:\work> .\kadai1-5.exe 53 < testfile C00001 C00003 ...
C:\work> java Kadai15 65 < testfile C00003 ... C:\work> java Kadai15 60 < testfile C00001 C00003 ... C:\work> java Kadai15 53 < testfile C00001 C00003 ...
なお、ファイルの入出力は標準入出力でも、ファイルの入出力でもどちらを使 用しても良い。 但し、ファイルの入出力を使う際は、ファイルの非存在などのエラー処理は必 ず行うこと。
一文字の処理に、文字列の文字数に比例した時間かかったり、一行の処理に 全体の行数分の時間がかかるようなプログラムは大幅に減点します。
2007/12/21 課題 2-3 に加筆しました。
12月19日は会議など所用で在室時間を確保できなくなりましたので、期限を一 日延長します。 できれば 12 月 20 日に提出してください。
紙の場合、11号館12F1206室で手渡し。冬休み中にやりとり可能なメールアドレスを記入すること。PDF ファイルを受信できること
PDF ファイルをメールしてきても良い。但し、冬休み中にやりとり可能なメールアドレスを指定すること。
これ以外の形式(マイクロソフトのワープロのファイル、画像ファイル)などは受け取りませんので注意。
ファイルを読み込み、英字のみか、先頭が英字で二文字目以降が英字または数 字である文字列を抽出し、文字列を辞書順に並べ、その文字列の頻度と 共に表示するプログラムを作成したい。 但し、大文字小文字は区別しない。 このプログラムを作成するのに、以下の設問にしたがって回答しなさい。
なお、辞書順とはつぎのような順序を言う
したがって、次のような順になります。
a < aa < aaa < ... < ab < aba < ...
実用上問題があるかもしれませんが、下記の例のように Matcher==matcher と しても構いません。 また、Matcher!=matcher として数え上げ、出力時の整列順序だけ大文字小文 字を区別しないようにプログラムを作成した場合は、より難易度の高い問題を 解いたとして評価します。
なお、この問題も既に 2ch に投稿され、解答も寄せられました。 何度も言いますが、同じ掲示板に何度も同じ問題を投稿するのはマナー違反で すので、くれぐれも新たに2ch にこの問題を投稿しないようにして下さい。 掲示板の皆様、本学の学生がお騒がせして済みませんでした。
import java.io.*;
import java.util.regex.*;
class Test {
public static void main(String[] arg) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String buf;
Pattern p = Pattern.compile("[0-9A-Za-z]+");
Matcher m;
while((buf=br.readLine())!=null){
m= p.matcher(buf);
while(m.find()){
System.out.println(m.group());
}
}
}
}
A: 1 arg: 1 br: 2 buf: 3 BufferedReader: 2 class: 1 compile: 1 find: 1 group: 1 import: 2 in: 1 InputStreamReader: 2 io: 1 IOException: 1 isr: 2 java: 2 m: 4 main: 1 Matcher: 2 new: 2 null: 1 out: 1 p: 2 Pattern: 2 println: 1 public: 1 readLine: 1 regex: 1 static: 1 String: 2 System: 2 Test: 1 throws: 1 util: 1 void: 1 while: 2 z: 1 Za: 1
ファイルを読み込み、英字のみか、先頭が英字で二文字目以降が英字または数字である文字列を出力するプログラムを作りなさい。
import java io import java util regex class Test public static void main String arg throws IOException InputStreamReader isr new InputStreamReader System in BufferedReader br new BufferedReader isr String buf Pattern p Pattern compile A Za z Matcher m while buf br readLine null m p matcher buf while m find System out println m group
文字列 s1,s2 の二つを比較する関数またはクラスを作りなさい。
int cmp(char *s1, char *s2);
これを strcmp と同じ仕様となるようにします。
但し、文字列は大文字、小文字を区別しないので、あらかじめ toupper()関数
(ctype.h をインクルードする必要あり)などを使用して比較対象を大文字に変
換します。
この後、辞書式順序の比較を行います。
s1 と s2 の文字を順番に比べていき
(1) s1 が先に終わったか、 s1 の文字の方が小さい時に負の値、
(2) s2 が先に終わったか、 s2 の文字の方が小さい時に正の値を返します。
(3)両方同時に終わったときは 0 を返します。
どちらも終わらず、注目している文字が同じ場合は、注目する文字を次に移し
ます。
class Cmp : public std::binary_function<std::string,std::string,bool> {
public:
bool operator()(const std::string& s1, const std::string& s2){
// ここは自分で書く
}
};
イテレータ、toupper の使用例:
#include <cctype>
#include <string>
#include <iostream>
int main(){
std::string h="Hello World!\n";
for(std::string::iterator p=h.begin(); p!=h.end(); ++p){
std::cout << static_cast<char>(std::toupper(*p));
}
}
class Cmp implements java.util.Comparator<String> {
public int compare(String s1, String s2){
// ここは自分で書く
}
}
但し、 Java の String クラスにはズバリ compareToIgnoreCase メソッドが
ありますので、そのまま使って下さい。
なお、テスト方法はこちら
題意を満たすプログラムを作りなさい。 プログラムを説明する時、2-1, 2-2 で作成したプログラムをどのように活用したか も説明しなさい。
完成したプログラムに、上記の実行例の入力を与え、出力が同じになることを 確かめなさい。 但し、 出題後の問題の変更ですので、特に確かめなくても不合格にはしませんが、 ここが同一にならないプログラムを提出すると、もともとの問題が解けてない ことになり、不合格になります。必ず確かめること。 さらに、何度も言っていることですが、「確かめなさい」という問題で「確か めました」という答は減点の対象になりますので、注意してください。
なお、問題文注釈にある通りの仕様変更をした場合は、実行例の出力がどのよ うに変化するか説明し、実際に予想通りの出力になることを確かめてください。
作成したプログラムのソースコードを作成したプログラムに与え、出力を 求めなさい。
ファイルの終端が改行の直後にあることを仮定しても構いません (販売するようなレベルのソフトウェアでは問題ですが)。
ファイルを二回以上 open しないこと。 0 回または 1 回で済ませて下さい。 また最適さを追求しすぎる必要はないですが、余りにも効率が悪すぎる手法を 使用した場合(バブルソートを使うなど)、講義の内容を理解していないと見な しますので、ご注意下さい。
#include <iostream>
#include <locale>
using std::isalpha;
using std::isalnum;
int main(){
std::locale loc;
std::cout << isalpha('2',loc)
<< isalpha('a',loc)
<< isalpha('#',loc)
<<std::endl;
std::cout << isalnum('2',loc)
<< isalnum('a',loc)
<< isalnum('#',loc)
<<std::endl;
}
古い gcc を使っていると locale が入ってないため、上は動きません。 新しい mingw32 にバージョンアップを勧めますが、古い gcc のまま動かした い場合は下記のようにして下さい。 但し、結果は上とは異なります。
#include <iostream>
#include <cctype>
using std::isalpha;
using std::isalnum;
int main(){
std::cout << isalpha('2')
<< isalpha('a')
<< isalpha('#')
<<std::endl;
std::cout << isalnum('2')
<< isalnum('a')
<< isalnum('#')
<<std::endl;
}
#include <stdio.h>
#include <ctype.h>
int main(void){
printf("%d %d %d\n", isalpha('2'),isalpha('a'),isalpha('#'));
printf("%d %d %d\n", isalnum('2'),isalnum('a'),isalnum('#'));
return 0;
}
課題 2-1 でできあがったプログラムは、各行ごとにはそれほど複雑な関数を 使用したりしません。 したがって、各行毎に説明をしてもプログラムがどのように動作するのかは説 明できません。
課題2-1 のプログラムを説明するには、次のようにすると良いでしょう。
文字列バッファの操作方法が記入されたオートマトンができたら、「これをそ のままプログラムにした」という主張だけで、プログラムの解説になっている はずです。
C++ で作る際、 map を使う方法と、 list を使う方法の二種類があります。 list を使う場合、 Cmp 型のオブジェクト変数を定義すると便利です。
なお、写したと思われるほど酷似したレポートが複数提出された場合、原著が どれかの調査を行わず、抽選で一通のレポートのみを評価 の対象とし、他は提出済みの不合格レポートとして再提出は課しません。 自分で意図せずに他人にコピーされてしまった場合も同様ですので、レポート の取り扱いについては十分に注意して下さい。