脱プログラミング入門
Amebaでブログを始めよう!

サンプル

/*
2~1000までの正の整数のうち、2の倍数でも,3の倍数でも,また5の倍数でもない整数 を求めるプログラム
*/

#include <stdio.h>

main(viod) {
int table[1001];
int i;

for(i=0;i<1001;i++) {
table[i]=i;
}

for(i=2;i<1001;i++){
if (i % 2==0) {
table[i]=0;
}
else if (i % 3==0){
table[i]=0;
}
else if (i % 5==0){
table[i]=0;
}
}

for(i=2;i<1001;i++){
if(table[i] != 0) {
printf("%d",table[i]);
printf("\n");
}
}
}

選択ソート

選択ソート

【最小値順の場合】
①A[0]を最小値と仮定する。
②A[0]~A[n-1]内の最小値をA[0]にセットする。
③A[0]を除いて、A[1]~A[n-1]内の最小値をA[1]にセットする。
④上記処理をA[n-2]~A[n-1]まで繰り返す。


#include <stdio.h>

main() {
int i,j,t,min;
int n[5]={5,8,4,3,9};

for(i=0;i<5;i++){
min=i;
for(j=i+1;j<5;j++){
if(n[j] < n[min]){
min=j;
}
}
t=n[i];
n[i]=n[min];
n[min]=t;
printf("%i\n", n[i]);
}
}

開き直るコツを知りたい

ソフトウエアハウスに勤めたとき、最初の1年ぐらいしかプログラムを書いていなかった。後は設計書ばかり書いていた。自分はSEだと人に宣言したことないが、会社ではSEの値段で発注元に請求している。そのせいなのか、少々プログラミングにコンプレックスを持っている。でも、お陰で基本設計から納品、仕様変更の開発に必要なシステム開発に必要なほとんどのプロセスを経験させていただいた。


学校に通ってから、プログラムを書く機会が増えた。90%以上は自力で書いていた。中に2、3日悩んだものもある。今日振り返ってみると、書いた内容のほとんどを忘れてしまった。ゆっくり思い出せるが、基本的なアルゴリズムばかりで、眼を閉じてもかけるようになりたい。書いたプログラムを繰り返し復習しなければならないと痛感した。

※復習の仕方について

http://www.21rots.com/hukusyu.htm


先週悪夢のような1週間だった。3つの課題の締め切り日に続き、1つの中間試験があった。おまけに分からない授業が増えた。今までは先生の説明が分かるようでわからないことが多かった。何とか重要なポイントだけ理解するようにしていた。先週のOSの授業は何に言っているのか、さっぱり分からなかった。ショックで学校のうどん屋で大盛りのうどんを注文して、やけ食いをしていた。


この状態では決して勉強できる状態ではないと思う。私には開き直る精神が必要だ。と思いながらも開きなりきれないのだ。コツがほしいのだ。

バブルソート

バブルソート、最も原始的なアルゴリズム。バブルソートの処理速度がデータ列の要素数を2乗したものにほぼ比例することを意味する。よって要素数が2倍になれば、処理速度は4倍になる。

array[n]からarray[0]まで 隣同士比較、一番小さい数字をarray[0]に入れる。

array[n]からarray[1] まで隣同士比較、一番小さい数字をarray[1]に入れる。

array[n]からarray[2] まで隣同士比較、一番小さい数字をarray[2]に入れる。

配列の要素が無くなるまで、上記処理を繰り返す。


/*
小さい順に並べる
*/

#include <stdio.h>

main() {
int n[5]={8,17,45,9,5};
int i,j,t;

for(i=0;i<5;i++) {
for(j=4;j>i;j--){
if(n[j] < n[j-1]){
t=n[j];
n[j]=n[j-1];
n[j-1]=t;
}

}
printf("%d\t",n[i]);
}

}



/*大きい順に並べる*/


関数

レポートA-1
fun m(x) =
if x>100
then x-10
else m(m(x+11))
この関数は、何にを計算するものか、言葉で説明しなさい。

