2017-12-01 11 views
-1

パスは行インデックス80、列インデックス0から始まります。マップの他のエッジ(列インデックス199)へのパスを作成する必要があります。私は私が訪問した前のセルに戻ることはできません、私は現在のセルに隣接しているセルの比較を行う必要がありますが、私は列を戻すことはできません、私は前進しなければならないか、 "私は現在の列で、私は細胞間の違いの最小量を見つけることです。C#2次元配列の隣接値の比較

パスを表すには、上に移動した右を表す(/)、右に移動したことを表すために()、右に移動した( - )を格納する必要があります。 、または(|)を表して、私は上下に動いた。

私は、隣接するセルを比較する方法について確認していない。ここで

は、私がこれまで持っているものです。私は文があればカップルが必要だと思っていますが、私はそれを理解できませんでした。 パスを表す限り、私は本当に何を使うべきかわかりません。私は別の方法をそれらの文字を別の2D配列に格納しようとしましたが、動作させることができませんでした。

static void Main(string[] args) 
    { 
     string[,] path = new string[116, 200]; 
     short[,] map = arrayMethod(); 

     int rowIndex = 80; 
     int colIndex = 0; 
     int positionOfX = 0; 
     int positionOfY = 0; 
     short minValue = short.MaxValue; 

     while (colIndex != 199) 
     { 
      for (short l = -1; l < 2; l++) 
      { 
       for (short k = 0; k < 2; k++) 
       { 
        if (map[l+ rowIndex, k+colIndex] < minValue) 
        { 
         positionOfX = l; 
         positionOfY = k; 
         minValue = map[l, k]; 
        } 
       } 
      } 
     } 
    } 
    // Method to store data into 2d array 
    public static short[,] arrayMethod() 
    { 
     short[,] map = new short[116, 200]; 

     string fileName = "land.csv"; 
     StreamReader reader = new StreamReader(File.Open(fileName, 
    FileMode.Open)); 
     string nextLine; 
     int partsCounter = 0; 
     while ((nextLine = reader.ReadLine()) != null) 
     { 
      string[] parts = nextLine.Split(','); 

      for (int cols = 0; cols < 200; cols++) 
      { 
       map[partsCounter, cols] = Convert.ToInt16(parts[cols]); 
      } 
      partsCounter++; 
     } 
     return map; 
    } 
+0

