I need to "Find the minimal positive integer not occurring in a given sequence. "
A[0] = 1
A[1] = 3
A[2] = 6
A[3] = 4
A[4] = 1
A[5] = 2, the function should return 5.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
I wrote the code in codility, but for many cases it did not worked and the performance test gives 0 %. Please help me out, where I am wrong.
class Solution {
public int solution(int[] A) {
if(A.Length ==0) return -1;
int value = A[0];
int min = A.Min();
int max = A.Max();
for (int j = min+1; j < max; j++)
{
if (!A.Contains(j))
{
value = j;
if(value > 0)
{
break;
}
}
}
if(value > 0)
{
return value;
}
else return 1;
}
}
The codility gives error with all except the example, positive and negative only values.
Edit: Added detail to answer your actual question more directly.
"Please help me out, where I am wrong."
In terms of correctness: Consider A = {7,2,5,6,3}. The correct output, given the contents of A, is 1, but our algorithm would fail to detect this since A.Min() would return 2 and we would start looping from 3 onward. In this case, we would return 4 instead; since it's the next missing value.
Same goes for something like A = {14,15,13}. The minimal missing positive integer here is again 1 and, since all the values from 13-15 are present, the value variable will retain its initial value of value=A[0] which would be 14.
In terms of performance: Consider what A.Min(), A.Max() and A.Contains() are doing behind the scenes; each one of these is looping through A in its entirety and in the case of Contains, we are calling it repeatedly for every value between the Min() and the lowest positive integer we can find. This will take us far beyond the specified O(N) performance that Codility is looking for.
By contrast, here's the simplest version I can think of that should score 100% on Codility. Notice that we only loop through A once and that we take advantage of a Dictionary which lets us use ContainsKey; a much faster method that does not require looping through the whole collection to find a value.
using System;
using System.Collections.Generic;
class Solution {
public int solution(int[] A) {
// the minimum possible answer is 1
int result = 1;
// let's keep track of what we find
Dictionary<int,bool> found = new Dictionary<int,bool>();
// loop through the given array
for(int i=0;i<A.Length;i++) {
// if we have a positive integer that we haven't found before
if(A[i] > 0 && !found.ContainsKey(A[i])) {
// record the fact that we found it
found.Add(A[i], true);
}
}
// crawl through what we found starting at 1
while(found.ContainsKey(result)) {
// look for the next number
result++;
}
// return the smallest positive number that we couldn't find.
return result;
}
}
The simplest solution that scored perfect score was:
public int solution(int[] A)
{
int flag = 1;
A = A.OrderBy(x => x).ToArray();
for (int i = 0; i < A.Length; i++)
{
if (A[i] <= 0)
continue;
else if (A[i] == flag)
{
flag++;
}
}
return flag;
}
Fastest C# solution so far for [-1,000,000...1,000,000].
public int solution(int[] array)
{
HashSet<int> found = new HashSet<int>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] > 0)
{
found.Add(array[i]);
}
}
int result = 1;
while (found.Contains(result))
{
result++;
}
return result;
}
A tiny version of another 100% with C#
using System.Linq;
class Solution
{
public int solution(int[] A)
{
// write your code in C# 6.0 with .NET 4.5 (Mono)
var i = 0;
return A.Where(a => a > 0).Distinct().OrderBy(a => a).Any(a => a != (i = i + 1)) ? i : i + 1;
}
}
A simple solution that scored 100% with C#
int Solution(int[] A)
{
var A2 = Enumerable.Range(1, A.Length + 1);
return A2.Except(A).First();
}
public class Solution {
public int solution( int[] A ) {
return Arrays.stream( A )
.filter( n -> n > 0 )
.sorted()
.reduce( 0, ( a, b ) -> ( ( b - a ) > 1 ) ? a : b ) + 1;
}
}
It seemed easiest to just filter out the negative numbers. Then sort the stream. And then reduce it to come to an answer. It's a bit of a functional approach, but it got a 100/100 test score.
Got an 100% score with this solution:
https://app.codility.com/demo/results/trainingUFKJSB-T8P/
public int MissingInteger(int[] A)
{
A = A.Where(a => a > 0).Distinct().OrderBy(c => c).ToArray();
if (A.Length== 0)
{
return 1;
}
for (int i = 0; i < A.Length; i++)
{
//Console.WriteLine(i + "=>" + A[i]);
if (i + 1 != A[i])
{
return i + 1;
}
}
return A.Max() + 1;
}
JavaScript solution using Hash Table with O(n) time complexity.
function solution(A) {
let hashTable = {}
for (let item of A) {
hashTable[item] = true
}
let answer = 1
while(true) {
if(!hashTable[answer]) {
return answer
}
answer++
}
}
The Simplest solution for C# would be:
int value = 1;
int min = A.Min();
int max = A.Max();
if (A.Length == 0) return value = 1;
if (min < 0 && max < 0) return value = 1;
List<int> range = Enumerable.Range(1, max).ToList();
List<int> current = A.ToList();
List<int> valid = range.Except(current).ToList();
if (valid.Count() == 0)
{
max++;
return value = max;
}
else
{
return value = valid.Min();
}
Considering that the array should start from 1 or if it needs to start from the minimum value than the Enumerable.range should start from Min
MissingInteger solution in C
int solution(int A[], int N) {
int i=0,r[N];
memset(r,0,(sizeof(r)));
for(i=0;i<N;i++)
{
if(( A[i] > 0) && (A[i] <= N)) r[A[i]-1]=A[i];
}
for(i=0;i<N;i++)
{
if( r[i] != (i+1)) return (i+1);
}
return (N+1);
}
My solution for it:
public static int solution()
{
var A = new[] { -1000000, 1000000 }; // You can try with different integers
A = A.OrderBy(i => i).ToArray(); // We sort the array first
if (A.Length == 1) // if there is only one item in the array
{
if (A[0]<0 || A[0] > 1)
return 1;
if (A[0] == 1)
return 2;
}
else // if there are more than one item in the array
{
for (var i = 0; i < A.Length - 1; i++)
{
if (A[i] >= 1000000) continue; // if it's bigger than 1M
if (A[i] < 0 || (A[i] + 1) >= (A[i + 1])) continue; //if it's smaller than 0, if the next integer is bigger or equal to next integer in the sequence continue searching.
if (1 < A[0]) return 1;
return A[i] + 1;
}
}
if (1 < A[0] || A[A.Length - 1] + 1 == 0 || A[A.Length - 1] + 1 > 1000000)
return 1;
return A[A.Length-1] +1;
}
class Solution {
public int solution(int[] A) {
int size=A.length;
int small,big,temp;
for (int i=0;i<size;i++){
for(int j=0;j<size;j++){
if(A[i]<A[j]){
temp=A[j];
A[j]=A[i];
A[i]=temp;
}
}
}
int z=1;
for(int i=0;i<size;i++){
if(z==A[i]){
z++;
}
//System.out.println(a[i]);
}
return z;
}
enter code here
}
In C# you can solve the problem by making use of built in library functions. How ever the performance is low for very large integers
public int solution(int[] A)
{
var numbers = Enumerable.Range(1, Math.Abs(A.Max())+1).ToArray();
return numbers.Except(A).ToArray()[0];
}
Let me know if you find a better solution performance wise
C# - MissingInteger
Find the smallest missing integer between 1 - 1000.000.
Assumptions of the OP take place
TaskScore/Correctness/Performance: 100%
using System;
using System.Linq;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
var A = new int[] { -122, -5, 1, 2, 3, 4, 5, 6, 7 }; // 8
var B = new int[] { 1, 3, 6, 4, 1, 2 }; // 5
var C = new int[] { -1, -3 }; // 1
var D = new int[] { -3 }; // 1
var E = new int[] { 1 }; // 2
var F = new int[] { 1000000 }; // 1
var x = new int[][] { A, B, C, D, E, F };
x.ToList().ForEach((arr) =>
{
var s = new Solution();
Console.WriteLine(s.solution(arr));
});
Console.ReadLine();
}
}
// ANSWER/SOLUTION
class Solution
{
public int solution(int[] A)
{
// clean up array for negatives and duplicates, do sort
A = A.Where(entry => entry > 0).Distinct().OrderBy(it => it).ToArray();
int lowest = 1, aLength = A.Length, highestIndex = aLength - 1;
for (int i = 0; i < aLength; i++)
{
var currInt = A[i];
if (currInt > lowest) return lowest;
if (i == highestIndex) return ++lowest;
lowest++;
}
return 1;
}
}
}
Got 100% - C# Efficient Solution
public int solution (int [] A){
int len = A.Length;
HashSet<int> realSet = new HashSet<int>();
HashSet<int> perfectSet = new HashSet<int>();
int i = 0;
while ( i < len)
{
realSet.Add(A[i]); //convert array to set to get rid of duplicates, order int's
perfectSet.Add(i + 1); //create perfect set so can find missing int
i++;
}
perfectSet.Add(i + 1);
if (realSet.All(item => item < 0))
return 1;
int notContains =
perfectSet.Except(realSet).Where(item=>item!=0).FirstOrDefault();
return notContains;
}
class Solution {
public int solution(int[] a) {
int smallestPositive = 1;
while(a.Contains(smallestPositive)) {
smallestPositive++;
}
return smallestPositive;
}
}
Well, this is a new winner now. At least on C# and my laptop. It's 1.5-2 times faster than the previous champion and 3-10 times faster, than most of the other solutions. The feature (or a bug?) of this solution is that it uses only basic data types. Also 100/100 on Codility.
public int Solution(int[] A)
{
bool[] B = new bool[(A.Length + 1)];
for (int i = 0; i < A.Length; i++)
{
if ((A[i] > 0) && (A[i] <= A.Length))
B[A[i]] = true;
}
for (int i = 1; i < B.Length; i++)
{
if (!B[i])
return i;
}
return A.Length + 1;
}
Simple C++ solution. No additional memory need, time execution order O(N*log(N)):
int solution(vector<int> &A) {
sort (A.begin(), A.end());
int prev = 0; // the biggest integer greater than 0 found until now
for( auto it = std::begin(A); it != std::end(A); it++ ) {
if( *it > prev+1 ) break;// gap found
if( *it > 0 ) prev = *it; // ignore integers smaller than 1
}
return prev+1;
}
int[] A = {1, 3, 6, 4, 1, 2};
Set<Integer> integers = new TreeSet<>();
for (int i = 0; i < A.length; i++) {
if (A[i] > 0) {
integers.add(A[i]);
}
}
Integer[] arr = integers.toArray(new Integer[0]);
final int[] result = {Integer.MAX_VALUE};
final int[] prev = {0};
final int[] curr2 = {1};
integers.stream().forEach(integer -> {
if (prev[0] + curr2[0] == integer) {
prev[0] = integer;
} else {
result[0] = prev[0] + curr2[0];
}
});
if (Integer.MAX_VALUE == result[0]) result[0] = arr[arr.length-1] + 1;
System.out.println(result[0]);
I was surprised but this was a good lesson. LINQ IS SLOW. my answer below got me 11%
public int solution (int [] A){
if (Array.FindAll(A, x => x >= 0).Length == 0) {
return 1;
} else {
var lowestValue = A.Where(x => Array.IndexOf(A, (x+1)) == -1).Min();
return lowestValue + 1;
}
}
I think I kinda look at this a bit differently but gets a 100% evaluation. Also, I used no library:
public static int Solution(int[] A)
{
var arrPos = new int[1_000_001];
for (int i = 0; i < A.Length; i++)
{
if (A[i] >= 0)
arrPos[A[i]] = 1;
}
for (int i = 1; i < arrPos.Length; i++)
{
if (arrPos[i] == 0)
return i;
}
return 1;
}
public int solution(int[] A) {
// write your code in Java SE 8
Set<Integer> elements = new TreeSet<Integer>();
long lookFor = 1;
for (int i = 0; i < A.length; i++) {
elements.add(A[i]);
}
for (Integer integer : elements) {
if (integer == lookFor)
lookFor += 1;
}
return (int) lookFor;
}
I tried to use recursion in C# instead of sorting, because I thought it would show more coding skill to do it that way, but on the scaling tests it didn't preform well on large performance tests. Suppose it's best to just do the easy way.
class Solution {
public int lowest=1;
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
if (A.Length < 1)
return 1;
for (int i=0; i < A.Length; i++){
if (A[i]==lowest){
lowest++;
solution(A);
}
}
return lowest;
}
}
Here is my solution in javascript
function solution(A) {
// write your code in JavaScript (Node.js 8.9.4)
let result = 1;
let haveFound = {}
let len = A.length
for (let i=0;i<len;i++) {
haveFound[`${A[i]}`] = true
}
while(haveFound[`${result}`]) {
result++
}
return result
}
class Solution {
public int solution(int[] A) {
var sortedList = A.Where(x => x > 0).Distinct().OrderBy(x => x).ToArray();
var output = 1;
for (int i = 0; i < sortedList.Length; i++)
{
if (sortedList[i] != output)
{
return output;
}
output++;
}
return output;
}
}
You should just use a HashSet as its look up time is also constant instead of a dictionary. The code is less and cleaner.
public int solution (int [] A){
int answer = 1;
var set = new HashSet<int>(A);
while (set.Contains(answer)){
answer++;
}
return answer;
}
This snippet should work correctly.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int result = 1;
List<int> lst = new List<int>();
lst.Add(1);
lst.Add(2);
lst.Add(3);
lst.Add(18);
lst.Add(4);
lst.Add(1000);
lst.Add(-1);
lst.Add(-1000);
lst.Sort();
foreach(int curVal in lst)
{
if(curVal <=0)
result=1;
else if(!lst.Contains(curVal+1))
{
result = curVal + 1 ;
}
Console.WriteLine(result);
}
}
}
I have 2 BitArray items and I need to know if any of bits are the same in each, "AND".
However, the length of the BitArrays can be different and ether one can be larger or smaller than the other.
How can I do an "AND" of two BitArrays, without getting an exception because of different sizes?
This is going to happen a lot, so I need it to be fairly quick.
Example
int[] ids = new int[3];
ids[0] = 1;
ids[1] = 3;
ids[2] = 5;
BitArray bs1 = new BitArray(ids.Max()+1);
for (int i = 0; i < ids.Count(); ++i)
{
bs1[ids[i]] = true;
}
ids[0] = 1;
ids[1] = 59;
ids[2] = 1111;
BitArray bs2 = new BitArray(ids.Max()+1);
for (int i = 0; i < ids.Count(); ++i)
{
bs2[ids[i]] = true;
}
ids[0] = 0;
ids[1] = 5;
ids[2] = 33;
BitArray bs3 = new BitArray(ids.Max()+1);
for (int i = 0; i < ids.Count(); ++i)
{
bs3[ids[i]] = true;
}
//if bs1 AND bs2 bitcount > 0 DisplayMessage("1 and 2 has some same items")
//if bs1 AND bs3 bitcount > 0 DisplayMessage("1 and 3 has some same items")
//if bs2 AND bs3 bitcount > 0 DisplayMessage("2 and 3 has some same items")
To solve my problem I modified the BitArray code and added the following
public static MyBitArray TruncateCopy(MyBitArray source, int size)
{
MyBitArray dest = new MyBitArray(size);
//copy all the arrays
for (int i = 0; i < dest.m_array.Length; ++i)
{
dest.m_array[i] = source.m_array[i];
}
//remove any of the items over the given size
for (int i = ((size % 32) + 1); i < 32; ++i)
{
dest.m_array[i >> 5] &= ~(1 << (i & 31));
}
return dest;
}
public bool HasCommonBits(MyBitArray comp)
{
MyBitArray copied, other;
if (this.Length < comp.Length)
{
other = this;
copied = TruncateCopy(comp, this.Length);
}
else
{
copied = TruncateCopy(this, comp.Length);
other = comp;
}
MyBitArray compareEq = copied.And(other);
return (!compareEq.IsEmpty());
}
public bool IsEmpty()
{
for (int i = 0; i < this.m_array.Length; ++i)
{
if (m_array[i] != 0)
return false;
}
return true;
}
public bool IsFull()
{
//run through all the full sets
for (int i = 0; i < this.m_array.Length - 1; ++i)
{
if (m_array[i] != -1) //-1 is all bits set in an integer
return false;
}
//go through the partial one
for (int i = 0; i < (this.Length % 32); ++i)
{
if (!this[i])
return false;
}
return true;
}
}
First, define what you want to happen in case of differing lengths. Maybe you just want to compare the first Math.Min(len1, len2) elements. In that case write a for loop whose index variable ranges from 0 to Math.Min(len1, len2). Compare the respective array elements in the loop body.
I examined BitArray with reflector. There is no way to trim it, or to perform a partial And. You're out of luck with this class. Replace it with a custom-written class that supports what you need. Writing a bit array is not especially hard.
Completely revised based on this comment:
The result bitarray of your example would be 01010. My original problem states that I need to see if any of the bits are the same. Thus the a resulting bitarray with any 1's would be True and all 0's would be False
BitArrray truncateCopyBA(BitArray source, int size)
{
BitArray dest = new BitArray(size);
for(int i = 0; i < size; ++i)
{
dest[i] = source[i];
}
return dest;
}
bool YourFunc(BitArray a, BitArray b)
{
BitArray one, two;
if (a.Length < b.Length)
{
one = a;
two = truncateCopyBA(b, a.Length);
}
else
{
one = truncateCopyBA(a, b.Length);
two = b;
// If you want to see which bits in both arrays are both ones, then use .And()
// If you want to see which bits in both arrays are the same, use .Not(.Xor()).
BitArray compareEq = a.And(b);
bool anyBitsSame=false;
for(int i = 0; i < compareEq.Length; ++i)
{
if(compareEq.Get(i))
{
return true;
}
}
return false
}
}
I believe this is what you're looking for, but honestly your question is still quite vague after clarifications.
Have
List<byte> lbyte
Have
byte[] searchBytes
How can I search lbyte for not just a single byte but for the index of the searchBytes?
E.G.
Int32 index = lbyte.FirstIndexOf(searchBytes);
Here is the brute force I came up with.
Not the performance I am looking for.
public static Int32 ListIndexOfArray(List<byte> lb, byte[] sbs)
{
if (sbs == null) return -1;
if (sbs.Length == 0) return -1;
if (sbs.Length > 8) return -1;
if (sbs.Length == 1) return lb.FirstOrDefault(x => x == sbs[0]);
Int32 sbsLen = sbs.Length;
Int32 sbsCurMatch = 0;
for (int i = 0; i < lb.Count; i++)
{
if (lb[i] == sbs[sbsCurMatch])
{
sbsCurMatch++;
if (sbsCurMatch == sbsLen)
{
//int index = lb.FindIndex(e => sbs.All(f => f.Equals(e))); // fails to find a match
IndexOfArray = i - sbsLen + 1;
return;
}
}
else
{
sbsCurMatch = 0;
}
}
return -1;
}
Brute force is always an option. Although slow in comparison to some other methods, in practice it's usually not too bad. It's easy to implement and quite acceptable if lbyte isn't huge and doesn't have pathological data.
It's the same concept as brute force string searching.
You may find Boyer-Moore algorithm useful here. Convert your list to an array and search. The algorithm code is taken from this post.
static int SimpleBoyerMooreSearch(byte[] haystack, byte[] needle)
{
int[] lookup = new int[256];
for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Length; }
for (int i = 0; i < needle.Length; i++)
{
lookup[needle[i]] = needle.Length - i - 1;
}
int index = needle.Length - 1;
var lastByte = needle.Last();
while (index < haystack.Length)
{
var checkByte = haystack[index];
if (haystack[index] == lastByte)
{
bool found = true;
for (int j = needle.Length - 2; j >= 0; j--)
{
if (haystack[index - needle.Length + j + 1] != needle[j])
{
found = false;
break;
}
}
if (found)
return index - needle.Length + 1;
else
index++;
}
else
{
index += lookup[checkByte];
}
}
return -1;
}
You can then search like this. If lbyte will remain constant after a certain time, you can just convert it to an array once and pass that.
//index is returned, or -1 if 'searchBytes' is not found
int startIndex = SimpleBoyerMooreSearch(lbyte.ToArray(), searchBytes);
Update based on comment. Here's the IList implementation which means that arrays and lists (and anything else that implements IList can be passed)
static int SimpleBoyerMooreSearch(IList<byte> haystack, IList<byte> needle)
{
int[] lookup = new int[256];
for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Count; }
for (int i = 0; i < needle.Count; i++)
{
lookup[needle[i]] = needle.Count - i - 1;
}
int index = needle.Count - 1;
var lastByte = needle[index];
while (index < haystack.Count)
{
var checkByte = haystack[index];
if (haystack[index] == lastByte)
{
bool found = true;
for (int j = needle.Count - 2; j >= 0; j--)
{
if (haystack[index - needle.Count + j + 1] != needle[j])
{
found = false;
break;
}
}
if (found)
return index - needle.Count + 1;
else
index++;
}
else
{
index += lookup[checkByte];
}
}
return -1;
}
Since arrays and lists implement IList, there's no conversion necessary when calling it in your case.
int startIndex = SimpleBoyerMooreSearch(lbyte, searchBytes);
Another way you could do with lambda expression
int index = lbyte.FindIndex(e => searchBytes.All(i => i.Equals(e));
I want to find the position of a substring in a string if present without using any string method including indexof. I tried so much times but failed. Will anybody tell me how to do in C#? We can use .Length operator.
Sorry.. thought this would be a fun exercise for me, so...
Spoiler
class Program
{
static void Main(string[] args)
{
string str = "abcdefg";
string substr = "cde";
int index = IndexOf(str, substr);
Console.WriteLine(index);
Console.ReadLine();
}
private static int IndexOf(string str, string substr)
{
bool match;
for (int i = 0; i < str.Length - substr.Length + 1; ++i)
{
match = true;
for (int j = 0; j < substr.Length; ++j)
{
if (str[i + j] != substr[j])
{
match = false;
break;
}
}
if (match) return i;
}
return -1;
}
}
Assuming this is homework, my suggestion is to bear in mind that a string is an IEnumerable of chars. So you can loop through the characters in your string...
Since any homework that inspired the question is well past due, here's a stab at a reasonably performant answer.
Simply cycling through the larger string, and cycling through the substring comparing each character as one goes takes Θ((n-m+1) m) time where m is the length of the substring, and n the index where the smaller string is found, or if there is no match the length of the larger minus that of the smaller.
There are a few different algorithm that give better performance, which differ among themselves in terms of which cases they work best in. The Knuth-Morris-Pratt algorithm takes Θ(m) to set up and then Θ(n) time to find, because it first creates a table to know how far ahead it can jump on failing to find a match, and on balance this makes for a quicker search.
Consider that if we were looking for "ababcd" and we'd first found "abab…" (possible match so far), if the next character is c we still have a possible match. If it's a we don't have a match, but should jump forward two characters to start looking for a match starting from that. If it's anything else, we should jump ahead five characters and continue looking for there. Preparing the table to tell us how far to jump makes things much faster from then on:
public static int IndexOf(string haystack, string needle)
{
if(haystack == null || needle == null)
throw new ArgumentNullException();
if(needle.Length == 0)
return 0;//empty strings are everywhere!
if(needle.Length == 1)//can't beat just spinning through for it
{
char c = needle[0];
for(int idx = 0; idx != haystack.Length; ++idx)
if(haystack[idx] == c)
return idx;
return -1;
}
if (needle.Length == haystack.Length) return needle == haystack ? 0 : -1;
if (needle.Length < haystack.Length)
{
int m = 0;
int i = 0;
int[] T = KMPTable(needle);
while(m + i < haystack.Length)
{
if(needle[i] == haystack[m + i])
{
if(i == needle.Length - 1)
return m == haystack.Length ? -1 : m;//match -1 = failure to find conventional in .NET
++i;
}
else
{
m = m + i - T[i];
i = T[i] > -1 ? T[i] : 0;
}
}
}
return -1;
}
private static int[] KMPTable(string sought)
{
int[] table = new int[sought.Length];
int pos = 2;
int cnd = 0;
table[0] = -1;
table[1] = 0;
while(pos < table.Length)
if(sought[pos - 1] == sought[cnd])
table[pos++] = ++cnd;
else if(cnd > 0)
cnd = table[cnd];
else
table[pos++] = 0;
return table;
}
Try this:
internal bool SearchWord(string str, string searchKey)
{
int j = 0; bool result = false;
for (int i = 0; i < str.Length; i++)
{
if (searchKey[j] == str[i])
{
j++; //count++;
}
else { j = 0; }
if (j == searchKey.Length)
{
result = true;
break;
}
}
return result;
}
Try this:
public static string BetweenOf(string ActualStr, string StrFirst, string StrLast)
{
return ActualStr.Substring(ActualStr.IndexOf(StrFirst) + StrFirst.Length,
(ActualStr.Substring(ActualStr.IndexOf(StrFirst))).IndexOf(StrLast) + StrLast.Length);
}
string mainString = Console.ReadLine();
string subString = Console.ReadLine();
for (int i = 0; i <= mainString.Length - subString.Length; i++)
{
bool match = true;
for (int j = 0; j < subString.Length && mainString[i + j] != subString[j]; j++)
{
match = false;
}
if (match)
Console.WriteLine(i);
}
public static findindex(String str,String substr)
{
char a[]=str.toCharArray();
char b[]=substr.toCharArray();
int j=0,t=0;
for(int i=0;i<str.length()&&j<substr.length();i++)
{
if(a[i]==b[j])
{
t=i;
j++;
}
else
continue;
}
if(t==0)
return -1;
else
return t-substr.length()+1;
}//in java
I have an array of bytes and i want to determine if the contents of this array of bytes exists within another larger array as a continuous sequence. What is the simplest way to go about doing this?
The naive approach is:
public static bool IsSubsetOf(byte[] set, byte[] subset) {
for(int i = 0; i < set.Length && i + subset.Length <= set.Length; ++i)
if (set.Skip(i).Take(subset.Length).SequenceEqual(subset))
return true;
return false;
}
For more efficient approaches, you might consider more advanced string matching algorithms like KMP.
Try to adapt some string search algorithm. One of the fastest is Boyer-Moore . It's quite easy as well. For binary data, Knuth-Morris-Pratt algorithm might work very efficiently as well.
This, which is a 1/1 port of this answer: Searching for a sequence of Bytes in a Binary File with Java
Is a very efficient way of doing so:
public static class KmpSearch {
public static int IndexOf(byte[] data, byte[] pattern) {
int[] failure = ComputeFailure(pattern);
int j = 0;
if (data.Length == 0) return -1;
for (int i = 0; i < data.Length; i++) {
while (j > 0 && pattern[j] != data[i]) {
j = failure[j - 1];
}
if (pattern[j] == data[i]) { j++; }
if (j == pattern.Length) {
return i - pattern.Length + 1;
}
}
return -1;
}
private static int[] ComputeFailure(byte[] pattern) {
int[] failure = new int[pattern.Length];
int j = 0;
for (int i = 1; i < pattern.Length; i++) {
while (j > 0 && pattern[j] != pattern[i]) {
j = failure[j - 1];
}
if (pattern[j] == pattern[i]) {
j++;
}
failure[i] = j;
}
return failure;
}
}