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

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

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

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

Q&A

解決済

5回答

1686閲覧

データを整理する際の二次元配列

peach

総合スコア13

C

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

0グッド

1クリップ

投稿2015/11/10 10:31

編集2015/11/10 11:27

2つの変数に対応するデータがある時、二次元の配列にしたいのですが、2つの変数の関数として出る値ではないため、どのようにしたらいいか困っております。
例として、
x y n

1 3000 0.52
1 4000 0.02
1 5000 0.38
2 3000 0.17
2 4000 0.21
2 5000 0.23
3 3000 0.14
.
.
.
5 5000 0.11

などという数値データを、
3000 4000 5000
1 0.52 0.02 0.38
2 0.17 0.21 0.23
3 0.14 ...
.
.
5
のような縦x横yに対応する値nの配列を組みたいと考えています。
前述のとおり、nがx,yの値から計算できるものではないので、n[i][j]をどのように記述してよいか分からずにおります。
このような場合に使える方法などがございましたら、教えて頂けるとありがたいです。

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

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

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

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

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

guest

回答5

0

回答にはまだ至っていませんが、土台となるコードをかいてみました。

c

1#include <stdio.h> 2#include <stdlib.h> 3 4typedef struct record { 5 int no; 6 int x; 7 double y; 8} RECORD; 9 10typedef struct { 11 int no; 12 double * y; 13} RECORD2; 14typedef struct { 15 int * col; 16 int col_size; 17 RECORD2 * row; 18 int row_size; 19} MAT; 20 21MAT * make_mat(RECORD * data, int data_size) { 22 MAT * ans = (MAT *)malloc(sizeof(MAT)); 23 ans->col_size = 0; 24 ans->row_size = 0; 25 26 // ダミー 27 ans->col_size = 3; 28 ans->col = (int*)malloc(ans->col_size * sizeof(int)); 29 for (int i = 0; i < ans->col_size; i++) { 30 ans->col[i] = i * 1000; 31 } 32 ans->row_size = 3; 33 ans->row = (RECORD2*)malloc(ans->row_size * sizeof(RECORD2)); 34 for (int i = 0; i < ans->row_size; i++) { 35 ans->row[i].no = i + 1; 36 ans->row[i].y = (double*)malloc(ans->col_size * sizeof(double)); 37 for (int j = 0; j < ans->col_size; j++) { 38 (ans->row[i]).y[j] = 0.2 * j + i; 39 } 40 } 41 return ans; 42} 43void show_mat(MAT * mat) { 44 printf("%-8s", " "); 45 for (int i = 0; i < mat->col_size; i++) { 46 printf("%-8d", (mat->col)[i]); 47 } 48 printf("\n"); 49 50 for (int i = 0; i < mat->row_size; i++) { 51 printf("%-8d", (mat->row)[i].no); 52 for (int j = 0; j < mat->col_size; j++) { 53 printf("%-8.2f", mat->row[i].y[j]); 54 } 55 printf("\n"); 56 } 57} 58 59int main() { 60 RECORD data[] = { 61 {1, 3000, 0.52}, 62 {1, 4000, 0.02}, 63 {1, 5000, 0.38}, 64 {2, 3000, 0.17}, 65 {2, 4000, 0.21}, 66 {2, 5000, 0.23}, 67 {3, 3000, 0.14} 68 }; 69 70 MAT * mat = make_mat(data, sizeof(data) / sizeof(RECORD*)); 71 show_mat(mat); 72}

実行結果

$ gcc 22.c $ ./a.out 0 1000 2000 1 0.00 0.20 0.40 2 1.00 1.20 1.40

make_mat() の中が今はダミーです。
ここをパラメータで渡ってきたデータを処理して、ans を生成するようにすれば完成するのですが。。。

投稿2015/11/10 14:24

katoy

総合スコア22324

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

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

peach

2015/11/10 14:42

構造体の理解が浅いので、時間がかかると思いますが、コード読ませていただきます。ありがとうございます!
guest

0

xがX個(1~X)、yの数がY個あるのであれば、ちょっと冗長ですが、
double n[X+1][Y];として領域確保し、
n[0][y]にyの各値を入れて、yが一致する列の値を取り出す方法は如何でしょうか?

ご提示されている例の場合、X=5, Y=3ですので、下記のイメージです。

C

1double n[5+1][3]= 2{ 3 {3000.0, 4000.0, 5000.0 }, 4 {0.52, 0.02, 0.38 }, 5 {0.17, 0.21, 0.23 }, 6 {0.14, ... }, 7 : : : 8 {..., 0.11 } 9};

doubleの一致チェックが必要になりますが、単純な==ではちょっと危ういので、ご注意下さい。
差の絶対値が十分に小さい時に一致と判断するのが、浮動小数点一致判定の定石です。

投稿2015/11/10 13:11

編集2015/11/10 13:32
Chironian

総合スコア23272

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

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

peach

2015/11/10 14:28

表記し損ねてしまいましたが、実際のデータはもっと数が増えてしまうので、今回は少し難しいかもしれませんが、初心者として、二次元配列はこのような書き方もあるのかと学べました!以後機会がある時に役立てます。ありがとうございました!
guest

0

ベストアンサー

x,y,nがどのような性質のものなのか判らないので、ズバリこれだというのは示せないのですが。

C++

1using RowItem = std::map<int, double>; 2using DataItems = std::map<int, RowItem>; 3 : 4 : 5DataItems items; 6items[x][y] = n;

とりあえず判る情報だけで組もうとすると、C++ならこんな感じですね。ただ、これを素のC言語で作るとなると……。

具体的な使用例などを示していただいて条件が限定できれば、Cでも簡単に実装する方法が見つかるかもしれません。

例えば、以下の条件ならより簡単に組むことができます。

① yは3000,4000,5000の3種類。
② 同じxには必ず①がセットになっている。つまり、xが同じデータが必ず3つ揃っている。
③ xは1から始まり、必ず1ずつ増える。
これらの条件に当てはまるなら、こんな感じでいけると思います。。

C

1int ydaya[3]; 2double items[/*xのデータ数*/][3]; 3 : 4 : 5ydata[0] = 3000; 6ydata[1] = 4000; 7ydata[2] = 5000; 8 9// ここから下をループで回してx,y,nのデータを設定します 10int i = x - 1; 11int j; 12for(j = 0; j < 3; j++) 13{ 14 if(y == ydata[j]) 15 break; 16} 17if(j >= 3) 18{ 19 // エラー処理 20} 21items[i][j] = n;

投稿2015/11/10 11:50

編集2015/11/10 14:18
catsforepaw

総合スコア5938

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

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

peach

2015/11/10 14:10

実際のデータ数は、x,yともにもっと多いのですが、おっしゃられている条件のように揃っているので問題ないと思われます。後半のコードで、さらにiについてもまわせば、それぞれに対応しているnが二次元的に並べられるのでしょうか。やってみます!
catsforepaw

2015/11/10 14:23

認識が合っていてよかったです。 > さらにiについてもまわせば、それぞれに対応しているnが二次元的に並べられるのでしょうか。 その通りですね。一応Cコード例の中にコメントを追記しました。 がんばってください。
guest

0

外しているかも知れませんが、yが1000単位で端数が無いなら
xとy/1000の最大値の配列(double n[max_x][max_y])を取ったらダメでしょうか?

投稿2015/11/10 11:15

cateye

総合スコア6851

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

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

0

Cじゃないとダメでしょうか?
C++が使用可能なら、std::mapで連想配列にできると解決できそうです。

投稿2015/11/10 10:46

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

peach

2015/11/10 11:09

私自身Cしか使ったことがなく、プログラムのその他の部分もCで書いてあるので、Cでやり方が分かると嬉しいです。 ++だとそんな便利な配列があるのですね! Pythonでも配列にするのは簡単な様なのですが…。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問