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

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

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

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

Q&A

解決済

4回答

6459閲覧

C#で、配列に配列が含まれているかどうか知りたいです。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

1クリップ

投稿2016/01/12 06:50

編集2016/01/12 08:32

Windows7 Pro, Visual Studio 2013 Expressの組み合わせで、Formアプリケーションを作っています。

配列に配列が含まれているかどうか知りたいです。
//検索元の配列
string[] array = new string[] { "red", "blue", "white", "blue", "red" };

ここからblue-whiteというならびを見つけたいです。

//"blue"の位置を取得する
int index1 = Array.IndexOf(array, "blue");
//index1は1

int index2 = Array.IndexOf(array, new string[]{"blue", "white"});
//index2は-1。

どうすればよいでしょう。

List<string>でも可能でしょうか?
よろしくおねがいします。

すこし書いてみました。

//検索元の配列
string[] array = new string[] { "red", "blue", "yellow", "pink", "green", "blue", "green" };

//"pink"の位置を取得する。3
int index1 = Array.IndexOf(array, "pink");

string[] subarray1 = new string[] { "blue", "yellow" };//成功する。1
string[] subarray2 = new string[] { "blue", "green" };//失敗する。-1
int indexarray1 = compareArray(array, subarray1);
int indexarray2 = compareArray(array, subarray2);

private int compareArray(string[] array, string[] subarray) {
int index = Array.IndexOf(array, subarray[0]);
bool IsSame = true;
if (0 < index) {
for (int i = 0; i < subarray.Length; i++, index++) {
if (array[index] != subarray[i]) IsSame = false;
}
}
if (!IsSame) return -1;
else return index-subarray.Length;
}

これを再帰的に実行すればよいのですが。こんな方向性でしょうか?

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

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

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

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

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

guest

回答4

0

ベストアンサー

やっつけました
効率他を考えるならまじめに実装してください

C#

