![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
こちらのプログラム、もう少しわかりやすく書けないでしょうか?
というよりNは3だとして、for文を使わずに同じ計算過程を何回か書く、ようはfor文でまとめられる前?のようなプログラムにして頂けないでしょうか?
for文を使わないでプログラムを表したいです。ちなみに、for文を使わない場合変数k,i,jは定数として置かれるのでしょうか?
まぁ、場合分けをまとめたのがfor文だと思うのでfor文を使わないならば変数に定数が入ると思いますが。
どうかよろしくお願いします。
for (k = 0; k < N -1; k++) {
for (i = k + 1; i < N; i++) {
d = a[i][k] / a[k][k];
for (j = k + 1; j <= N; j++)
a[i][j] -= a[k][j] * d;
}
}
以下は全体のプログラムです。
/*********************************************
* 連立方程式の解法 ( ガウスの消去法 )
*********************************************/
#include <iostream> // for cout
#include <stdio.h> // for printf()
// 元の数定義
#define N 4 // 3
using namespace std;
/*
* 計算クラス
*/
class Calc
{
double a[N][N + 1];
// 各種変数
double d; // ダミー
int i, j, k; // LOOP インデックス
public:
// 連立方程式を解く(ガウスの消去法)
void calcGaussElimination();
};
/*
* 連立方程式を解く(ガウスの消去法)
*/
void Calc::calcGaussElimination()
{
// 係数
static double a[N][N + 1] = {
//{ 2.0, -3.0, 1.0, 5.0},
//{ 1.0, 1.0, -1.0, 2.0},
//{ 3.0, 5.0, -7.0, 0.0}
{ 1.0, -2.0, 3.0, -4.0, 5.0},
{-2.0, 5.0, 8.0, -3.0, 9.0},
{ 5.0, 4.0, 7.0, 1.0, -1.0},
{ 9.0, 7.0, 3.0, 5.0, 4.0}
};
// 元の連立方程式をコンソール出力
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++)
printf("%+fx%d ", a[i][j], j + 1);
printf("= %+f\n", a[i][N]);
}
// 前進消去
for (k = 0; k < N -1; k++) {
for (i = k + 1; i < N; i++) {
d = a[i][k] / a[k][k];
for (j = k + 1; j <= N; j++)
a[i][j] -= a[k][j] * d;
}
}
// 後退代入
for (i = N - 1; i >= 0; i--) {
d = a[i][N];
for (j = i + 1; j < N; j++)
d -= a[i][j] * a[j][N];
a[i][N] = d / a[i][i];
}
// 結果出力
for (k = 0; k < N; k++)
printf("x%d = %f\n", k + 1, a[k][N]);
}
/*
* メイン処理
*/
int main()
{
try
{
// 計算クラスインスタンス化
Calc objCalc;
// 連立方程式を解く(ガウスの消去法)
objCalc.calcGaussElimination();
}
catch (...) {
cout << "例外発生!" << endl;
return -1;
}
// 正常終了
return 0;
}
A 回答 (8件)
- 最新から表示
- 回答順に表示
No.8
- 回答日時:
う~ん、こういうのはどうでしょう。
前進消去の
for (j = k + 1; j <= N; j++)
を
for (j = 0; j <= N; j++)
に変えてみる。これでちゃんと動くので
前進消去が終わったところで
配列をダンプしてみる。
綺麗な上三角になっているはず。
行列の変化が教科書の通りになるので
前進消去がKひとつ分、つまり前進消去のー行分
でどう変化するか、デバッガやダンプで
追うのも良いでしょう。
No.5
- 回答日時:
#define N 4 なので
for (k = 0; k < N -1; k++){} のkは、0,1,2と変化する。
その中で
for (i = k + 1; i < N; i++){} のiは、k+1,k+2,…,N-1(=3)と変化する。
その中で
for (j = k + 1; j <= N; j++){} のjは、k+1,k+2,…、N(=4)と変化する。
従って一番内側のforの{}の中はk,i,jの値が以下の組み合わせで変化します。
k j i
0 1 1 ループ1回目
0 1 2 ループ2回目
0 1 3 ループ3回目
0 1 4 ループ4回目
0 2 1 ループ5回目
0 2 2 ループ6回目
0 2 3 ループ7回目
0 2 4 ループ8回目
0 3 1 ループ9回目
0 3 2 ループ10回目
0 3 3 ループ11回目
0 3 4 ループ12回目
1 2 2 ループ13回目
1 2 3 ループ14回目
1 2 4 ループ15回目
1 3 2 ループ16回目
1 3 3 ループ17回目
1 3 4 ループ18回目
2 3 3 ループ19回目
2 3 4 ループ20回目
各ループ時の k,i,jの値を式の中に当てはめてみればよろしいかと思います。
No.4
- 回答日時:
No.3です。
補足文を見ました。>どの順番でforが働いているのかわかりません。
次のプログラムを実行してみてください。これで順番ぐらいはわかるでしょう。
int i = -1, j = -1, k = -1;
for (i=0; i<3; i++) {
printf("for i: i=%d, j=%d, k=%d\n", i, j, k);
for (j=0; j<3; j++) {
printf("for j: i=%d, j=%d, k=%d\n", i, j, k);
for (k=0; k<3; k++) {
printf("for k: i=%d, j=%d, k=%d\n", i, j, k);
}
}
}
複雑なことを一足飛びにやろうとするから混乱するのだと思います。わからない部分を簡単な例題に置き換えて理解の助けにする、といった姿勢で臨むと、自己解決できるようになると思います。一見すごく面倒くさいことを繰り返すように思うかもしれませんが、次に類似の疑問がわいたときにこういった経験が必ず役に立ちます。
No.3
- 回答日時:
>ようはfor文でまとめられる前?のようなプログラムにして頂けないでしょうか?
こういうのは人にやってもらうのではなくて自分でするものです。人に作ってもらったところで何も理解したことになりません。自分でやるから意味があると思います。
こんな感じにやります。
x = 0;
for (i=0; i<3; i++) {
x += a[i];
printf("i=%d, x=%d\n", i, x);
}
ならば、
x = 0;
i = 0;
x += a[i];
printf("i=%d, a[i]=%d, x=%d\n", i, a[i], x);
i ++;
x += a[i];
printf("i=%d, a[i]=%d, x=%d\n", i, a[i], x);
i ++;
x += a[i];
printf("i=%d, a[i]=%d, x=%d\n", i, a[i], x);
// i++するとi<3に反するのでここで終わり
です。ここでは、forを忠実に再現するためi++としていますが、iにあたる部分に直接数値を書いても構わないと思います。
ご質問文ではforが入れ子になっていますが、やることは大差ありません。
No.2
- 回答日時:
えっと。
。。プログラム(ソフトウェア)を作る際は最初に設計をしましょう。
大切なのは処理手順を日本語(日常使っている母国語)で書き表すことです。
箇条書きを使ったり、何らかのチャート図をご存知したらそれを使って書き表します。
箇条書きの場合は単に、、、
(1) ...
(2) ...
(3) ...
というものではなく、条件分岐や繰り返し処理が明確に分かるよう、、、
(1) ...
(2) ...
1) ...
2) ...
(3) ...
といった構造を持った書き方をすると頭の中にある処理手順を正確に書きだしやすくなります。
コーディングはこれを使用するプログラミング言語に翻訳するだけの作業です。
ですので設計のかなりの部分は使用するプログラミング言語に依存せずに書ける場合が多いです。
ただし、通常の手続き型言語とオブジェクト指向言語ではモジュール(クラス)設計が異なりますので、そこを意識する部分は変わらざるを得ませんが。。。
ちなみに蛇足ですが、ソースコードの全ての行を1文字目から書くと処理構造が大変わかりにくくなります。
if文やfor文などの構造(=処理範囲ですね)がわかるようタブを上手に使うと後から読みやすくデバッグもしやすいです。
コーディングルールを作って統一されるとよいです。
参考まで。
No.1
- 回答日時:
>こちらのプログラム、もう少しわかりやすく書けないでしょうか?
何をもって「わかりやすい」かは意見の分かれるところですが、
>for文を使わずに同じ計算過程を何回か書く
ことは可能でしょう
>プログラムにして頂けないでしょうか?
ご自分のハンドコーディングで展開されればよろしいかと
>for文を使わない場合、
>k=0のときi=1など、k=0のときi=2など場合分けと地道な計算のプログラムになると思いますが、
>以上のような地道な計算が見たいです。
ご自由に。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- C言語・C++・C# LU分解法のピボット選択機能実装について(C言語・gcc-9) 1 2022/07/22 15:20
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
do-while文が禁止される理由
-
ループを途中で抜けたいのですが。
-
入力した文字列から母音だけを...
-
入力した数値を倍々するプログラム
-
VBScriptでSQLに接続し、CSV出...
-
Cプログラムが終了しない
-
C言語forループが完結した場合...
-
For文の終了値を関数にしても問...
-
ループの特定入力終了
-
エクセルでC言語のfor文と同じ...
-
エクセルVBAで Do While (1)って?
-
if文の中にfor文なのか、for文...
-
こちらのプログラム、もう少し...
-
if文を使わずに奇数・偶数を判断
-
フラッシュ暗算
-
break文でループを一気に抜ける...
-
ゲームオーバーのプログラム
-
Enterキーを押されたら次の処理...
-
C言語での引数の省略方法
-
2÷3などの余りについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
break文でループを一気に抜ける...
-
ループを途中で抜けたいのですが。
-
入力した文字列から母音だけを...
-
do-while文が禁止される理由
-
入力した数値を倍々するプログラム
-
C言語forループが完結した場合...
-
if文の中にfor文なのか、for文...
-
プログラミングC言語についての...
-
エクセルVBAで Do While (1)って?
-
For文の終了値を関数にしても問...
-
エクセルでC言語のfor文と同じ...
-
Delphiで・・・
-
ループの特定入力終了
-
UWSCにてある一定の動作を無限...
-
C言語、自己参照構造体のプログ...
-
C言語 数字を削除する関数
-
Cプログラムが終了しない
-
Excel VBAで年度をまたぐ期間の...
-
プログラムで関数は使わない方...
-
VBScriptでSQLに接続し、CSV出...
おすすめ情報
for文を使わない場合、
k=0のときi=1など、k=0のときi=2など場合分けと地道な計算のプログラムになると思いますが、
以上のような地道な計算が見たいです。
// 前進消去
for (k = 0; k < N -1; k++) {
for (i = k + 1; i < N; i++) {
d = a[i][k] / a[k][k];
for (j = k + 1; j <= N; j++)
a[i][j] -= a[k][j] * d;
}
}
において、forが3つありますが、どの順番でforが働いているのかわかりません。
二重まではわかるのですが、三重はさっぱりわかりません。
forの働きがわからないとk,i,jの変化がわからなくなります。
どうかよろしくお願いします。