歯ブラシ選びの大事なポイントとは?

2行2列を5乗させるプログラムを作って、一応できたつもりだったんですが結果が合いません・・・
何かヒントでもいいのでわかる方いらっしゃいましたらよろしくお願いします。

<プログラム>
#include <stdio.h>

#define N 2

int A[N][N];
int A_NEW[N][N];
int A_5[N][N]; /* 行列Aを5乗したもの */

int main()
{
int i,j,k,l;

/* 2行2列の係数行列Aの成分を入力 */
printf("係数行列Aを%d行%d列で入力してください\n", N, N);

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("A[%d][%d]=", i+1, j+1);
scanf("%d", &A[i][j]);
}
}

for(i=0; i<N; i++)/* A_NEW=A*Aの計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_NEW[i][j] += A[i][k] * A[k][j];
}
}
}

for(l=0; l<3; l++)
{
for(i=0; i<N; i++)/* A_5の計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_5[i][j] += A_NEW[i][k] * A[k][j];
}
}
}

for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
A_NEW[i][j] = A_5[i][j];
}
}
}

printf("A_5=\n"); /* 出力 */

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


<入力例>
A=
1 3
2 1

<期待する結果>
A=
241 303
202 241

<このプログラムの結果>
406 498
332 406

A 回答 (3件)

#include <stdio.h>



#define N 2

int A[N][N];
int A_NEW[N][N];
int A_5[N][N]; /* 行列Aを5乗したもの */

int main()
{
int i,j,k,l;

/* 2行2列の係数行列Aの成分を入力 */
printf("係数行列Aを%d行%d列で入力してください\n", N, N);

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("A[%d][%d]=", i+1, j+1);
scanf("%d", &A[i][j]);
}
}

for(i=0; i<N; i++) /* A_NEW=A*Aの計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_NEW[i][j] += A[i][k] * A[k][j];
}
}
}

for(l=0; l<3; l++)
{
for(i=0; i<N; i++) /* A_5の計算 */
{
for(j=0; j<N; j++)
{
for(k=0; k<N; k++)
{
A_5[i][j] += A_NEW[i][k] * A[k][j]; /* …P */
}
}
}

for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
A_NEW[i][j] = A_5[i][j];
}
}

/* 一端0に戻さないと残存している結果にPを足されることになる …Q*/

for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
A_5[i][j] = 0;
}
}


}

printf("A_5=\n"); /* 出力 */

for( i=0; i<N; i++)
{
for( j=0; j<N; j++)
{
printf("%d ", A_NEW[i][j]); /* Qで0に戻しちゃったので出力結果の変数が変わっています。*/
}
printf("\n");
}
}

/*
ただ,個人的には,二つの行列を計算するだけの関数を分けて
mainから5回呼び出した方が綺麗だと思う
面倒なので書かないけど,ここまで自力でコード書く人なら
これだけできちんと書けるだけの人なはず。頑張ってね!
*/
    • good
    • 0
この回答へのお礼

なるほど!
完全に理解できました。
加筆修正ありがとうございます!
次は関数使って書いてみます!

お礼日時:2008/07/22 10:06

他の方が指摘をされているので,サンプル書いてみました.


------
int A[N][N] = {{1,3},{2,1}};//入力
int R[N][N] = {{1,0},{0,1}};//出力 単位行列で初期化
int i, j, k,l;

for(l = 0; l < 5; l++){
  //i行目の処理
  for (i = 0; i < N; i++) {
    //i行目をTに記憶
    int T[N];
    for (k = 0; k < N; k++)
      T[k] = R[i][k];
    //i行目の計算
    for (j = 0; j < N; j++) {
      //i行j列目を計算
      int tmp = 0;
      for (k = 0; k < N; k++)
        tmp += T[k] * A[k][j];
      R[i][j] = tmp;
    }
  }
}
------
R = R * A
積の計算では,Rのi行目の計算を始める前にまず,i行目を記憶.
記憶したi行目とAのi列目を計算してRのi行目へ記憶としています.
こうすることで,RとAだけで計算を進めることができます.

