C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 39 を表示中)
■20074 / )  再帰によるスタックオーバーフロー?
□投稿者/ ヤナックス (1回)-(2008/06/05(Thu) 11:11:18)

分類:[C#] 

以下のようなテーブルがあります。(実際は数万件程度)

<親コード> <子コード> <年> <月>
 AAA    BBB    2008  6
 BBB    CCC    2008  6
 CCC    AAA    2008  6
 AAA    DDD    2008  6
 EEE    AAA    2008  6
 EEE    CCC    2008  6
 EEE    DDD    2008  6

上記表から上の3行のように親コードと子コードの関係がループするような
行を抜き出したいのでとりあえず処理を作ったのですが、
再帰処理の部分なのかスタックオーバーフローで落ちてしまいます。

落ちないようにする方法としてはどういう方法があるのでしょうか?
ご存知でしたらおおまかにでも構いませんので教えていただけないでしょうか?


以下ソースです。


    protected DataSet dtSet = new DataSet("XXX");
    protected string SerchTarget;

    private void button1_Click(object sender, EventArgs e)
    {


      OracleConnection OraConn = new OracleConnection();
      OracleDataAdapter OraDA;
      
      DataView dtView = new DataView();
      dtSet.Clear();
      dataGridView3.Rows.Clear();

      //〜DB接続やらなんやかんや〜

      for (int i = 0; i <= dtSet.Tables[0].Rows.Count - 1; i++)
      {

        SerchTarget = dtSet.Tables[0].Rows[i].ItemArray[1].ToString();

        if (checkloop(SerchTarget, dtSet.Tables[0].Rows[i].ItemArray[2].ToString(), int.Parse(dtSet.Tables[0].Rows[i].ItemArray[3].ToString())) == true)
        {
          //抜き出した行をグリッドに入れる
          wktable.ImportRow(dtSet.Tables[0].Rows[i]);
        }

      }
    }


    //再帰処理部分。
    private bool checkloop(string grp, string ffiscalyr, int fperiod)
    {

      int Row;
      string wkKOgrp;

      //パラメタで渡されたコードが親コードとしてもつ行の行数を取得。ない場合は-1
      Row = Find(dtSet, grp, ffiscalyr, fperiod, 0,int.Parse(dtSet.Tables[0].Rows.Count.ToString())-1);

      while (Row > -1)
      {
        wkKOgrp = dtSet.Tables[0].Rows[Row].ItemArray[1].ToString();

        //一番おおもとの比較値と比較
        if (SerchTarget == wkKOgrp)
        {
          return true;
        }
        else
        {
          //自身を再度呼び出す
          if(checkloop(wkKOgrp,ffiscalyr,fperiod) == false)
          {
            //現在の行数以降で、パラメタで渡されたコードが親コードとしてもつ行の行数を取得。ない場合は-1
            Row = Find(dtSet, grp, ffiscalyr, fperiod, Row + 1, dtSet.Tables[0].Rows.Count - 1);
          }
          else
          {
            return true;
          }
        }
      }

      return false;
    }

    //子コードが一致したデータの行数を返す関数
    private int Find(DataSet ds, string GRP, string ffiscalyr, int fperiod, int startrow, int endrow)
    {
      int i;

      for (i = startrow ; i <= endrow ; i++)
      {
        if ((ds.Tables[0].Rows[i].ItemArray[0].ToString() == GRP) && (ds.Tables[0].Rows[i].ItemArray[2].ToString() == ffiscalyr) && (int.Parse( ds.Tables[0].Rows[i].ItemArray[3].ToString()) == fperiod))
        {
          return i;
        }
      }

      return -1;
    }
返信 編集キー/


管理者用

- Child Tree -