質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1422閲覧

行列の値を正しい結果に直したいです。

Jhon_McClane

総合スコア48

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/07/01 16:48

編集2020/07/02 02:23

前提・実現したいこと

私の質問欄の1つ前の質問の続きです。
取り除く行及び列を指定するのですが、指定する数が2つ以上になると
正しい結果が返ってきません。結果を記述します。
0と1を指定したのにもかかわらず、結果から推定するに0と2を指定したかのような結果になっています。
原因が突き止められないため質問しました。

該当のソースコード

#include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_MAX 256 /* rows行×cols列の行列をプリントする */ void print(int **mtx, int rows, int cols) { int row, col; for ( row = 0; row < rows; ++row) { for ( col = 0; col < cols; ++col ) { printf("%d ", mtx[row][col]); } printf("\n"); } printf("\n"); } /* rows行×cols列の行列から target_row行を削除する */ void erase_row(int **mtx, int rows, int cols, int target_row) { int row, col; for ( row = target_row; row < rows-1; ++row ) { for ( col = 0; col < cols; ++col ) { mtx[row][col] = mtx[row+1][col]; } } } /* rows行×cols列の行列から target_col列を削除する */ void erase_col(int **mtx, int rows, int cols, int target_col) { int row, col; for (row = 0; row < rows; ++row) { for (col = target_col; col < cols-1; ++col) { mtx[row][col] = mtx[row][col+1]; } } } int main( int argc, char *argv[] ) { int i, j; int N; int **org_adjacent; int **new_adjacent; int n1, n2; FILE *fp; char fn[NAME_MAX]; int delete[2]={0,1}; if ( argc != 2 ) { fprintf( stderr, "Usage: %s graph_file\n", argv[0] ); exit( 1 ); } strcpy( fn, argv[1] ); if (( fp = fopen( fn, "r" )) == NULL ) { fprintf( stderr, "File open error %s\n", fn ); exit( 1 ); } //ファイルの先頭を読み取り行列の大きさを取得する fscanf( fp, "%d", &N ); org_adjacent = (int **)malloc(sizeof(int *)*N); new_adjacent = (int **)malloc(sizeof(int *)*N); for(i=0;i<N;i++){ org_adjacent[i] = (int *)malloc(sizeof(int)*N); new_adjacent[i] = (int *)malloc(sizeof(int)*N); } for(i=0;i<N;i++) for(j=i;j<N;j++) org_adjacent[i][j] = org_adjacent[j][i] = 0; while( fscanf( fp, "%d %d", &n1, &n2 ) != EOF ) { org_adjacent[n1][n2]++; org_adjacent[n2][n1]++; } for(i=0;i<N;i++) for(j=0;j<N;j++) new_adjacent[i][j] = org_adjacent[i][j]; print(new_adjacent,N,N); int rows = N; int cols = N; erase_row(new_adjacent, rows, cols, delete[0]); --rows; erase_row(new_adjacent, rows, cols, delete[1]); --rows; erase_col(new_adjacent, rows, cols, delete[0]); --cols; erase_col(new_adjacent, rows, cols, delete[1]); --cols; print(new_adjacent, rows, cols); for(i=0;i<N;i++){ free(org_adjacent[i]); free(new_adjacent[i]); } free(org_adjacent); free(new_adjacent); return 0; }

結果

元の行列

0 1 1 1 0 1 1 1 1 0 1 0 1 1 0 0 1 1 0 1 0 1 0 0 1 0 1 0 1 0 0 0 0 1 0 1 0 1 0 0 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 1 0

0行目、1行目、0列目、1列目を取り除く
期待する結果

0 1 0 1 0 0 1 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

自分のプログラムを実行した結果

0 0 1 1 0 0 0 0 1 0 0 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 0 1 0 1 0 0 0 1 1 0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/07/01 21:58

大きいほうから順に削除しないとズレるのは当然ちゃう?
Jhon_McClane

2020/07/02 02:01

意外と単純なことに気がつきませんでした。ありがとうございます。
episteme

2020/07/02 02:37

あるいはどんな順で削除してもいいけど、 「とある行/列を削除したら、それより大きい残りのヤツはみんな-1」せんと。
Jhon_McClane

2020/07/05 15:10

行列の処理手順について勉強になりました。ありがとうございます。
guest

回答2

0

ベストアンサー

大きい値の行または列を先に削除するとよいでしょう。
例えば、2 と 5 を削除する場合、5 を削除してから 2 を削除する。

投稿2020/07/02 00:06

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jhon_McClane

2020/07/02 02:00

できました。ありがとうございます。
guest

0

行だけに注目し, 0行目と1行目を削除することにします。
元の行列

text

10 1 1 1 0 1 1 1 ←削除 21 0 1 0 1 1 0 0 ←削除 31 1 0 1 0 1 0 0 41 0 1 0 1 0 0 0 50 1 0 1 0 1 0 0 61 1 1 0 1 0 1 1 71 0 0 0 0 1 0 1 81 0 0 0 0 1 1 0

0行目削除後

text

11 0 1 0 1 1 0 0 21 1 0 1 0 1 0 0 31 0 1 0 1 0 0 0 40 1 0 1 0 1 0 0 51 1 1 0 1 0 1 1 61 0 0 0 0 1 0 1 71 0 0 0 0 1 1 0

ここまでは思い通りだと思いますが、
1行目削除は、今のコードだと元の行列ではなく、「0行目削除のあとの行列」から1行目を削除することになります。
したがって、以下に示す行を削除します。

0行目削除後の行列

text

11 0 1 0 1 1 0 0 21 1 0 1 0 1 0 0 ←削除 31 0 1 0 1 0 0 0 40 1 0 1 0 1 0 0 51 1 1 0 1 0 1 1 61 0 0 0 0 1 0 1 71 0 0 0 0 1 1 0

結果的には元の行列の2行目にあたる行が削除されることになります。
0行目を削除したことによって元の行列の1行目がずれてしまっているので、例えば、ずれた分を補正するとか色々解決策はあるのかなと思います。

投稿2020/07/01 17:21

編集2020/07/01 17:26
Penpen7

総合スコア698

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jhon_McClane

2020/07/02 01:56

わかりやすい説明ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問