1using System.Linq; 2using System.Collections.Generic; 3using System; 4 5public class TEST{ 6 public static void Main(){ 7 //検索元の配列 8 List<string> array = new List<string> { "red", "blue", "yellow", "pink", "green", "blue", "green", "blue", "red" }; 9 10 11 List<string> sub1 = new List<string> { "blue", "yellow" }; //ある 12 List<string> sub2 = new List<string> { "blue", "green" }; //ある 13 List<string> sub3 = new List<string> { "blue", "hoge" }; //ない 14 15 if(array.Any(sub1)) 16 Console.WriteLine("sub1"); 17 if(array.Any(sub2)) 18 Console.WriteLine("sub2"); 19 if(array.Any(sub3)) 20 Console.WriteLine("sub3"); 21 } 22} 23 24public static class IEnumerableExtensions 25{ 26 public static bool Any<T>(this IEnumerable<T> source, IEnumerable<T> target) 27 { 28 return source 29 .Select((x, i) => source.Skip(i).Take(target.Count()) ) 30 .Any(x=>x.SequenceEqual(target)); 31 } 32}

投稿2016/01/12 09:14

編集2016/01/12 09:18
ozwk

総合スコア13521

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

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

hsk

2016/01/13 03:52 編集

素晴らしいです...横から失礼しますが、LINQって気持ちよく書けるなぁとしみじみ感じました。 Select((x, i) =>).Skip(i).Take(target.Count()) ... で、おおもとの配列から1つずつ(配列の添字iを列挙して)、ずらしながら(i個分Skipしながら)、比較する配列と同じ長さの配列の配列を得て(Takeして) SequenceEqual() で、比較する配列と配列内各要素が一致しているかどうかをしらべて Any() で上記の比較で1つでも一致していれば trueを返すように しているのですね。 「拡張メソッド」(array.Any() のような、オブジェクト外部からオブジェクトにメソッドを追加するような記述方法)の記法は http://ufcpp.net/study/csharp/sp3_extension.html http://www.atmarkit.co.jp/fdotnet/bookpreview/kisokaracs_1101/kisokaracs_1101_01.html などに説明されています。 kaoruriderさんにとって釈迦に経の内容もあるかもしれませんが、ご容赦を。
退会済みユーザー

退会済みユーザー

2016/01/18 02:08

お返事遅くなりました。 先週は質問後、debugに忙殺されてしまいました。 ozwkさん、これはすごいです。 hskさんもおっしゃってますが、これは美しいコードです。 うっとりしました。 すごく幸せな気持ちになりました。 今日は東京では雪で、電車とか大変だったのですが、すっとびました。 いや、ほんとにきれいです。 viva! linqですね。 追加でお願いなのですが、現在boolを返してますけど、複数一致することもあるので、true/falseではなくて、List<int> startpoints を返すことは可能でしょうか? hskさん、買い被りです。かいかぶりって、かいつぶりに似てますけど、まだまだとてもこのコードをするっと理解する力はわたしにはないです。 hskさんの解説で、なるほどと納得しました。ozwkさんへの感謝とあわせて感謝を。 ありがとうございました。
aglkjggg

2016/01/19 02:02 編集

List<int>ではなく IEnumerable<int>ですが一応出来ました。 .Select(...).Where(...) あたりがあまり綺麗ではないので、あとはプロにお任せします http://ideone.com/XMqJsQ ※コメントにMarkdown記法は使えないのですね。。。
guest

0

配列から要素の特定の並び順を一発で検索するメソッドは残念ながらArrayやListに実装されていませんので、自分でロジックを実装する必要があります。

C#

1string[] array1 = new string[] {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}; 2string[] array2 = new string[] {"e", "f", "g"}; 3for (int i = 0; i + array2.Length < array1.Length; i++) { 4 bool find = true; 5 for (int j = 0; j < array2.Length; j++) { 6 if (array2[j] != array1[i + j]) { 7 find = false; 8 break; 9 } 10 } 11 if (find) { 12 Console.WriteLine("Find at " + i); 13 } 14}

例えばこんな感じになるのでは。
ご参考になれば。

投稿2016/01/12 08:44

tkanda

総合スコア2425

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

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

退会済みユーザー

退会済みユーザー

2016/01/12 08:55

ありがとうございます。 //検索元の配列 List<string> array = new List<string> { "red", "blue", "yellow", "pink", "green", "blue", "green", "blue", "red" }; //"pink"の位置を取得する。3 int index1 = Array.IndexOf(array.ToArray(), "pink"); List<string> subarray1 = new List<string> { "blue", "yellow" };//成功する。1 List<string> subarray2 = new List<string> { "blue", "green" };//成功する。5 List<string> subarray3 = new List<string> { "blue", "red" };//失敗する。-1 int indexarray1 = compareArray(array, subarray1); int indexarray2 = compareArray(array, subarray2); int indexarray3 = compareArray(array, subarray3); private int compareArray(List<string> array, List<string> subarray) { int index = Array.IndexOf(array.ToArray(), subarray[0]); bool IsSame = true; if (0 < index) { for (int i = 0; i < subarray.Count; i++, index++) { if (array[index] != subarray[i]) IsSame = false; } } if (!IsSame) { // n番目~m番目の要素を削除する array.RemoveRange(0, index - subarray.Count+1); int newindex = Array.IndexOf(array.ToArray(), subarray[0]); if (0 < newindex) return compareArray(array, subarray) + subarray.Count; else return -1; } else return index - subarray.Count; } 再帰で失敗しました。
tkanda

2016/01/12 09:02

大した処理ではない割に、いろいろ凝りすぎな気がします。 再帰とかはいったん忘れて、私が示したようにベタなループ処理にしたほうが可読性も高まって良いのでは。
退会済みユーザー

退会済みユーザー

2016/01/18 03:58

たしかに。凝りすぎて動きませんでした。
guest

0

以前こんなQ&Aがありましたのでこれもご参考に。
https://teratail.com/questions/20408
ここの回答にあるSunday法、もしご興味があれば解説します。

投稿2016/01/12 08:41

yuba

総合スコア5568

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

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

退会済みユーザー

退会済みユーザー

2016/01/12 08:56

とても参考になりました。ありがとうございます。
guest

0

投稿2016/01/12 08:34

aglkjggg

総合スコア769

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

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

退会済みユーザー

退会済みユーザー

2016/01/12 08:56

とても参考になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問