引数Xが101 以下の場合は 出力は91になるでしょう

仮に Xが95の場合
if文により else節が実行されます
ここで m(m(x+11))の m(x+11)を評価します ....(1)
したがって m(x+11) ... m(95+11) ... m(106)として 再帰します

引数Xが 106となるので if文は成立しThen節が実行されます
したがって 106-10の 96が返り値 となります

ここで帰るところが (1)の外側の m()になります
ここでm(96)を再度評価することになります

これを繰り返して m(97) m(98) m(99) m(100) m(101) まで繰り返されます
最後の m(101)の 返り値は Then節ですので 91となります

引数Xが 102以上ですと 単に10減算した値が出力になりますよ



#include <stdio.h>
#include <stdlib.h>

int m( int x ){
if ( x > 100 ) {
return x - 10;
} else {
int n = m(x+11);
return m(n);
}
}

main(void){
int x = 0,n=0;
x=99.5;
n = m( x );
printf( "m(%d)=%d\n", x, n );
}

Scheme_構造体

構造体

1.宣言

2.コンストラクタ(make-構造体名)、セレクタ(構造体名-各引数) 構造体?が生成


問1:ballの座標値から原点までの距離を求める。

入力 ⇒ballの構造体

処理 ⇒distance-to-0関数

出力 ⇒数値(距離)


;;ballの構造体を定義

(define-struct ball
(x y delta-x delta-y))


以下のものが生成

;;make-ball(x y delta-x delta-y)

::ball-x,ball-y,ball-delta-x,ball-delta-y

;;ball?

;;distance-to-0関数を定義

(define (distance-to-0 a-ball)
(sqrt
(+ (sqr (ball-x a-ball)) (sqr (ball-y a-ball)))))


;;実行
(distance-to-0 (make-ball 3 4 0 0))



問2:A点とB点のXの差を求める

入力 ⇒A点とB点の構造体

処理 ⇒関数distance 引数A点とB点の構造体のコンストラクタ

出力 ⇒数値
;;任意点の座標の構造体pointを宣言

(define-struct point(x y z))

;;distance関数を定義

(define (distance pA pB)
(- (point-x pA) (point-x pB)))

;;実行1

(distance (make-point 19 2 3) (make-point 6 7 8))


;;実行2
(define p0 (make-point 0 0 0))
(define p1 (make-point 100 0 0))
(distance p0 p1)