5乗の計算は,入力としてR,A(入力)を取り,出力としてRを出力するようにしてみました.
Rの初期値を R = E(Eは単位行列) として R = R * A を5回まわしています.
一回目は,R = E * A = A,2回目は R = R * A = Aの2乗となっていきます.

定式化(設計)をきっちりとせずにコーディングに移ると,その場で作った曖昧な処理がうまく働かないことが多いので
PCに向かう前に,紙に式などを書いてみると返って早く完成しますよ.
    • good
    • 0
この回答へのお礼

なるほどー
こっちの方がシンプルですね!
わかりやすく書いていただきありがとうございます!

一応先に紙に書いてから作ってるんですが、まだ勉強し始めて
1週間ちょっとなのでまだまだ完成に至るまでには甘いです・・・

お礼日時:2008/07/22 10:12

デバッガを使って 変数の値を追いかけましょう



for(i=0; i<N; i++) /* A_NEW=A*Aの計算 */
{
  for(j=0; j<N; j++)
  {
    for(k=0; k<N; k++)
    {
      A_NEW[i][j] += A[i][k] * A[k][j];
    }
  }
}
のループの中で A_NEW[i][j]の期待する値と実際の値を比べて見ましょう
+= で代入 & 加算をしているので kのループに入る前のA_NEW[i][j]の値はどうなっているのが正常なのでしょう
    • good
    • 0
この回答へのお礼

ご意見ありがとうございます。
ただ、まだデバッガの使い方を習っていないのでわからないです・・・
代わりにprintfで逐次調べてみます!

お礼日時:2008/07/22 10:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qc言語 行列のn階乗のプログラム

  1 2 -1
D= 3 0 -2
  -1 1 2

の3次正方行列のn乗を計算するプログラムを作成しています。
いろいろと試してみましたがうまくいきません。
どなたか教えていただけるとうれしいです。
よろしくおねがいします。



#include <stdio.h>

int main(void)
{
int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };
int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };
int s[3][3];
int m,n;
int i,j,k;


printf("[A]^n;n = ");scanf("%d",&n);

for (m=2;m <= n;m++){
for (i=0;i<3;i++){
for (j=0;j<3;j++){
s[i][j] = 0;
for(k=0;k<3;k++){
s[i][j] =s[i][j] + a[i][k] * b[k][j];
}
}
}


for(i=0;i<3;i++){
for(j=0;j<3;j++){
b[i][j]=s[i][j];
}
}
printf("%3d",s[i][j]);
putchar('\n');
}
return (0);
}

  1 2 -1
D= 3 0 -2
  -1 1 2

の3次正方行列のn乗を計算するプログラムを作成しています。
いろいろと試してみましたがうまくいきません。
どなたか教えていただけるとうれしいです。
よろしくおねがいします。



#include <stdio.h>

int main(void)
{
int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };
int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };
int s[3][3];
int m,n;
int i,j,k;


printf("[A]^n;n = ");scanf("%d",&n);

for (m=2;m <= n;m++){
for (i=0;i<3;i++){
for (j=0;j<3;...続きを読む

Aベストアンサー

計算方法はあってます。
違っているのは次の2箇所です。
(1) 行列a, bの値設定
(2) 計算結果の表示

> int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };
> int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };

1行1列目の要素(つまりa[0][0]とb[0][0]の値)が-1になっています。
行列Dの1行1列目の要素は1ですよね。

> printf("%3d",s[i][j]);
> putchar('\n');

この2行だけだとs[3][3]だけを表示して終わってしまいます。
また、この位置で出力してしまうと2乗 ~ n乗の結果が全部表示されてしまいます。

n乗の結果のみを出力したいなら、
この2行を消してreturn文の直前に

for(i = 0; i < 3; i++){
 for(j = 0; j < 3; j++){
  printf("%3d",s[i][j]);
 }
 putchar('\n');
}

と打ち込んでみましょう
(ちなみに上のコードは全角空白を含んでいるので、
回答文からこのコードをコピー&ペーストしてしまうと
コンパイルエラーが起きるので注意してください)。

計算方法はあってます。
違っているのは次の2箇所です。
(1) 行列a, bの値設定
(2) 計算結果の表示

> int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };
> int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} };

