I have a question, I need to check if some array is part of greater array, it would be rather easy but I need to check if the greater array contains exact same sequence. For example
int[] greaterArray = {8, 3, 4, 5, 9, 12, 6 ... n - elements}
int[] lesserArray = {3, 4, 5}
Now I need to know if lesser array is part of this array but with same sequence so It it contains 3, 4, 5 next to each other in greater array.
I tried:
var exists = greaterArray.Intersect(lesserArray).Any();
But it return me information if any element of lesser array exists in greater array, not exact sequence. Any ideas?
int[] greaterArray = {8, 3, 4, 5, 9, 12, 6};
int[] lesserArray = { 3, 4, 5 };
bool sequenceFound = false;
for (int i = 0; i <= greaterArray.Length - lesserArray.Length; i++)
{
if (greaterArray.Skip(i).Take(lesserArray.Length).SequenceEqual(lesserArray))
{
sequenceFound = true;
break;
}
}
if (sequenceFound)
{
//sequence found
}
else
{
//sequence not found
}
Use the above code. It takes multiple sub-sequences from greaterArray of length equal to the length of lesserArray and matches it with lesserArray.
A bit more generic and without the use of LINQ:
int[] greaterArray = {8, 2, 4, 5, 9, 12, 3, 4, 5};
int[] lesserArray = {3, 4, 5};
for (int i = 0; i <= greaterArray.Length - lesserArray.Length; i++)
{
var sub = greaterArray.SubArray(i, lesserArray.Length);
if (Enumerable.SequenceEqual(sub, lesserArray))
{
Console.WriteLine("Equals!");
}
}
And this utils to get the SubArray:
public static T[] SubArray<T>(this T[] data, int index, int length)
{
T[] result = new T[length];
Array.Copy(data, index, result, 0, length);
return result;
}
This should do your work
int[] grtarr = { 8, 3, 4, 5, 9, 12, 6 };
int[] lsarr = { 3, 4, 5 };
List<int> lstGrtArr = grtarr.ToList();
List<int> lstLsrArr = lsarr.ToList();
bool sequenceMatch = false;
for (int i = 0; i < grtarr.Count(); i++)
{
if (lstGrtArr.Where(x => lstGrtArr.IndexOf(x) >= i).Take(lstLsrArr.Count()).SequenceEqual(lstLsrArr))
{
sequenceMatch = true;
break;
}
}
if(sequenceMatch)
{
//Do Something
}
static bool isPrefix(int[] source, int start_pos, int[] prefix)
{
bool result = start_pos + prefix.Length <= source.Length;
for (int i = 0; result && i < prefix.Length; ++i, ++start_pos)
result = source[start_pos] == prefix[i];
return result;
}
static bool Contains(int[] source, int[] prefix)
{
bool result = false;
for (int i = 0; !result && i < source.Length; ++i)
result = source[i] == prefix[0] ? isPrefix(source, i, prefix) : false;
return result;
}
Use this piece of code:
public bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1,a2))
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}
Or if you want to use Linq and don't care too much about performance, the easiest thing is:
var arrays_are_the_same = Enumerable.SequenceEqual(a1, a2);
Related
so I was solving some unrelated coding challenge and I needed to split an int array based on an element.
similar to how String.Split works.
for example:
var arr1 = new int [] { 3, 3, 0, 2, 4, 3, 2 };
var arr2 = new int [] { 8, 8, 5, 7, 9, 8, 7, 4, 8 };
var results1 = Split(arr1, 0);
foreach (var arr in results1)
Console.WriteLine(string.Join(",", arr));
var results2 = Split(arr2, 8);
foreach (var arr in results2)
Console.WriteLine(string.Join(",", arr));
the output here is:
3,3
2,4,3,2
5,7,9
7,4
I was surprised, I could not find any answers for this, String.Split kept coming up, but no integer!
so I wrote this:
public int[][] Split(int[] arr, int element)
{
List<int[]> arrays = new List<int[]>();
int skip = 0;
int take = 0;
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == element && take != 0)
{
arrays.Add(arr.Skip(skip).Take(take).ToArray());
skip = i + 1;
take = 0;
continue;
}
if (arr[i] != element)
take++;
if (take == 0)
skip = i + 1;
if (arr.Length - 1 == i && take != 0)
arrays.Add(arr.Skip(skip).Take(take).ToArray());
}
return arrays.ToArray();
}
this works (I think), but it is very messy and I don't like it
Any other solutions?
In general case, you can implement it (String.Split like routine but for IEnumerable<T>) as follows:
public static IEnumerable<T[]> Split<T>(IEnumerable<T> source,
T delimiter,
StringSplitOptions options = StringSplitOptions.None,
IEqualityComparer<T> comparer = null) {
if (null == source)
yield break; // Or throw new ArgumentNullException(nameof(source));
if (null == comparer)
comparer = EqualityComparer<T>.Default;
List<T> current = new List<T>();
foreach (T item in source) {
if (comparer.Equals(item, delimiter)) {
if (current.Count > 0 || !options.HasFlag(StringSplitOptions.RemoveEmptyEntries))
yield return current.ToArray();
current.Clear();
}
else
current.Add(item);
}
if (current.Count > 0 || !options.HasFlag(StringSplitOptions.RemoveEmptyEntries))
yield return current.ToArray();
}
Then
var arr1 = new int [] { 3, 3, 0, 2, 4, 3, 2 };
var results1 = Split(arr1, 0);
foreach (var arr in results1)
Console.WriteLine(string.Join(", ", arr));
public static IEnumerable<List<TValue>> SplitBy<TValue>(List<TValue> source, TValue by)
{
int start = 0;
int count = 0;
foreach (TValue item in source)
{
if (item.Equals(by))
{
List<TValue> part = source.GetRange(start, count);
start = start + count + 1;
count = 0;
if (part.Any())
{
yield return part;
}
}
else
{
count++;
}
}
List<TValue> rest = source.GetRange(start, count);
yield return rest;
}
https://dotnetfiddle.net/Widget/Preview?url=/Widget/7ORu8p
My task is:
Please, implement the GetListOfPrimeNumbers method that returns a list of prime numbers from the argument list.
All numbers in the result list should be unique, duplicates should not be added to the result list.
The number is prime if its only dividers are 1 and this number itself.
using Linq is forbidden
Given numbers:
{23}{27}{29}{5}{30}{8}{19}{29}{26}{8}{17}{24}{19}{4}{4}{9}{15}{6}{9}{29}
Expected: {23}{29}{5}{19}{17}
Actual: {23}{27}{29}{5}{19}{29}{17}{19}{9}{15}{9}{29}
I've written this code:
List<int> numbers2 = new List<int>();
foreach (int x in numbers)
{
for (int i = 2; i < x; i++)
{
if (x % i == 0)
{
break;
}
else
{
numbers2.Add(x);
break;
}
}
}
for (int i = 0; i < numbers2.Count-1; i++)
{
if (numbers2[i] == numbers2[i + 1])
{
numbers2.Remove(numbers2[i]);
}
}
for (int i = 0; i < numbers2.Count - 1; i++)
{
if (numbers2[i] == numbers2[i + 1])
{
numbers2.Remove(numbers2[i]);
}
}
return numbers2;
what is the mistake? help, please!
you can try that :)
int[] nums = { 23, 27, 29, 5, 30, 8, 19, 29, 26, 8, 17, 24, 19, 4, 4, 9, 15, 6, 9, 29 };
List<int> numbers = nums.ToList();
List<int> numbers2 = new List<int>();
foreach (int number in numbers)
{
bool IsprimeNumber = true;
long value = Convert.ToInt32(Math.Sqrt(number));
if (number % 2 == 0)
{
IsprimeNumber = false;
}
for (long i = 3; i <= value; i = i + 2)
{
if (number % i == 0)
{
IsprimeNumber = false;
break;
}
}
if (IsprimeNumber)
{
if (!numbers2.Contains(number))
{
numbers2.Add(number);
}
}
}
foreach (int numero in numbers2)
{
Console.WriteLine(numero);
}
Console.ReadLine();
this is the problem [enter image description here][1]
class Program
{
/* I 'am sorry, but if written this code in french so I will explain the name of variables in English, and what are they doing
and Yes I am aware this code is spaghetti and I would appreciate if there is a better way to write it
T is an Array, and cible is a target */
public static int [] getRange(int[] T, int cible)
{
// T_indices is an Array of indexes
int[] T_indices = new int[10];
//cpt is a counting variable
int cpt=0;
for (int i = 0; i < T.Length; i++)
{
if(T[i]==cible)
{
for (int j = i; j < T.Length; j++)
{
if(T[i]==T[j])
{
T_indices[cpt] = j;
cpt++;
}
else
{
break;
}
}
break;
}
}
//checking if the element doesn't existe so we can return a -1
if(cpt==0)
{
T_indices = new int[1];
T_indices[0] = -1;
return T_indices;
}
else
{
//T_indices_Finaux is the final index Array
int[] T_indices_Finaux = new int[2];
T_indices_Finaux[0] = T_indices[0];
// Max doesn't need explanation I guess
int max = T_indices[0];
for (int i = 0; i < T_indices.Length; i++)
{
if(max< T_indices[i])
{
max = T_indices[i];
}
}
T_indices_Finaux[1] = max;
if(T_indices_Finaux[0]== T_indices_Finaux[1])
{
T_indices_Finaux = new int[1];
T_indices_Finaux[0] = T_indices[0];
}
return T_indices_Finaux;
}
}
// here we put this spaghetti code to the test suprisenly wroking out
static void Main(string[] args)
{
int[] T = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
for (int i = 0; i < getRange(T, 2).Length; i++)
{
Console.WriteLine(getRange(T, 2)[i]);
}
Console.Read();
}
}
int[] T_indices = new int[10];
How do you know, that 10 is enough? You do not. This magic number would cause, that the code sometimes works and sometimes it just throws out of range exception. Besides this, the code is okay, but you do it in a bit too complicated way. What you need is basically this
public static int[] getRange(int[] T, int cible)
{
for (int i = 0; i < T.Length; ++i)
{
if (T[i] == cible)
{
int j = i + 1;
while (j < T.Length && T[j] == cible) { ++j; }
--j;
if (i == j) { return new int[] { i }; }
return new int[] { i, j };
}
}
return new int[] { -1 };
}
And btw. the test code calls the getRange function up to three times. You should call it once, store the result array and loop over that array.
pleas try this :
change getRange Method to this :
public static List<int> getRange(int[] T, int cible)
{
var result=new List<int>();
var list = T.ToList();
if(!list.Contains(cible))
result.Add(-1);
else
{
result.Add(list.IndexOf(cible));
if (list.Count(x=>x==cible)>1)
result.Add(list.LastIndexOf(cible));
}
return result;
}
and use it like this :
int[] T = { 1, 2, 2, 2, 2, 3, 4, 7, 8, 8 };
getRange(T, 2).ForEach(Console.WriteLine);
In this solution you will never get an OutOfRange ٍException and also use the native c # method (for get index of a item in array. "IndexOf" Instead "for") which is much faster and more efficient.
How find template in array ?
Template
int[] = {X, X, X}; //(example 3,3,3)
, or template
int[,] temp2 =
{
{X, X, ?}
{?, X, X}
}
Example
int[,] temp2 =
{
{3, 3, 1}
{2, 3, 3}
}
For example, in such an array?
int[,] a = new int[,]
{
{ 1, 4, 5, 3, 4 },
{ 1, 2, 3, 1, 3 },
{ 1, 1, 2, 4, 4 },
{ 4, 4, 3, 3, 3 },
{ 3, 4, 4, 5, 5 }
};
Is there a faster way than searching each cell and its neighboring cells?
If you are looking for patterns inside a bigger array, probably checking cell by cell is the only way to do it. You could do some complex optimizations for skipping the ? values and speedup a little, but I don't think it would easily work.
A sample code that should do what you asked:
// null means anything is ok, X is 0, Y is 1, Z is 2...
int?[,] temp = new int?[,]
{
{0, 0, null},
{null, 0, 0}
};
int[,] a = new int[,]
{
{ 0, 1, 1, 2, 4, 4, 1 },
{ 0, 1, 4, 4, 3, 3, 3 },
{ 0, 2, 3, 4, 4, 5, 5 }
};
int row, col;
bool success = CheckPattern(temp, a, out row, out col);
Console.WriteLine("Success: {0}, row: {1}, col: {2}", success, row, col);
and then
private static bool CheckPattern(int?[,] temp, int[,] data, out int row, out int col)
{
int rowsT = temp.GetLength(0);
int colsT = temp.GetLength(1);
int rowsD = data.GetLength(0);
int colsD = data.GetLength(1);
// Find the "maximum" value of the template (how many different
// condition are there... If there is only "X" then 1, "X", "Y" then 2,
// "X", "Y", "Z" then 3...
int max = -1;
for (int i = 0; i < rowsT; i++)
{
for (int j = 0; j < rowsT; j++)
{
if (temp[i, j] != null)
{
max = Math.Max(temp[i, j].Value, max);
}
}
}
// We save in an array the "current" values of "X", "Y", "Z", ...
int?[] values = new int?[max + 1];
for (int i = 0; i < rowsD - rowsT + 1; i++)
{
for (int j = 0; j < colsD - colsT + 1; j++)
{
Array.Clear(values, 0, values.Length);
bool success = true;
// Check the template
for (int k = 0; k < rowsT; k++)
{
for (int r = 0; r < colsT; r++)
{
if (temp[k, r] != null)
{
int? curr = values[temp[k, r].Value];
if (curr == null)
{
// If this is the first time we check this
// condition, then any value is good
values[temp[k, r].Value] = data[i + k, j + r];
}
else if (curr.Value == data[i + k, j + r])
{
// For subsequent instances we check this
// condition, then the data must have the
// value found in the previous instance
}
else
{
success = false;
break;
}
}
}
if (!success)
{
break;
}
}
if (success)
{
row = i;
col = j;
return true;
}
}
}
row = 0;
col = 0;
return false;
}
This piece of code should work even for multiple conditions "X", "Y"...
I have this Array i wrote a function MostFreq that takes an array of integers and return 2 values : the more frequent number in the array and its frequency check this code i worte what do you think ? is there a better way to do it?
static void Main()
{
int [] M={4,5,6,4,4,3,5,3};
int x;
int f=MyMath.MostFreq(M,out x );
console.WriteLine("the most Frequent Item = {0} with frequency = {1}",x,f);
}
=====
in the class Mymath
public static int MostFreq(int[] _M, out int x)
{
//First I need to sort the array in ascending order
int Max_Freq, No_Freq, i, k;
Array.Sort(_M);
k = _M[0];
Max_Freq = 0; i = 0; x = 0;
while (i < _M.Length)
{
//No_Freq= the frequency of the current number
No_Freq = 0;
//X here is the number which is appear in the array Frequently
while (k == _M[i])
{
No_Freq++;
i++;
if (i == _M.Length)
break;
}
if (No_Freq > Max_Freq)
{
//so it will be printed the same
Max_Freq = No_Freq;
x = k;
}
if (i < _M.Length) k = _M[i];
}
return (Max_Freq);
}
LINQ it up. I know this is in VB but you should be able to convert it to C#:
Dim i = From Numbers In ints _
Group Numbers By Numbers Into Group _
Aggregate feq In Group Into Count() _
Select New With {.Number = Numbers, .Count = Count}
EDIT: Now in C# too:
var i = from numbers in M
group numbers by numbers into grouped
select new { Number = grouped.Key, Freq = grouped.Count()};
Assuming you can't use LINQ, I'd probably approach the algorithm like this:
Create Key/Value dictionary
Iterate your array, add a key the dictionary for each unique elem, increment the value each time that element is repeated.
Walk the dictionary keys, and return the elem with the highest value.
This isn't a great solution but it is simple, ContainsKey is an O(1) lookup, so you'll be at most iterating your array twice.
From a software engineering standpoint, I would expect a function called MostFreq to return the element with the highest frequency - not the frequency itself. I would switch your out and return values.
You could eliminate the sort you do at the start by iterating the entire array once, keeping a count of how many times you come across each value in a temporary array, and then iterating the temporary array for the highest number. You could keep both the highest frequency count and the most frequent item throughout, too.
Different sorts have different efficiencies on different types of data, of course, but this would be a worst case of just two iterations.
Edit: Apologies for the repeat... 'Tweren't there when I started :)
Done in 1 pass....
public class PopularNumber
{
private Int32[] numbers = {5, 4, 3, 32, 6, 6, 3, 3, 2, 2, 31, 1, 32, 4, 3, 4, 5, 6};
public PopularNumber()
{
Dictionary<Int32,Int32> bucket = new Dictionary<Int32,Int32>();
Int32 maxInt = Int32.MinValue;
Int32 maxCount = 0;
Int32 count;
foreach (var i in numbers)
{
if (bucket.TryGetValue(i, out count))
{
count++;
bucket[i] = count;
}
else
{
count = 1;
bucket.Add(i,count);
}
if (count >= maxCount)
{
maxInt = i;
maxCount = count;
}
}
Console.WriteLine("{0},{1}",maxCount, maxInt);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MostFrequentElement
{
class Program
{
static void Main(string[] args)
{
int[] array = new int[] { 4, 1, 1, 4, 2, 3, 4, 4, 1, 2, 4, 9, 3, 1, 1, 7, 7, 7, 7, 7 };
Array.Sort(array, (a, b) => a.CompareTo(b));
int counter = 1;
int temp=0 ;
List<int> LOCE = new List<int>();
foreach (int i in array)
{
counter = 1;
foreach (int j in array)
{
if (array[j] == array[i])
{
counter++;
}
else {
counter=1;
}
if (counter == temp)
{
LOCE.Add(array[i]);
}
if (counter > temp)
{
LOCE.Clear();
LOCE.Add(array[i]);
temp = counter;
}
}
}
foreach (var element in LOCE)
{
Console.Write(element + ",");
}
Console.WriteLine();
Console.WriteLine("(" + temp + " times)");
Console.Read();
}
}
}
Here's an example how you could do it without LINQ and no dictionaries and lists, just two simple nested loops:
public class MostFrequentNumber
{
public static void Main()
{
int[] numbers = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
int counter = 0;
int longestOccurance = 0;
int mostFrequentNumber = 0;
for (int i = 0; i < numbers.Length; i++)
{
counter = 0;
for (int j = 0; j < numbers.Length; j++)
{
if (numbers[j] == numbers[i])
{
counter++;
}
}
if (counter > longestOccurance)
{
longestOccurance = counter;
mostFrequentNumber = numbers[i];
}
}
Console.WriteLine(mostFrequentNumber);
//Console.WriteLine($"occured {longestOccurance} times");
}
}
You get the value of the most frequently occurring number, and (commented) you could get also the numbers of the occurrences.
I know I have an "using Linq;", that's just to convert the initial input string to an int array and to spare a couple of lines and a parsing loop. Algorithm is fine even without it, if you fill the array the "long" way...
Lets suppose the array is as follows :
int arr[] = {10, 20, 10, 20, 30, 20, 20,40,40,50,15,15,15};
int max = 0;
int result = 0;
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < arr.length; i++) {
if (map.containsKey(arr[i]))
map.put(arr[i], map.get(arr[i]) + 1);
else
map.put(arr[i], 1);
int key = map.keySet().iterator().next();
if (map.get(key) > max) {
max = map.get(key) ;
result = key;
}
}
System.out.println(result);
Explanation:
In the above code I have taken HashMap to store the elements in keys and the repetition of the elements as values. We have initialized variable max = 0 ( max is the maximum count of repeated element) While iterating over elements We are also getting the max count of keys.
The result variable returns the keys with the mostly repeated.
int[] arr = { 4, 5, 6, 4, 4, 3, 5, 3 };
var gr = arr.GroupBy(x => x).OrderBy(x => x.Count()).Last();
Console.WriteLine($"The most Frequent Item = {gr.Key} with frequency = {gr.Count()}"); // The most Frequent Item = 4 with frequency = 3
int[] numbers = new int[] {1, 2, 3, 2, 1, 4, 2};
Dictionary<int, int> numberCounts = new Dictionary<int, int>();
foreach (int number in numbers)
{
if (numberCounts.ContainsKey(number))
{
numberCounts[number]++;
}
else
{
numberCounts[number] = 1;
}
}
int maxCount = numberCounts.Values.Max();
int mostFrequentNumber = numberCounts.Where(x => x.Value == maxCount).OrderByDescending(x => x.Key).First().Key;
Console.WriteLine("Most frequent number: " + mostFrequentNumber);
int count = 1;
int currentIndex = 0;
for (int i = 1; i < A.Length; i++)
{
if (A[i] == A[currentIndex])
count++;
else
count--;
if (count == 0)
{
currentIndex = i;
count = 1;
}
}
int mostFreq = A[currentIndex];