Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找两个数组之间的匹配序列(模式匹配)C#_C#_Arrays - Fatal编程技术网

查找两个数组之间的匹配序列(模式匹配)C#

查找两个数组之间的匹配序列(模式匹配)C#,c#,arrays,C#,Arrays,我有两个数组,一个是我正在比较的主数组,第二个数组有许多整数,它们的顺序可能会向右或向左移动,也可能包含默认值 此比较的结果(真/假)如下所示: x = -9; //unknown number int[] mainArray = new int[]{3,1,0,1}; int[] a = new int[]{x,x,x,x}; // true int[] b = new int[]{x,x,1,x}; // true int[] c = new int[]{x,x,1,0}; // tru

我有两个数组,一个是我正在比较的主数组,第二个数组有许多整数,它们的顺序可能会向右或向左移动,也可能包含默认值

此比较的结果(真/假)如下所示:

x = -9; //unknown number

int[] mainArray = new int[]{3,1,0,1};

int[] a = new int[]{x,x,x,x}; // true
int[] b = new int[]{x,x,1,x}; // true
int[] c = new int[]{x,x,1,0}; // true
int[] d = new int[]{x,x,1,0}; // true
int[] e = new int[]{x,3,1,0}; // true
int[] f = new int[]{1,3,1,0}; // true
int[] g = new int[]{3,1,0,x}; // true
int[] h = new int[]{3,1,1,0}; // false
int[] i = new int[]{x,1,1,x}; // false
int[] j = new int[]{0,1,1,x}; // false
int[] k = new int[]{3,1,x,x}; // true
如果序列存在于主数组中,那么搜索的方法是什么? 有两个问题我无法解决: 1) 数组可能会向右或向左移动,但即使移动,结果也是正确的 2) 在比较中跳过的x值


我最终做了很多if语句,但我确信这个问题是由其他人优雅地解决的。

想法:将输入转换为字符串并复制它,以便它包含移位变量:

{ 3, 1, 0, 1 } ==> ",3,1,0,1,3,1,0,1,"
将模式数组转换为正则表达式。每个
x
\d+
替换,表示一个或多个数字:

{ 3, 1, x, x } ==> ",3,1,\d+,\d+,"
然后比较

string inputAsString = String.Join(",", mainArray) + ",";
inputAsString = "," + inputAsString + inputAsString;

string pattern =
    "," + String.Join(",", input.Select(i => i == x ? @"\d+" : i.ToString())) + ",";

bool result = Regex.IsMatch(inputAsString, pattern);
其中
input
是一个数组
a
k


下面是一个版本,它告诉您数组的移位量。为此,我们对数字进行格式化,使它们具有相同的长度。这允许我们计算输入字符串中匹配位置的偏移量

const int x = -9; //unknown number

int[] mainArray = new int[] { 3, 1, 0, 1 };

int[][] inputs = new[]{ //        is match, shift
        new int[] { x, x, x, x }, // true    0
        new int[] { x, x, 1, x }, // true    1
        new int[] { x, x, 1, 0 }, // true    1
        new int[] { x, x, 1, 0 }, // true    1
        new int[] { x, 3, 1, 0 }, // true    1
        new int[] { 1, 3, 1, 0 }, // true    1
        new int[] { 3, 1, 0, x }, // true    0
        new int[] { 3, 1, 1, 0 }, // false
        new int[] { x, 1, 1, x }, // false
        new int[] { 0, 1, 1, x }, // false
        new int[] { 3, 1, x, x },  // true   1           
        //-------- all possible shifts:
        new int[] { 3, 1, 0, 1 },  // true   0 <=> -4          
        new int[] { 1, 3, 1, 0 },  // true   1 <=> -3          
        new int[] { 0, 1, 3, 1 },  // true   2 <=> -2          
        new int[] { 1, 0, 1, 3 },  // true   3 <=> -1            
};

const int digits = 3;
string format = new String('0', digits);
string inputAsString =
    String.Join(",", mainArray.Select(i => i.ToString(format))) + ",";