スタックオーバーフローは、「私のために」コード作成サイトではありません。 [この記事を読む](https://stackoverflow.com/help/how-to-ask) –

+0

誰かに私のためにそれをするように求めることはありません。私は助けを求めています。ありがとう。 –

+1

あなたが持っているコードに何が間違っているのか教えてください。 – john

答えて

0

は、パスの選択について、あなたが言う:私は、細胞間の差の最小量を求めています

私はそれに戻ってきます。各セルは、単純な数値比較であるべきであるアレイでshort、で表されることを考えると、隣接するセルを比較について


問題の核心は、私が信じているのは、隣接する細胞を見つけることです。

さて、あなたは2Dグリッドを持っている、とあなたが一つのセルの座標を持っている...

+-----+-----+-----+-----+ 
|  |  |  |  | 
+-----+-----+-----+-----+ 
|  |  |  |  | 
+-----+-----+-----+-----+ 
|  |  | x,y |  | 
+-----+-----+-----+-----+ 
|  |  |  |  | 
+-----+-----+-----+-----+ 

あなたは1で座標を変更することにより、隣接するセルを見つけることができます。

+-----+-----+-----+-----+ 
|  |  |  |  | 
+-----+-----+-----+-----+ 
|  |  |x,y-1|  | 
+-----+-----+-----+-----+ 
|  |x-1,y| x,y |x+1,y| 
+-----+-----+-----+-----+ 
|  |  |x,y+1|  | 
+-----+-----+-----+-----+ 

注意:原点が左上隅にあると仮定して座標を表現しています。これがコンピュータグラフィックスの標準的な取り決めです。あなたの場合は適用されないかもしれません。それにかかわらず、これらはあなたの隣接する細胞であり続けます。

我々は戻って前の列(列の数は常に増加しなければならない)私は、隣接する1つを無視することは安全だと思うに行くべきではない場合:

+-----+-----+-----+-----+ 
|  |  |  |  | 
+-----+-----+-----+-----+ 
|  |  |x,y-1|  | 
+-----+-----+-----+-----+ 
|  |  | x,y |x+1,y| 
+-----+-----+-----+-----+ 
|  |  |x,y+1|  | 
+-----+-----+-----+-----+ 

我々はこれを行うことができます

// the map 
short[,] map = arrayMethod(); 

// map dimensions 

int numRows = map.GetLength(0); 
int numCols = map.GetLength(1); 

// current position 
int rowIndex = 80; 
int colIndex = 0; 

while (colIndex < numCols - 1) 
{ 
    var current = map[rowIndex, colIndex]; 
    if (rowIndex > 0) 
    { 
     // We are not at the low row edge 
     var adjacent = map[rowIndex - 1, colIndex]; 
     Compare(current, adjacent); 
    } 
    if (rowIndex < numRows - 1) 
    { 
     // We are not at the high row edge 
     var adjacent = map[rowIndex + 1, colIndex]; 
     Compare(current, adjacent); 
    } 
    /*if (colIndex > 0) 
    { 
     // We are not at the low column edge 
     var adjacent = map[rowIndex, colIndex - 1]; 
     Compare(current, adjacent); 
    }*/ 
    if (/*colIndex < numCols - 1*/ true) 
    { 
     // We are not at the high column edge 
     var adjacent = map[rowIndex, colIndex + 1]; 
     Compare(current, adjacent); 
    } 
    // ... update rowIndex, colIndex 
} 

ifブロックが隣接セルの1つに対応するので、ここでは、ifを持っている理由は、我々はエッジでないかどうかをチェックする - 私は耳を前記のようにライアー - あなたが端にいれば、その方向に隣接するものはありません。

また、ifのコラムに戻るとコメントしました。私は最後の条件付きでコメントしました。つまり、whileがすでにそれをチェックしているからです。

私はCompareメソッドを使用して、あなたがやりたい比較を表現しています。それに戻ってきます。また、rowIndexcolIndexを更新していないことに気づいてください。上記の内容は無限ループです。これを修正するために、隣接するセルをリストとして扱うことをお勧めします。後でもっと簡単にすることができます。

補足:いいえ、リストは必要ありません。それはそれなしで行うことができますが、それはより多くの繰り返しにつながり、読みにくくなり、エラーを起こしやすくなります。

// the map 
short[,] map = arrayMethod(); 

// map dimensions 

int numRows = map.GetLength(0); 
int numCols = map.GetLength(1); 

// current position 
int rowIndex = 80; 
int colIndex = 0; 

while (colIndex < numCols - 1) 
{ 
    var current = map[rowIndex, colIndex]; 
    var adjacents = new List<Tuple</*row*/ short, /*column*/ short>>(); 
    if (rowIndex > 0) 
    { 
     adjacents.Add(Tuple.Create(rowIndex - 1, colIndex)); 
    } 
    if (rowIndex < numRows - 1) 
    { 
     adjacents.Add(Tuple.Create(rowIndex + 1, colIndex)); 
    } 
    adjacents.Add(Tuple.Create(rowIndex, colIndex + 1)); 
    foreach (var adjacent in adjacents) 
    { 
     Compare(map[adjacent.Item1, adjacent.Item2], current); 
    } 
    // ... update rowIndex, colIndex 
} 

今...

私は、細胞間の差の最小量を見つけることしています。

私は違いの絶対値として理解していますが、私はこれを最小限に抑えたいと推測しています(要件はそれほど明確ではありません)。

という理解の下で、我々は比較を実装することができます

foreach (var adjacent in adjacents) 
{ 
    var diff = Math.Abs(map[adjacent.Item1, adjacent.Item2] - current); 
} 

をそして、我々の目的地選択:今

Tuple<short, short> best; 
short bestDiff; 
foreach (var adjacent in adjacents) 
{ 
    var diff = Math.Abs(map[adjacent.Item1, adjacent.Item2] - current); 
    if (best == null || bestDiff > diff) 
    { 
     best = adjacent; 
     bestDiff = diff; 
    } 
} 
rowIndex = best.Item1; 
colIndex = best.Item2; 

を、付与された、あなたが列を戻ったり、バックにはなりません以前のセル。したがって、あなたは最後のポジションを把握しなければならないので、そのポジションをチェックしないでください。もちろん

// the map 
short[,] map = arrayMethod(); 

// map dimensions 

int numRows = map.GetLength(0); 
int numCols = map.GetLength(1); 

// current position 
int rowIndex = 80; 
int colIndex = 0; 

// old position 
int rowIndexOld = 80; 
int colIndexOld = -1; // <-- placing it outside the map 

while (colIndex < numCols - 1) 
{ 
    var current = map[rowIndex, colIndex]; 
    var adjacents = new List<Tuple<short, short>>(); 
    if (rowIndex > 0 && rowIndexOld != rowIndex - 1 && colIndexOld != colIndex) 
    { 
     adjacents.Add(Tuple.Create(rowIndex - 1, colIndex)); 
    } 
    if (rowIndex < numRows - 1 && rowIndexOld != rowIndex + 1 && colIndexOld != colIndex) 
    { 
     adjacents.Add(Tuple.Create(rowIndex + 1, colIndex)); 
    } 
    if (rowIndexOld != rowIndex && colIndexOld != colIndex + 1) 
    { 
     adjacents.Add(Tuple.Create(rowIndex, colIndex + 1)); 
    } 
    rowIndexOld = rowIndex; 
    colIndexOld = colIndex; 
    // etc 
} 

は、パスを選択すると、出力にそれを書くためにあなたのロジックを追加します。

正直言って、私は要件を十分に理解していません...なぜ、あなたは前方、上、下にしか動かすことができない場合、斜めの動きを表現する表記がありますか?とにかく、対角線あれば、それははるかに困難ではありません。

+-------+-------+-------+-------+ 
|  |  |  |  | 
+-------+-------+-------+-------+ 
|  |x-1,y-1| x,y-1 |x+1,y-1| 
+-------+-------+-------+-------+ 
|  | x-1,y | x,y | x+1,y | 
+-------+-------+-------+-------+ 
|  |x-1,y+1| x,y+1 |x+1,y+1| 
+-------+-------+-------+-------+ 

はあなたがそのためのコードをうまくすることができます確信している、同じのちょうどより多くです。それらは、チェックのためにさらに隣接していて、リストに追加するでしょう。

あなたが私よりも優れた要件を理解していただければ幸いです。


ヒント:

  • あなたは、マップ内の位置を表すためにタイプを使用することを検討することができます。あなたは行と列の変数のペアをたくさん使用しているので、その型を持つのが理にかなっています...私はちょうどTuple<short, short>を使っていますが、もっとうまくいくかもしれません。

  • 隣接が古い位置でないかどうかをチェックし、それをリストに追加するロジックをカプセル化したい場合があります。利点は、コードをより読みやすくし、エラーを起こしにくくすることです(例えば、隣接するものを間違ってチェックすることはありませんが、別のものを追加することは避けてください)。&ペーストで滑る可能性があります。


補遺:私は出力が文字列になると思います、そしてあなたがStringBuilderでそれを構築することができます。あなたが加えるキャラクターはあなたがどれを選ぶかによって決まります。隣接する座標と使用する文字の両方を保持している構造であれば、それを選択するともっと簡単になります。または、コンソールにパスを描く必要がありますか?それはまったく異なるものですから。

+0

ありがとうございました! 申し訳ありませんが、いくつかの要件が不明な場合は、パスは、上下左右、斜め方向(上下左右)に移動できます。 –

+0

私はタプルを全く知らない。我々は授業中にそれらについて何も学んでいない。 –