問3:3次元空間の、2点間のユークリッド距離を求める
;; distance = sqrt( sqr((x1-x2 )+(y1-y2)+(z1-z2)
(define-struct point(x y z))
(define p0 (make-point 0 0 0))
(define p1 (make-point 100 0 0))
(define p2 (make-point 0 200 0))
(define p3 (make-point 100 100 0))

(define (distance p-fast p-next)
(cond
[(and (point? p-fast)
(point? p-next))
(sqrt
(+
(sqr (- (point-x p-fast) (point-x p-next)))
(sqr (- (point-y p-fast) (point-y p-next)))
(sqr (- (point-z p-fast) (point-z p-next)))
))]
[else 'ERROR]))

(distance p0 p1)
(distance p0 p2)
(distance p0 p3)
(distance 1 2)

DrSchemeに組み込み済の構造体

posn構造体 任意1点:属性x y


問4:3次元上の球を表現する構造体


(define-struct point (x y z))
(define-struct circle (c r))

;;c0とc1の距離を求める
(define (distance c-fast c-last)
(sqrt
(+
(sqr (- (point-x (circle-c c-fast)) (point-x (circle-c c-last))))
(sqr (- (point-y (circle-c c-fast)) (point-y (circle-c c-last))))
(sqr (- (point-z (circle-c c-fast)) (point-z (circle-c c-last))))
)))

;;c0とc1の半径の合計を求める
(define (sumr c-fast c-last)
(+
(circle-r c-fast)
(circle-r c-last)
))

;;over関数を定義
(define (over c-fast c-last)
(cond
[(> (distance c-fast c-last) (sumr c-fast c-last)) false]
[else true]))

;;比較
(define c0 (make-circle (make-point 0 0 0) 10))
(define c1 (make-circle (make-point 10 0 0) 3))
(define c2 (make-circle (make-point 0 -12 0) 2))

;;(distance c0 c1)
;;(sumr c0 c1)
(over c0 c1)
(over c0 c2)
(over c1 c2)


問5:式の計算

(define-struct expr (opc opr1 opr2))


(define (eval expr1)
(cond
[(eq? (expr-opc expr1) 'PLUS) (+ (expr-opr1 expr1) (expr-opr2 expr1))]
[(eq? (expr-opc expr1) 'MUL) (* (expr-opr1 expr1) (expr-opr2 expr1))]
[(eq? (expr-opc expr1) 'DIV) (/ (expr-opr1 expr1) (expr-opr2 expr1))]
[(eq? (expr-opc expr1) 'SUB) (- (expr-opr1 expr1) (expr-opr2 expr1))]
))

(eval (make-expr 'PLUS 1 3))
(eval (make-expr 'MUL 100 2))
(eval (make-expr 'DIV 3 1))
(eval (make-expr 'SUB 1000 200))

入力された文字列の中の小文字のアルファベットを大文字にした文字列を出力

/*
1、文字列を入力
2、入力された文字列の中の小文字のアルファベットを大文字にした文字列を出力
*/

#include <stdio.h>

main() {

char str[100];
int i;

printf("input character\n");

scanf("%s",str);

i=0;
while (str[i] != '\0'){
if(str[i]>='a' && str[i]<='z') {
str[i]=str[i]-'a'+'A';
i++;
}
}
printf("%s\n",str);

}

入力された文字列を逆順にした文字列を出力するプログラムを作成しなさい。

/*
入力された文字列を逆順にした文字列を出力するプログラムを作成しなさい。
例えば、appleは、elppaと出力される。文字列とは、文字コード'\0'で終る文字の配列であることを注意すること。
処理手順:
1、文字配列を0から取得
2、 文字配列をnから出力
test data:
print→tnirp
123456789→987654321
hello world→olleh
@@@@@→@@@@@
*/

#include <stdio.h>

main() {

char str[100];
int len=0;
int i;

printf("input string\n");
scanf("%s",str);

len=0;
while(str[len] != '\0') {
len++;
}

for(i=len;i>=0;i--) {
printf("%c",str[i]);
}

}

文字列中に含まれている文字「a」の個数を調べて、その個数を出力。

/*
処理手順:
1、文字列を入力
2、文字列中に含まれている文字「a」の個数を調べて、その個数を出力。

test data:
and→1
tea→1
hahaha→3
yuilo→0
12345→0
*agaoaa→4
*/

#include <stdio.h>

main() {

char str[100];
int i,j;


printf("input string.\n");
scanf("%s",str);

j=0;
for(i=0;str[i];i++) {
if(str[i]=='a') {
j++;
}
}

printf("j=%d",j);
}

文字列中に含まれている、0から9までの各数字の出現回数を表示するプログラム

/*
処理手順:
1、文字列を入力
2、文字列中に含まれている、0から9までの各数字の出現回数を表示するプログラム
*/

#include <stdio.h>

main() {

char str[100];
int i,ch;
int cnt[10]={0};

while(1){
ch=getchar();
if(ch==EOF) break;

switch(ch) {
case '0' : cnt[0]++;break;
case '1' : cnt[1]++;break;
case '2' : cnt[2]++;break;
case '3' : cnt[3]++;break;
case '4' : cnt[4]++;break;
case '5' : cnt[5]++;break;
case '6' : cnt[6]++;break;
case '7' : cnt[7]++;break;
case '8' : cnt[8]++;break;
case '9' : cnt[9]++;break;
}
}

for(i=0;i<10;i++) {
printf("%d=%d\n",i,cnt[i]);
}

}