1行1列目の要素(つまりa[0][0]とb[0][0]の値)が-1になっています。
行列Dの1行1列目の要素は1ですよね。

> printf("%3d",s[i][j]);
> putchar('\n');

この2行だけだとs[3][3]だけを表示して終わってしまいます。
また、この位置で出力してしまうと2乗 ~ n乗の結果が全部表示されてしまいます。

n乗の結果...続きを読む

QC言語、行列の積を求めるプログラムについて

「次に示す行列x,yの積を求めるプログラムを作成せよ。
  x[2][3]={{1,2,3},{4,5,6}} y=[3][2]={{1,5},{5,3},{81}}」
という問題です。自分ではとりあえず、
#include<stdio.h>
int main(void)
{
int i,j;
int x[2][3]={{1,2,3},{4,5,6}};
int y[3][2]={{1,5},{5,3},{8,1}};
int xy[3][3]={0};

for(i=0;i<3;i++)
for(j=0;j<3;j++)
xy[i][j]=x[i][j]*y[i][j];

for(i=0;i<3;i++){
for(j=0;j<3;j++)
printf("%3d",xy[i][j]);
putchar('\n');
}
return 0;
}
というプログラムを作ってみましたが、ダメでした。
ちゃんと積の表示が出るようにするにはどこをどう変えるべきでしょうか?

Aベストアンサー

#include<stdio.h>
int main(void)
{
int x[2][3] = { { 1, 2, 3 }, { 4, 5, 6} };
int y[3][2] = { { 1, 5 }, { 5, 3 }, { 8, 1 } };
int xy[2][2];
int i, j, k;

for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
xy[i][j] = 0;
for (k = 0; k < 3; k++) {
xy[i][j] += x[i][k] * y[k][j];
}
}
}

for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%4d", xy[i][j]);
}
putchar('\n');
}
return 0;
}

#include<stdio.h>
int main(void)
{
int x[2][3] = { { 1, 2, 3 }, { 4, 5, 6} };
int y[3][2] = { { 1, 5 }, { 5, 3 }, { 8, 1 } };
int xy[2][2];
int i, j, k;

for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
xy[i][j] = 0;
for (k = 0; k < 3; k++) {
xy[i][j] += x[i][k] * y[k][j];
}
}
}

