[英]How to compare two arrays of chars and see location?
示例:第一個序列 (A,B,C,D) 第二個序列 (X,A,Z,A,B,C,D,E,A)
第一個序列包含在 position 4 的第二個序列中,因為字母 A、B、C、D 出現的順序與第一個序列完全相同
char[] firstSequence = new char[] { 'A', 'B', 'C', 'D'};
char[] secondSequence = new char[] {'X','A','Z','A','B','C','D','E','A'}
筆記; 在撰寫此答案時,尚不清楚所討論的序列是 char 的 arrays。 這個答案為字符串或復雜類型的 collections 提供了更一般的建議。 對於 char 的 arrays,可以選擇不使用 string.Join 分隔符或使用帶有 char 數組的字符串構造函數的特定優化; 其他答案提到了這一點,所以我不會在這里重復
不太確定您如何存儲序列,但希望在這種情況下它們是可枚舉的:
string.Join(",", haystackCollection).Contains(string.Join(",", needleCollection));
我使用逗號作為分隔符,但您應該使用實際 collections 中從未出現過的字符
更完整的例子:
var haystackCollection = "XAZABCDEA".ToCharArray();
var needleCollection = "ABCD".ToCharArray();
bool result = string.Join(",", haystackCollection).Contains(string.Join(",", needleCollection));
僅當您的 collections 是相同長度的字符串時,這才是可靠的。 如果干草堆可能包含不同長度的字符串,則變得不可靠,因為{"AB","AC"}
的干草堆不包含{"B","A"}
的針,但此方法會報告它確實存在。
您可以通過在每個字符串連接操作的開頭和結尾放置分隔符來使其更好:
string s = ",";
(s+string.Join(s, haystackCollection)+s).Contains(s+string.Join(",", needleCollection)+s);
但此時完全切換方法可能會更好。 此外,如果您想知道它出現的索引,使用此字符串連接方法會有點棘手,因為您必須使用 IndexOf 然后反復減去每個元素的長度加上分隔符才能返回索引。 您最好使用循環代替:
int idx = 0;
while(idx < haystack.Length){
if(haystack[idx] == needle[0]){
int i = 1;
while(haystack[idx+i] == needle[i] && i<needle.Length)
i++;
if(i == needle.Length)
return idx; // you found the start of the needle
}
idx++;
}
在后一種方法中,我們開始在大海撈針中尋找針的第一個元素。 如果我們找到它,我們將啟動一個循環來檢查針的 rest。 只有當它在大海撈針中找到針頭時,該循環才會保持鑼聲。 如果循環提前停止,那么索引變量i
將不會一直遞增到針數組的長度,因此我們可以得出結論,如果變量i
確實等於針的長度,則針在大海撈針中的 position idx
要使這種方法奏效,您確實需要 collections 可被 Integer 索引,而不僅僅是可枚舉,除非您想變得更加復雜。 請記住,如果您使用 List 而不是 Array 那么它是 Count 而不是 Length
將您的 firstSequence 和 secondSequence 轉換為字符串,然后使用.Contains()
。
//Inputs
char[] firstSequence = new char[] { 'A', 'B', 'C', 'D'};
char[] secondSequence = new char[] {'X','A','Z','A','B','C','D','E','A'}
//Convert char array to string
string firstString = new string(firstSequence);
string secondString = new string(secondSequence);
//Use .Contains() to check string availability
bool isExist = secondString.Contains(firstString);
//Print message on console
Console.WriteLine(isExist ? "Sequence Exist" : "Sequence Not Exist");
//This will give you staring index of first string in second string i.e 3
//Next four will be your indexes that are 3, 4, 5, 6
if(isExist)
{
int startIndex = secondString.IndexOf(firstString);
Console.WriteLine(string.Join(", ", Enumerable.Range(startIndex , firstString.Length)));
}
結果:
Sequence Exist
3, 4, 5, 6
我不清楚你的問題,但如果你的意思是你想在另一個字符串中找到一個字符串的 position 你可以使用這個:
char[] firstSequence = new char[] { 'A', 'B', 'C', 'D'};
char[] secondSequence = new char[] {'X','A','Z','A','B','C','D','E','A'}
var firstString = new string(firstSequence);
var secondString = new string(secondSequence);
var positionIndex = secondString.IndexOf(fisrtString);
如果您只想測試firstSequence
項目以與 firstSequence 中相同的順序出現在secondSequence
中的firstSequence
,例如
{A, X, A, B, P, Q, D, A, C, D}
^ ^ ^ ^
A B C D
您可以嘗試Linq Aggregate
:在我們想要匹配的firstSequence
中有項目a
和index
,我們可以計算我們想要與secondSequence
中的下一個項目匹配的index
代碼:
using System.Linq;
...
bool contains = secondSequence.Aggregate(0,
(index, a) => (index >= firstSequence.Length) || (firstSequence[index] != a)
? index // match completed or nothing to macth
: index + 1) >= firstSequence.Length; // match next item
相同的想法,但如果所有firstSequence
必須在沒有中斷的情況下出現,則不同的Aggregate
:
{A, X, A, B, C, D, P, Q}
^ ^ ^ ^
A B C D
代碼:
using System.Linq;
...
bool contains = secondSequence
.Aggregate(0, (index, a) =>
index >= firstSequence.Length ? index // match found, do nothing
: firstSequence[index] == a ? index + 1 // can we match next item?
: firstSequence[0] == a ? 1 // restart and match the 1st item
: 0) // restart
>= firstSequence.Length; // Have we match all items?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.