• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:共通の値をもつ座標の組み合わせについて)

共通の値を持つ座標の組み合わせについて

nag0720の回答

  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.10

#6~#8のプログラムにバグがありました。 パブリック変数の初期設定を充分にしていなかったので、エクセルを再起動せずに1の場所だけ変えて再実行してもうまくいかないようです。 バグ修正およびスピードアップした改良版です。 Option Explicit Option Base 1 Const SIZE = 10 Dim C(SIZE, SIZE) As Boolean Dim S(SIZE) As Integer Dim T(SIZE) As Integer Dim TCount As Integer Dim Count As Long Sub Combination() Dim i As Integer, j As Integer For i = 1 To SIZE For j = 1 To SIZE C(i, j) = 0 Next Next For i = 1 To SIZE - 1 For j = i + 1 To SIZE C(i, j) = Cells(i + 1, j + 1) C(j, i) = C(i, j) Next Next Worksheets("Sheet2").Select Count = 0 For i = 1 To SIZE - 1 TCount = 0 For j = i + 1 To SIZE If C(i, j) Then TCount = TCount + 1 T(TCount) = j End If Next S(1) = i AddCombin 1, 1 S(1) = 0 Next End Sub Sub AddCombin(n As Integer, k As Integer) Dim i As Integer, j As Integer, i0 As Integer, j0 As Integer Dim ExistNext As Boolean, CheckFlag As Boolean ExistNext = False For j = k To TCount CheckFlag = True For i = 2 To n If Not C(S(i), T(j)) Then CheckFlag = False Exit For End If Next If CheckFlag Then ExistNext = True S(n + 1) = T(j) AddCombin n + 1, j + 1 S(n + 1) = 0 End If Next If n = 1 Or ExistNext Then Exit Sub j0 = 1 For i0 = 1 To n For j = j0 To S(i0) - 1 CheckFlag = True For i = 1 To n If Not C(S(i), j) Then CheckFlag = False Exit For End If Next If CheckFlag Then Exit Sub Next j0 = S(i0) + 1 Next Count = Count + 1 For i = 1 To n Worksheets("Sheet2").Cells(Count + 1, i + 1) = S(i) Next Worksheets("Sheet2").Cells(Count + 1, 2).Select End Sub これをC言語にするとつぎのようになります。 #include <stdio.h> #define SIZE 10 void add_combin(int n, int k, char c_data[][SIZE], int s_data[], int t_data[], int *pt_count, long int *pcount, FILE *fp) { int exist_next = 0; for (int j = k; j < *pt_count; j++) { int check_flag = 1; for (int i = 1; i < n; i++) { if (c_data[s_data[i]][t_data[j]] == 0) { check_flag = 0; break; } } if (check_flag == 1) { exist_next = 1; s_data[n] = t_data[j]; add_combin(n + 1, j + 1, c_data, s_data, t_data, pt_count, pcount, fp); s_data[n] = 0; } } if (n == 1 || exist_next == 1) return; int j0 = 0; for (int i0 = 0; i0 < n; i0++) { for (int j = j0; j < s_data[i0]; j++) { int check_flag = 1; for (int i = 0; i < n; i++) { if (c_data[s_data[i]][j] == 0) { check_flag = 0; break; } } if (check_flag == 1) return; } j0 = s_data[i0] + 1; } (*pcount)++; printf("%d\n", *pcount); fprintf(fp, "%d", s_data[0] + 1); for (int i = 1; i < n; i++) fprintf(fp, " %d", s_data[i] + 1); fprintf(fp, "\n"); } void main() { char c_data[SIZE][SIZE]; int s_data[SIZE]; int t_data[SIZE]; int t_count; long int count = 0; char str[256]; FILE *fp; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) c_data[i][j] = 0; c_data[i][i] = 1; } fp = fopen("data.txt", "r"); for (int i = 0; i < SIZE - 1; i++) { fgets(str, 256, fp); for (int j = i + 1; j < SIZE; j++) { if (str[j - i - 1] == '1') { c_data[i][j] = 1; c_data[j][i] = 1; } } } fclose(fp); fp = fopen("out.txt", "w"); for (int i = 0; i < SIZE - 1; i++) { t_count = 0; for (int j = i + 1; j < SIZE; j++) { if (c_data[i][j] == 1) t_data[t_count++] = j; } s_data[0] = i; add_combin(1, 0, c_data, s_data, t_data, &t_count, &count, fp); s_data[0] = 0; } fclose(fp); } セルが使えませんので、表データと組み合わせ結果はファイルになります。 表データは次のようなファイルにしてください。 ファイル名は、data.txt ファイル内容は、表の右上の三角の領域の部分を、行ごとに0,1をつなげた文字列にしてください。 例えば、質問の図の10×10の場合は、 100101100 00101000 0001000 101000 01101 0000 110 11 0 というように、9行のデータファイルになります。 (112×112の表なら、111行のデータファイルになります) 組み合わせ結果はout.txtに出力されます。 実行中はコンソールに件数が表示されます。 上記のプログラムは標準的なCのコードです。 お使いのコンパイラによっては変更すべき点もあると思いますので、適宜修正してください。 本来なら、エラー処理をしたり、SIZEを可変にしたりすべきでしょうが、長くなるので割愛しています。 必要なら御自分で組み込んでください。

jugyou1
質問者

お礼

再度のアドバイスありがとうございます。 上述のC言語のコードをVisual Studio 2008のC++、win32コンソールにて入力後、ビルドしましたらexeファイルができました。exeファイルをdosモードで起動data.txtファイルを読み込ませようとしました(方法は、ローカルディスク(D:)にexeファイルおよびdata.txtファイルを入れまして、dosモードにて、d:\>program.exeと入力しました)がout.txtが出力されなくてどのようにすればいいか困ってしまいました。exeファイルの起動方法もしくはexeファイルの作成の工程についてアドバイスをいただけたら幸いです。 (初歩的な質問になりまして申し訳ありません。お時間あるときに教えていただけるとありがたいです) また、VBAのコードを112×112で実行しましたら約3時間程度かかりまして処理が完了しました。プログラムのすごさを実感しました。改めてお礼申し上げます。

関連するQ&A

  • エクセルVBAでVLookupを使って値を転記する

    エクセル2003で商品の一覧表を作成しています。 Sheet1は商品一覧(左図) Sheet2は価格表(右図)となっています。 マクロを使用して、Sheet1のB列に価格表のデータを転記させたいと考えています。 VLookupになるのかと思い、自分でいろいろとやってみたのですが、 どうしても動作せず、挫折してしまいました。 商品一覧の最後の行までいって、空白セルがくると止まるというのが、 難しくてできませんでした。 どうかお願いいたします。

  • 2つの数字の組み合わせに対応する文字を返すコードを教えてください。

    すみませんがお知恵を拝借させてください。下のような表で,B列の値に0~3,C列の値に0~3のいずれかを入れたとき,2つの数字の組み合わせに対応するA列にある名前を返すコードを教えていただけませんか。  例えば,B列の値=2,C列の値=0のとき,「酒井」と出力したいのですが。 ※2つの数字の組み合わせに重複はありません。範囲は下に書いた10名分のみです。よろしくお願いいたします。  ----------------------------------------- B列の値:_ C列の値:_ A列  B列  C列 ------------------- 大田  3   0 酒井  2   0 三宅  2   1 坂下  1   0 原田  0   0 山内  0   1 山口  1   1 相馬  1   2 渡辺  0   2 安藤  0   3

  • 選択した行の値だけを合計

    選択した行の値だけを、その行のどのセルをダブルクリックしても合計する方法を教えてください。 A列は、ID,B・C列は値があらかじめ入力されています。 D列に、合計を表示させたいです。 関数・VBAでは、一括して合計はでましたが、VBAで必要な行だけの合計の出し方がわかりません。 VBAの勉強のために活かしたいく、よろしくお願いします。

  • エクセルVBAでのまとめ計算

     初めまして、よろしくお願いします。 データーで    A      B     C     D      E ・・・ 1              5     7      2 2              3     7      0 3 4              6     3      6 5              2     8      3 6              0     3      4 ・     ・      ・      ・      ・ ・     ・      ・      ・      ・ 100             3     4      5 という表がありますA列には(C列の値/(D列以降の平均値))をB列には(C列の値-(D列以降の平均値))を表示させたいと思います。たまに3行のような空白の行があります。関数式ではなく、VBAで解る方、よろしくお願いします。

  • 組合せVBA

    環境はExcel2002です A列に連番数字1から100が入力されていて B列の100行には数字のデータがあるとします ある目的の数値Xに一番近くなるB列の組合せをC列に表示したいのです…VBAで B列に表示するのはA列の連番です 『一番近くなる』の意味は2通りあって、両方の算出方法をご教示願います (1)目的の数値Xを絶対超えないで目的の数値Xに一番近くなる組合せ (2)目的の数値Xを必ず超えて目的の数値Xに一番近くなる組合せ

  • エクセル 値が一致しないものを見つけたい

    お世話になります。 エクセルでA列B列にそれぞれ数値が入っている表があり、A列にはあってB列にはない数値を分かるようにしたいと思っています。      A列  B列   C列 1行目  1   1 2行目  1   5 3行目  4   0   4 4行目  5   1    5行目  1   0   1 ・A1、A2、A5の値が1であるように、A・B列とも重複する数値が入ることがあります。 ・A列とB列の値は1対1で対応し、例えばA1がB1と対応するならA2はB4と対応します。 この表ではA3、A5に対応する値がB列にないので、C列にその値を表示させています。 ・一致しない数字を分かるようにする方法にこだわりはなく、例のようにC列に値や×を表示させる、A列に色をつける、一致するものがあった数値は削除する等、なんでも構いません。 お分かりになる方、どうぞよろしくお願いいたします。

  • 【エクセル】歯抜けの空白欄に上段と同じ値を入れたい

    エクセル(2010)で ある表に ところどころ空欄があり、 そこに上段と同じ値を入れたいです。 随時発生する作業のため マクロ(もしくはVBA)が組めればと考えておりますが、 初心者につき、ご教示いただけますでしょうか。 A列:項番 B列:大項目 C列:中項目 D列:小項目 E列:備考 ※1行目:項目名、2行目以降:値 という表で、 A列のナンバリング・D列の小項目 以外は 上と同じ扱いとなるため空欄となってしまっていますが、 アクセス(DB)に取り込むため、空欄の無い形にしたいのです。 ※ちなみに、A列・D列は空欄が無い状態=最終行以下は空白です。 よろしくお願い致します。

  • 【VBA】組み合わせの計算

    VBAにてランダム(適当)な値10個の中で1.5に近い組み合わせを探し、それ以外の値を隣の列に移動させたいのですが、方法がわかりません。 どなたか教えてください

  • Excel VBAにて座標読み込み・配置

    当方、Excel VBAに関しては全くのド素人でございます。 お客さんに頼まれて、次のことをやりたいのですが、どうしたらよいか途方に暮れています。 (-50,-50)~(50,50)までの2mピッチの合計2601個のxyz座標データ(txt)をSheetに読み込み。 A列=x B列=y C列=z そしてAD列・26行のセルを座標(0,0)として、セルにz値を展開したいのです。 横軸=x 縦軸=y BC列・1行が(50,50) E列・51行が(-50,-50) 以上のことをExcel VBAでやりたいのですが・・・ 可能でしょうか? 宜しくお願いします。

  • エクセルVBA 変数Aと変数Bの組み合わせに対応する値を返すコード

    ワークシート上に次の表があり,この表をもとにして,変数A(0~4)と変数B(0~4)の組み合わせに対応するC列の値を返すコードは,どう書いたらよいでしょうか。  例えば,変数Aのセルに●(4),変数Bのセルに▲(0)と入力したら,値のセルに■(5)と表示させたいのです。  どなたか教えていただけませんか。 A列  B列  C列  4   0   5  3   1   4  3   0   5  2   2   3  2   1   4  2   0   4  1   3   2  1   2   2  1   1   3  1   0   3  0   4   1  0   3   1  0   2   2  0   1   3  0   0   3 変数A:● 変数B:▲ 値:■