for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
printf("%4d", xy[...続きを読む

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。

Q2の累乗を計算するプログラムを作ったのですが・・・

C言語を用いて、2の累乗(2,4,8,16・・・)を
計算して表示するプログラムを

#include<stdio.h>
void main(void)
{
int i,s;
s=1;
for(i=1; i<=15; i++)
{
s=s*2;
printf("i=%2d s=%7d\n",s);
}
}

と打ち込んで実行したのですが、結果が

i= 1 s= 2
i= 2 s= 4
i= 3 s= 8
i= 4 s= 16
i= 5 s= 32
i= 6 s= 64
i= 7 s= 128
i= 8 s= 256
i= 9 s= 512
i=10 s= 1024
i=11 s= 2048
i=12 s= 4096
i=13 s= 8192
i=14 s= 16384
i=15 s= -32768

のように、2の15乗だけが負になってしまいました。
最初のintをdoubleやfloatに直して実行すればよいのかとも考えたのですが、
実行すると答えがすべて0になってしまい上手くいきませんでした。
どの部分がおかしいのでしょうか・・・;

C言語を用いて、2の累乗(2,4,8,16・・・)を
計算して表示するプログラムを

#include<stdio.h>
void main(void)
{
int i,s;
s=1;
for(i=1; i<=15; i++)
{
s=s*2;
printf("i=%2d s=%7d\n",s);
}
}

と打ち込んで実行したのですが、結果が

i= 1 s= 2
i= 2 s= 4
i= 3 s= 8
i= 4 s= 16
i= 5 s= 32
i= 6 s= 64
i= 7 s= 128
i= 8 s= 256
i= 9 s= 512
i=10 s= 1024
i=11 s= 2048
i=12 s= 4096
i=13 s= 8192
i=14 s= 16384
i=1...続きを読む

Aベストアンサー

No2です。

追記ですが、printfの変換指定子は型にあわせたものを使わなければ正しく表示されません。
long であれば %ld にしてください。

参考URL:http://ja.wikipedia.org/wiki/Printf

Qセグメンテーション違反とは??

linuxでC言語のプログラムを構築しています。
gccでコンパイルしたときにセグメンテーション違反という
エラーが出てしまいます。
セグメンテーション違反とは一体なんの
ことなんでしょうか?
メモリのことだと思ってるんですが、原因がよくわかりません。C言語初心者なので
わかりやすく教えて頂けるとありがたいです。

Aベストアンサー

似たような質問を発見しました。以下のURLを参考にしてみてはどうでしょうか?

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=715484

Q三角関数の記述の仕方

タイトルそのまんまなんですが、三角関数はC言語ではどのように記述すればいいでしょうか?
角度にラジアン表記でπ(パイ)を使いたいんですが、その表記方法もわかりません。
僕の持っている本に載ってなかったので質問させていただきました。
よろしくお願いします。

Aベストアンサー

C言語で三角関数を使うためには、math.h をインクルードする必要があります。使い方は例えば、こんな感じです。

#define M_PI 3.14159265358979 /* 円周率 */

double x, y, theta;

theta = M_PI / 4.0;
x = cos(theta); /* sin,cos,tanの引数は弧度法の角度です。*/
y = sin(theta);

πは上記の例のように自分で定義して使ってください。

Q入力した数値を0~3乗するプログラム (C言語)

この前学校の授業でやり方がわからなかったことがあるので質問させていただきます。

scanfを使って入力した整数を0~3乗したものを出力するプログラムをかけ

ちなみに7を入力すれば、
7^0=1,7^1=7,7^2=49,7^343
と出力されるようにしなさい

という問題が出ました。

これは掛け算を使って作るのでしょうか?

このプログラムの作り方と解答例をご教授願います。

Aベストアンサー

以下のようにしてください。
--------------------------------------------
#include <stdio.h>
int main(void)
{
int result = 1;
int x;
int i;
printf("x=");
scanf("%d",&x);
printf("x=%d\n",x);
for(i = 0; i < 4;i++) {
printf("%d^%d=%d\n",x,i,result);
result = result * x;
}
return (0);
}
-----------------------------------------
7を入力したときの実行結果
x=7
x=7
7^0=1
7^1=7
7^2=49
7^3=343
--------------------------------------
CentOS release 5.6 (Final)
gcc バージョン 4.1.2 20080704 (Red Hat 4.1.2-50)
で動作確認済みです。

以下のようにしてください。
--------------------------------------------
#include <stdio.h>
int main(void)
{
int result = 1;
int x;
int i;
printf("x=");
scanf("%d",&x);
printf("x=%d\n",x);
for(i = 0; i < 4;i++) {
printf("%d^%d=%d\n",x,i,result);
result = result * x;
}
return (0);
}
-----------------------------------------
7を入力したときの実行結果
x=7
x=7
7^0=1
7^1=7
7^2=49
7^3=343
--------------------------------------
CentOS release 5.6 (Final)...続きを読む

QC言語のポインターに関する警告

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int=i; /*main関数内のfor文で使用*/
char line[100], out[100];
void change(int);

/*関数*/
void change(int i)
  {
   if(line[i]=='1'){
    out[10]="a\0"
   }if(line[i]=='2'){
    out[10]="b\0";
   }if(line[i]=='3'){
    out[10]="c\0"
}
}

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int...続きを読む

Aベストアンサー

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(line[i]=='1'){
    out[10]=0x61; /* aのASCIIコード */
   }if(line[i]=='2'){
    out[10]=0x62; /* bのASCIIコード */
   }if(line[i]=='3'){
    out[10]=0x63; /* cのASCIIコード */
}
}
と書きましょう。

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(l...続きを読む

Q縦の棒グラフ

こんにちは。30代のプログラム初心者です。
C言語で一日毎の平均気温に合わせて、「*」印を下図のようなイメージで表示する棒グラフを作成したい(5℃なら*を5つ表示)のですが、丸1日試行錯誤してもうまくいきませんでした。
ちなみに配列kionには、一日毎の気温を格納しています。

int kion{5,4,3,・・・};
(℃)
10|
9|
8|
7|
6|
5| *
4| * *
3| * * *
2| * * * (以下省略)
1|_*_* *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
0 1 2 3 4 5 6 7 8 9 10 11 12 ~(以下省略)

横のメモリの
_ _ _ _ _ _ _ _ _ _ _ _ _
0 1 2 3 4 5 6 7 ・・・

は、普通にprintfで表示させているのですが、
縦の
10|
9|
8|
7|
6|
5|
の表示がうまくいきません。
二次元配列を使っているのですが、やりかたが悪いんだと思います。
アドバイスを頂ければありがたいです。よろしくお願い致します。

こんにちは。30代のプログラム初心者です。
C言語で一日毎の平均気温に合わせて、「*」印を下図のようなイメージで表示する棒グラフを作成したい(5℃なら*を5つ表示)のですが、丸1日試行錯誤してもうまくいきませんでした。
ちなみに配列kionには、一日毎の気温を格納しています。

int kion{5,4,3,・・・};
(℃)
10|
9|
8|
7|
6|
5| *
4| * *
3| * * *
2| * * * (以下省略)
1|_*_* *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _
0 1 2 3 4 5 6 7 8 9 10 11 12 ~(以下省略)...続きを読む

Aベストアンサー

こんな感じでどうでしょう?

for (i = 10; i > 0; i--){
 // 気温iのメモリ表示
 printf("%dl", i);

 // グラフ表示
 for (j = 0; j < 10; j++){
  if (kion[j] >= i){
   printf("*");
  }
  else{
   printf(" ");
  }
 }

 // 改行
 printf("\n");
}

一応、グラフまで表示できるようにしました。
ただし、このままでは、気温や日数の桁数が変わるとグラフががたがたになると思います。
質問者様がプログラミングの自己学習されているという判断でよいのでしょうか?
後は自力できれいな表示ができるようにがんばってください。

QVisial C++おけるπの使い方

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main(void){
int i,n,count=0;
double x,y,r,error;

srand((unsigned)time(NULL)); /*乱数の初期化*/

printf("How many trials?");
scanf("&d",&n);

for(i=0;i<n;i++){
x=rand()/(RAND_MAX+1.0);
y=rand()/(RAND_MAX+1.0);

if(y<sin(M_PI*x)){
count++;
}
}

r=(double)count/n; /*キャスト演算子を使用*/
error=2/M_PI-r;

printf("Result is %f (Error: %f)\n",r,error);

return 0;
}

自宅でCプログラミングの練習をするためVisial C++ 2008を使って
プログラムをしています。y<sin(πx)となった時の
割合などを計算するプログラムで                「M_PIが定義されていない識別子です」
とでてきます。所持している本を参考にしてもM_PI=πとして用いる
と書いてあり、math.hもインクルードしてるので原因が分からなくて
困ってます。Visial c++ではπの使い方には何か別の使い方がある
のでしょうか?よろしくお願いします。
*↓が実際に作ったプログラムです。
#include ...続きを読む

Aベストアンサー

★アドバイス
・math.hをインクルードする前に『_USE_MATH_DEFINES』定数を define します。

#define _USE_MATH_DEFINES
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int main( void )
{
 :
 return 0;
}
必ず include する前に定義して下さい。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング