Task:
A subset is a continuous segment of an array.
Two integer arrays are given with elements from 1 to 100: of N and n (N > n).
For every subset of the first array of n length find out the next thing:
Does this subset have the same values as in the second array? Order isn't important.
The method shouldreturn bool[]
. For clarity, the length of a returning array is equal to the number of subsets.Main attention to the
IsSubArray
methodExamples:
in the next examples false - f, true - tSecond array: 4 2 3 First array: 1 2 3 4 5 4 3 2 return array: f t f f f t
Second array: 1 2 3 5 1 7 6 5 7 1 First array: 6 5 7 1 return array: f f f t t f t
What have I tried
I've tried to solve this task in different ways and this is the fastest. In this use the second for
cycle to initialize the current subset and the third for
cycle to remove the same values. I did it with help of List<int>
data type.
My question
Is there another faster way to perform this task? Maybe any other ways to write for
cycles or use another check instead of currentSubArray.Remove
Code
using System; using System.Collections.Generic; using System.Text; using System.Linq; using ClassLibrary1; namespace ConsoleApp1 { class Program { static void Main(string[] args) { bool err = false; int[] firstArray = {1, 2, 3, 4, 5, 6, 7, 4, 8, 9, 10, 6, 4, 5, 7}; int[] secondArray = { 7, 5, 4, 6 }; bool[] expect = { false, false, false, true, true, false, false, false, false, false, false, true }; var actual = IsSubArray(firstArray, secondArray); Console.Write("Actual Elements : "); Print(actual); Console.Write("Expect Elements : "); Print(expect); Console.ReadKey(); } static void Print(bool[] array) { foreach (var e in array) Console.Write("{0}, ", e); Console.Write("\n"); } internal static bool[] IsSubArray(int[] firstArray, int[] secondArray) { bool[] isSubArray = new bool[firstArray.Length - secondArray.Length + 1]; for (int i = 0; i + secondArray.Length <= firstArray.Length; i++) { var currentSubArray = new List<int>(); for (int j = 0; j < secondArray.Length; j++) { currentSubArray.Add(firstArray[i + j]); } for (int k = 0; k < secondArray.Length; k++) { if (!currentSubArray.Contains(secondArray[k])) { isSubArray[i] = false; break; } else currentSubArray.Remove(secondArray[k]); } if (currentSubArray.Count == 0) { isSubArray[i] = true; } } return isSubArray; } } }
different ways and this is the fastest
How does it differ from the one most readable? How did you test?\$\endgroup\$string
orstringBuilder
too in theory but I don't believe they will be fast. "How does it differ from the one most readable?" My past variants weren't more readable. They were just slower. "How did you test?" the time check is arrays of 1000 length and of 100 length and repeated the test 1000 times. And then it's compared with their time limit.\$\endgroup\$