Related
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 want to move all the data from column 0 of a 2D array to a separate 1D array. I have this so far:
for (int x = 0; x < 100; x++) { //100 is the amount of rows in the 2D array
array1D[x] = array2D[x, 0]; //0 is the column I want to take from
}
Is there a more better/more efficient way to achieve the same result?
You cannot copy out the columns, but you can copy out the rows with Buffer.BlockCopy()
class Program
{
static void FillArray(out int[,] array)
{
// 2 rows with 100 columns
array=new int[2, 100];
for (int i=0; i<100; i++)
{
array[0, i]=i;
array[1, i]=100-i;
}
}
static void Main(string[] args)
{
int[,] array2D;
FillArray(out array2D);
var first_row=new int[100];
var second_row=new int[100];
int bytes=sizeof(int);
Buffer.BlockCopy(array2D, 0, first_row, 0, 100*bytes);
// 0, 1, 2, ...
Buffer.BlockCopy(array2D, 100*bytes, second_row, 0, 100*bytes);
// 100, 99, 98, ..
}
}
Update
Here is an extension method do extract a single row from a 2D array (of any type)
public static T[] GetRow<T>(this T[,] array, int rowIndex)
{
int n = array.GetLength(1);
var row = new T[n];
var size = Buffer.ByteLength(row);
Buffer.BlockCopy(array, rowIndex*size, row, 0, size);
return row;
}
to be used as
var array = new double[3, 3] {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7 ,8, 9 } };
var second = array.GetRow(1);
// {4, 5, 6}
Can't figure out why the line winningNumbers[i] += count; comes up as outside the bounds of the array.
static int[] CheckWinningNumbers(int[][]lottoNumbers, int[]drawNumbers)
{
int[] winningNumbers = new int[8];
for (int i = 0; i < lottoNumbers.Length; i++)
{
int k = 0;
int count = 0;
for (int j = 0; j < lottoNumbers[i].Length; j++)
{
if (lottoNumbers[i][j] == drawNumbers[k])
{
count +=1;
}
k += 1;
winningNumbers[i] += count;
}
}
return winningNumbers;
Just replace
int[] winningNumbers = new int[8];
With
int[] winningNumbers = new int[lottoNumbers.Length];
As long as you are iterating lottoNumbers.Length the variable i will not exceed its boundaries.
Edit
I ran it with the following data and it works
int[][] lottoNumbers = { new[] { 1, 2 },
new[]{ 3, 4 },
new[]{ 5, 6 },
new[]{ 7, 8 } };
int[] drawNumbers = {1, 4, 5, 8};
I don't know what data you are testing it on but you are using jagged arrays intead of multidimensional. this will not guarantee that all your sub arrays have the same length which might be problematic. If all the arrays have the same length and performance is not critical here I'd suggest you use Multidimensional Arrays
I setup an array and i would like to create a method that will return an array with the elements in reverse. e.g. if there are 10 slots then array1[9] = 6 so then array2[0] = 6.
I suppose i have to return an array - how would i do that? And i dont know how to reverse and add to another array.
Thank you!
int[] arr = {43, 22, 1, 44, 90, 38, 55, 32, 31, 9};
Console.WriteLine("Before");
PrintArray(arr);
Console.WriteLine("After");
Reverse(arr);
Console.ReadKey(true);
}
static int[] Reverse(int[] array)
{
for (int i = array.Length; i < 1; i--)
{
int x = 0;
array[i] = array[x++];
Console.WriteLine(array[i]);
}
}
static void PrintArray(int[] array)
{
for (int j = 0; j < array.Length; j++)
{
Console.Write(array[j] + " ");
}
Console.WriteLine("");
You can use Array.Reverse
Example from above line
public static void Main() {
// Creates and initializes a new Array.
Array myArray=Array.CreateInstance( typeof(String), 9 );
myArray.SetValue( "The", 0 );
myArray.SetValue( "quick", 1 );
myArray.SetValue( "brown", 2 );
myArray.SetValue( "fox", 3 );
myArray.SetValue( "jumps", 4 );
myArray.SetValue( "over", 5 );
myArray.SetValue( "the", 6 );
myArray.SetValue( "lazy", 7 );
myArray.SetValue( "dog", 8 );
// Displays the values of the Array.
Console.WriteLine( "The Array initially contains the following values:" );
PrintIndexAndValues( myArray );
// Reverses the sort of the values of the Array.
Array.Reverse( myArray );
// Displays the values of the Array.
Console.WriteLine( "After reversing:" );
PrintIndexAndValues( myArray );
}
public static void PrintIndexAndValues( Array myArray ) {
for ( int i = myArray.GetLowerBound(0); i <= myArray.GetUpperBound(0); i++ )
Console.WriteLine( "\t[{0}]:\t{1}", i, myArray.GetValue( i ) );
}
You should be able to use the extension method Reverse
int[] arr = { 43, 22, 1, 44, 90, 38, 55, 32, 31, 9 };
Console.WriteLine("Before");
PrintArray(arr);
Console.WriteLine("After");
PrintArray(arr.Reverse().ToArray());
Or if you don't mind modifing the original sequence you can use Array.Reverse
int[] arr = { 43, 22, 1, 44, 90, 38, 55, 32, 31, 9 };
Console.WriteLine("Before");
PrintArray(arr);
Array.Reverse(arr);
Console.WriteLine("After");
PrintArray(arr);
You can reverse an array by swapping elements from both ends of the array till you reach the middle.
for(int start = 0, end = arr.Length - 1; start < arr.Length/2; start++, end--)
{
swap(arr[start], arr[end]);
}
int a;
Console.WriteLine("Enter the array length");
a=int.Parse(Console.ReadLine());
Console.WriteLine("enter the array element");
int[] sau = new int[a];
for (int i = 0; i < a; i++)
{
sau[i] = int.Parse(Console.ReadLine());
}
for (int i =a.Length-1 ; i < 0;i--)
{
Console.WriteLine(sau[i]);
}
Console.ReadLine();
}
}
}
Create a new array that has the same length as the old array and reverse is done like this
index -> new index
0 -> length - 1
1 -> length - 1 - 1
2 -> length - 1 - 2
..
i -> length - 1 - i
so this translates to this code
int[] myVariable = new int[] { 1, 2, 3, 4, 5 };
int[] reversedVariable = new int[myVariable.Length]();
for (int i = 0; i < myVariable.Length ; i++)
{
reversedVariable[myVariable.Length - 1 - i] = myVariable[i];
}
return reversedVariable;
public class MyList<T> : IEnumerable<T>
{
private T[] arr;
public int Count
{
get { return arr.Length; }
}
public void Reverse()
{
T[] newArr = arr;
arr = new T[Count];
int number = Count - 1;
for (int i = 0; i < Count; i++)
{
arr[i] = newArr[number];
number--;
}
}
}
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];