我有两个数组,一个是我要比较的主数组,第二个数组有许多整数,它们的顺序可能向右或向左移动,并且还可能包含默认值。
此比较的结果(对/错)如下:
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)数组可能会向右或向左移动,但是即使将其移动,结果也为true 2)比较中跳过的x值
我最终做了很多if语句,但是我确信这个问题已经被其他人很好地解决了。
答案 0 :(得分:1)
想法:将输入转换为字符串并将其复制,以使其包含移位的变体:
{ 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}");
}
此版本还将一些测试输出写入控制台。
答案 1 :(得分:1)
如果我正确地获得了问题说明,则可以尝试执行以下操作:
class MyEqualityComparer : IEqualityComparer<int>
{
private int specialValue;
public MyEqualityComparer(int specialValue) {this.specialValue = specialValue;}
public bool Equals(int x, int y)
{
if (y == specialValue) return true;
return x.Equals(y);
}
public int GetHashCode(int obj)
{
return obj.GetHashCode();
}
}
void Main()
{
int x = -9; //unknown number
int[] mainArray = new int[] { 3, 1, 0, 1 };
var lists = new List<int[]> {
new int[] { x, x, x, x }, // true
new int[] { x, x, 1, x }, // true
new int[] { x, x, 1, 0 }, // true
new int[] { x, x, 1, 0 }, // true
new int[] { x, 3, 1, 0 }, // true
new int[] { 1, 3, 1, 0 }, // true
new int[] { 3, 1, 0, x }, // true
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
};
var mainRepeated = mainArray.ToList();
mainRepeated.AddRange(mainArray);
foreach (var e in lists)
{
foreach (var i in Enumerable.Range(0, mainArray.Length))
{
if (mainRepeated.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()); // we've got a match
break;
}
}
}
}