inputAsString = "," + inputAsString + inputAsString;
Console.WriteLine($"inputAsString = \"{inputAsString}\"");
foreach (int[] input in inputs) {
    string pattern =
        "," + String.Join(",", input.Select(i => i == x ? @"\d+" : i.ToString(format))) + ",";

    var match = Regex.Match(inputAsString, pattern);
    int shift = -match.Index / (digits + 1);
    if (shift <= -input.Length / 2) {
        shift += input.Length;
    }
    Console.WriteLine($"match = \"{match.Value}\", success = {match.Success}, index = {match.Index}, shift = {shift}");
}
constintx=-9//未知数
int[]mainArray=newint[]{3,1,0,1};
int[][]inputs=new[]{//is match,shift
新的int[]{x,x,x},//true 0
新int[]{x,x,1,x},//true 1
新int[]{x,x,1,0},//true 1
新int[]{x,x,1,0},//true 1
新的int[]{x,3,1,0},//true 1
新的int[]{1,3,1,0},//true 1
新的int[]{3,1,0,x},//true 0
新的int[]{3,1,1,0},//false
新的int[]{x,1,1,x},//false
新的int[]{0,1,1,x},//false
新的int[]{3,1,x,x},//true 1
//--------所有可能的转移:
新的int[]{3,1,0,1},//true 0-4
新int[]{1,3,1,0},//真1-3
新的int[]{0,1,3,1},//true 2-2
新的int[]{1,0,1,3},//true 3-1
};
常量整数位数=3;
字符串格式=新字符串('0',数字);
字符串输入字符串=
Join(“,”,mainArray.Select(i=>i.ToString(format)))+“,”;
inputAsString=“,”+inputAsString+inputAsString;
WriteLine($“inputAsString=\”{inputAsString}\”);
foreach(输入中的int[]输入){
字符串模式=
“,”+String.Join(“,”,input.Select(i=>i==x?@“\d+”:i.ToString(格式)))+“,”;
var match=Regex.match(输入字符串,模式);
int shift=-match.Index/(位数+1);

如果(shift如果我得到了正确的问题陈述,您可以尝试以下方法:

x = -9; //unknown number

int[] mainArray = new int[]{3,1,0,1};

int[] a = new int[]{x,x,x,x}; // true
int[] b = new int[]{x,x,1,x}; // true
int[] c = new int[]{x,x,1,0}; // true
int[] d = new int[]{x,x,1,0}; // true
int[] e = new int[]{x,3,1,0}; // true
int[] f = new int[]{1,3,1,0}; // true
int[] g = new int[]{3,1,0,x}; // true
int[] h = new int[]{3,1,1,0}; // false
int[] i = new int[]{x,1,1,x}; // false
int[] j = new int[]{0,1,1,x}; // false
int[] k = new int[]{3,1,x,x}; // true
类MyEqualityComparer:IEqualityComparer
{
私人特殊价值;
public MyEqualityComparer(int specialValue){this.specialValue=specialValue;}
公共布尔等于(整数x,整数y)
{
如果(y==specialValue)返回true;
返回x等于(y);
}
公共int GetHashCode(int obj)
{
返回obj.GetHashCode();
}
}
void Main()
{
int x=-9;//未知数
int[]mainArray=newint[]{3,1,0,1};
变量列表=新列表{
新的int[]{x,x,x},//true
新的int[]{x,x,1,x},//true
新的int[]{x,x,1,0},//true
新的int[]{x,x,1,0},//true
新的int[]{x,3,1,0},//true
新的int[]{1,3,1,0},//true
新的int[]{3,1,0,x},//true
新的int[]{3,1,1,0},//false
新的int[]{x,1,1,x},//false
新的int[]{0,1,1,x},//false
新的int[]{3,1,x,x},//true
};
var main repeated=mainArray.ToList();
main.AddRange(mainArray);
foreach(列表中的变量e)
{
foreach(可枚举.Range(0,mainArray.Length)中的变量i)
{
if(main repeated.Skip(i).Take(e.Count()).SequenceEqual(e,new MyEqualityComparer(x)))
{
Console.WriteLine(e.Aggregate(new StringBuilder(),(sb,s)=>(s==x?sb.Append(“x”):sb.Append(s)).Append(,”).ToString();//我们找到了一个匹配项
打破
}
}
}
}

Why
newint[]{x,x,x}
应返回
true
?请分享您尝试过的内容?第二个数组有许多整数,其顺序可能会向右或向左移位数字可以移位多少次?移位值是数组的长度。两个数组的长度相同。如果数组的长度为4,则4次移位。x是默认值条件,可能为此我可以使用if语句进行筛选。对于其他人,我可以在向右移动的同时迭代4次,并在每个项之间找到正确的序列。非常感谢您的帮助。是否可以演示如何在没有Linq:if(main repeated.Skip(I).Take(e.Count()).SequenceEqual的情况下编写此行(e,新MyEqualityComparer(x)))
SequenceEqual
几乎是我的核心或答案-如果你删除它,你将不得不编写更多的代码。这个LINQ的哪一部分不符合你的要求?谢谢你的回答。正则表达式是否也可以给出模式移位的次数?不,但它给出了字符串中的位置。如果你使用前导零对数字进行格式化,使它们具有相同的长度,然后您可以计算移位。例如,
String.Join(“,”,main数组,选择(i=>i.ToString(“000”)
。而不是取消调用
Regex.IsMatch
,您必须调用
Regex.Match
Regex.Matches
,以提供位置。