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

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

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

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

2808閲覧

c#で線形探索をしたいです。

naka1220

総合スコア15

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2018/04/11 14:58

編集2018/04/11 16:27

前提・実現したいこと

約1500行で10列のcsvファイルがあります。
csvファイルは、
ヘッダ
0.1 18.00 ・・・・
0.2 17.99 ・・・・
0.3 17.99 ・・・・
0.4 17.98 ・・・・
0.5 17.97 ・・・・
.
.
.
というような感じのテキストになっています。

このとき、各行の2列目の値を2行目から調べていって、2列目の値が、2行目2列目の値より0.02以上低い値の時の最初の行番号を取得したいです。
上記のcsvファイルの場合、5行目の行番号を取得したいです。

自分なりに調べたものの、うまくいきませんでした。

どうかご教授願えないでしょうか。よろしくお願い申し上げます。

該当のソースコード

c#

1public string[][] Data(string file) 2 { 3 char[] linedelimiter = { '\n' }; 4 char[] columndelimiter = { ' ' }; 5 6 List<string[]> ReadCSVList = new List<string[]>(); 7 8 using(StreamReader Sr = new StreamReader(file, Encoding.UTF8)) 9 { 10 Sr.ReadLine(); 11 while (!Sr.EndOfStream) 12 { 13 string[] ReadCSVLines = Sr.ReadToEnd().Split(linedelimiter); 14 foreach(string ReadCSVLine in ReadCSVLines) 15 { 16 string[] DataItem = ReadCSVLine.Split(columndelimiter); 17 if(DataItem.Length == 10) 18 { 19 ReadCSVList.Add(DataItem); 20 } 21 } 22 } 23 } 24 return ReadCSVList.ToArray(); 25 } 26 27public int GetLineNumber(string file) 28 { 29 int Notfound = -1; 30 31 double T = double.Parse(Data(file)[0][1]); 32 int Length = Data(file).Length; 33 34 for (int i = 1; i < Length; i++) 35 { 36 double X = double.Parse(Data(file)[i][1]); 37 if (X - T <= - 0.02) 38 { 39 return i; 40 } 41 } 42 return Notfound; 43 }

試したこと

ネットで調べはしたものの、-1しか値が返ってきません。

補足情報(FW/ツールのバージョンなど)

Visual Studio 2017 .NET Framework 4.6.1

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

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

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

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

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

Wind

2018/04/11 15:36

ちゃんと見て無いけども、Tにヘッダ行の値が入ってるってことは無いよね?
Zuishin

2018/04/11 16:22

Trim() とか RemoveEmptyEntries とか謎のメソッドやオプションを使ってるのでちゃんと読む気になれません。実際のデータがどんなものか知りませんがそれらを使わなければならないようなデータだと厄介です。
naka1220

2018/04/11 16:29

申し訳ありません。コードを修正いたしました。
guest

回答1

0

ベストアンサー

私は試しに以下のようなテキストを用意してみました。

a b c d e f g h i j
0.1 18.00 123 123 123 123 123 123 123 123
0.2 17.99 123 123 123 123 123 123 123 123
0.3 17.99 123 123 123 123 123 123 123 123
0.4 17.98 123 123 123 123 123 123 123 123
0.5 17.97 123 123 123 123 123 123 123 123

このテキストをファイルにして貴方のGetLineNumberメソッドに読み込ませると4が返ったので、少なくともこのテキストでは「-1しか返らない」という問題が再現しません。

問題の再現するテキストを一つ用意して貰えませんか?



ちなみにコーディング部分ですが、自分なら次のように書きます。

C#

1public int GetLineNumber2(string file) 2{ 3 //ヘッダを除く全行を読んで、2列目のデータだけ抜き出す。 4 var lines = File.ReadLines(file).Skip(1); 5 var datas = lines.Select(line => double.Parse(line.Split(' ')[1])).ToList(); 6 7 //最初のデータから0.02引いた値をしきい値としてメモ 8 var threshold = datas[0] - 0.02; 9 10 //データの中に、しきい値以下のものがあるかどうか検索 11 //(ただし最初のデータは検索から除く) 12 var idx = datas.FindIndex(1, data => (data <= threshold)); 13 14 if (idx < 0) 15 { 16 //ヒットしなかった。 17 return -1; 18 } 19 else 20 { 21 //ヒットしたので返す値について考える。 22 //データのインデックスがnのとき、ファイル内の行のインデックスはヘッダを考慮してn+1である。 23 //なのでidxに1を足して返せば良い。 24 return idx + 1; 25 } 26} 27

投稿2018/04/11 17:44

MagoCat

総合スコア86

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

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

naka1220

2018/04/12 01:34

データはお見せできないのでご了承いただきたいですが、ご回答にあるようなテキストです。ただ、行の最初と最後にスペースが入っていて、行によってスペースの数がまちまちだったりしますので、その前後のスペースを取り除きたいです。ラムダ式をあまり理解できていませんので、どうすれば良いかわかりません。ご教授願えないでしょうか
naka1220

2018/04/12 01:43

上記のコードですと、入力文字列の形式が正しくありませんとエラーが表示されます
sh_akira

2018/04/12 07:53

横から失礼します。 回答者はエスパーではありません。あなたの質問文に対し、この回答は完璧です。 回答者はエスパーではありませんので、あなたのデータがどうなっているか知りません。 知らないものに回答はできません。 指摘された際に、TrimとRemoveEmptyEntriesを消したのはなぜですか? 必要なのはたまに行先頭と終端にスペースが入る場合があり、Trimが必要で、 さらに空行が入っている場合があるので、RemoveEmptyEntriesを使っているという"説明"です。 回答者全員が要求しているのは、"問題が再現するデータ"です。誰も実際のデータなど見たくありません。 これではあんまりなので、編集前のコードから推測できる回答が以下です。 double.Parse(line.Split(' ')[1]) を double.Parse(line.Trim().Split(' ')[1]) ここがTrim()を入れる位置です。 空行の削除はいくつか方法がありますが、lines.Selectを lines.Where(line => !string.IsNullOrWhiteSpace(line)).Select このようにWhere文を挟んで取り除けます。 ただし、スペースを取り除くのも空行を消すのもあなたの元のコードでやっていますよね? それで-1が返るのであれば、お手上げです。再現するデータを用意してください。 特にあなたのコードでif(DataItem.Length == 10)ここが気になります。 空行、スペースだけでない説明していない壊れた行が含まれてるんじゃないですか?
naka1220

2018/04/12 08:22

ご指摘頂きありがとうございます。 今後、反省し質問する際には十分注意を払います。 私からも何点か反論したい点はありますが、あまり生産的ではないと思われますので控えます。 プログラム初心者の身ではありますが、今後もどうぞよろしくお願い申し上げます。
sh_akira

2018/04/12 09:12

naka1220さんの元のソースコードですが、Data(file)を呼ぶたびに1500行全部読み込みしなおすので、 気を付けてくださいね。仮に何百行と対象データが見つからないと、滅茶苦茶重くなります。 それでもうまくいかなければCSVファイルをテキストエディタで開いて、100行ずつやってみる等で 試すことをお勧めします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問