I m Trying to convert a number entered in the text box post.But I can not find the right reasons, does not work.Are you also please have a look.Thank you in advance!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace NumberToText
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void NumberControl()
{
if ((txtNumber.Text.Length>7))
{
MessageBox.Show("Please enter a smaller number");
}
}
public void ReadNumber()
{
try
{
int ones, tens, hundreds, thousands, tenthousands, hundredthousands,
millions;
int number = Convert.ToInt32(txtNumber.Text);
int[] array=new int[7];
for (int j = 0; j < txtNumber.Text.Length; )
{
array[j] = (number / (10 ^ (txtNumber.Text.Length -
(txtNumber.Text.Length - j)))) % 10;
j += 1;
}
if (txtSayi.Text.Length != 7)
{
for (int i = 6; i >= txtNumber.Text.Length; )
{
dizi[i] = 0;
i-=1;
}
}
ones = array[0];
tens = array[1];
hundreds = array[2];
thousands = array[3];
tenthousands = array[4];
hundredthousands = array[5];
millions = array[6];
//Converting to numbers in TURKISH Text
string[] a_ones = { "", "Bir", "İki", "Üç", "Dört", "Beş", "Altı",
"Yedi", "Sekiz", "Dokuz" };
string[] a_tens = { "", "On", "Yirmi", "Otuz", "Kırk", "Elli",
"Altmış", "Yetmiş", "Seksen", "Doksan" };
string[] a_hundreds = { "", "Yüz", "İkiyüz", "Üçyüz", "Dörtyüz",
"Beşyüz", "Altıyüz", "Yediyüz", "Sekizyüz", "Dokuzyüz" };
string[] a_thousands = { "", "Bin", "İkibin", "Üçbin", "Dörtbin",
"Beşbin", "Altıbin", "Yedibin", "Sekizbin", "Dokuzbin" };
string[] a_tenthousands = { "", "On", "Yirmi", "Otuz", "Kırk",
"Elli", "Altmış", "Yetmiş", "Seksen", "Doksan" };
string[] a_hundredthousands = { "", "Yüz", "İkiyüz", "Üçyüz",
"Dörtyüz", "Beşyüz", "Altıyüz", "Yediyüz", "Sekizyüz", "Dokuzyüz" };
string[] a_millions = { "", "Birmilyon", "İkimilyon", "Üçmilyon",
"Dörtmilyon", "Beşmilyon", "Altımilyon", "Yedimilyon", "Sekizmilyon", "Dokuzmilyon"
};
lblText.Text = a_millions[millions] + " " + a_hundredthousands
[hundredthousands] + a_tenthousands[tenthousands] + " " + a_thousands[thousands] + "
" + a_hundreds[hundreds] + " " + a_tens[tens] + " " + a_ones[ones];
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
private void btnConvert_Click(object sender, EventArgs e)
{
NumberControl();
ReadNumber();
}
}
}
for (int j = 0; j < txtNumber.Text.Length; )
{
array[j] = (number / (10 ^ (txtNumber.Text.Length - (txtNumber.Text.Length - j)))) % 10;
j += 1;
}
(txtNumber.Text.Length - (txtNumber.Text.Length - j)) is j, so:
for (int j = 0; j < txtNumber.Text.Length; j += 1)
{
array[j] = (number / (10 ^ j)) % 10;
}
You're XOR'ing 10 with j?
Also, "Sekizmilyon" is not a word. You need a put a space in between.
It looks like you're trying to calculate a power of 10 with ^ when you probably mean Math.Pow. Using the reduction aib suggested, your line:
array[j] = (number / (10 ^ (txtNumber.Text.Length - (txtNumber.Text.Length - j)))) % 10;
becomes:
array[j] = (number / (int)Math.Pow(10, j)) % 10;
A couple of other suggestions:
Change NumberControl to return a bool so you can skip the call to ReadNumber if the entered number is too large. Currently it goes into ReadNumber even if the number is more than 7 digits, which results in an array out of bounds error
The block of code starting with if (txtSayi.Text.Length != 7) seems redundant.
Related
What I want to do is to spread tasks over a number of servers randomly with very little bias if possible. So far what I worked on is able to randomly spread the tasks over a different servers. The problem is that whenever I spread the tasks over the servers, it spreads the 1-3 tasks per server. The load balancing method used is Power of Two Choices. Forgive me if I get the concept wrong.
Power of Two Choices is where two random queues are chosen, where the one with the least tasks, is assigned a task. Correct me if I'm wrong.
The photo below shows my current output.
What I want is this
My main file is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace C1._2
{
class Program
{
static void details(Server[] server, int num)
{
int count = 0;
for (int i = 0; i < server.Length; i++)
{
if (server[i].Tasks == num)
{
count++;
}
}
Console.WriteLine("There are " + count + " servers with " + num + " tasks.");
}
static void Main(string[] args)
{
Random rand = new Random();
int n = 256; //number of tasks
int m; //number of servers
m = 64;//Convert.ToInt32(Console.ReadLine())
Console.WriteLine("Number of servers(m): " + m);
int d = 1; //random servers to be chosen
Console.WriteLine("Number of tasks(n): " + n);
Console.WriteLine("Number of randomly selected server(d): " + d);
//Main server setup
Server[] servers = new Server[m];
for (int i = 0; i < m; i++)
{
servers[i] = new Server(i);
}
if (d == 1)
{
for (int i = 0; i < n; i++)
{
int randS = rand.Next(m);
servers[randS].Tasks++;
}
}
//Power of Two choice algorithm is here
if (d == 2)
{
for(int i = 0; i < n; i++)
{
Server s1 = servers[rand.Next(m)];
Server s2 = servers[rand.Next(m)];
if (s1.Tasks < s2.Tasks)
{
for(int j = 0; j < m; j++)
{
if (servers[j].SNo == s1.SNo)
{
servers[j].Tasks++;
}
}
}
else
{
for (int j = 0; j < m; j++)
{
if (servers[j].SNo == s2.SNo)
{
servers[j].Tasks++;
}
}
}
}
}
//Server min max
Server maxServer = new Server();
maxServer = servers[0];
for (int i = 0; i < m; i++)
{
if (maxServer.Tasks < servers[i].Tasks)
{
maxServer = servers[i];
}
}
Console.WriteLine("\nIndex of servers with most tasks: " + "[" + maxServer.SNo + "]");
Console.WriteLine("Highest number of tasks: " + maxServer.Tasks+"\n");
Server minServer = new Server();
minServer = servers[0];
for (int i = 0; i < m; i++)
{
if (minServer.Tasks > servers[i].Tasks)
{
minServer = servers[i];
}
}
Console.WriteLine("\nIndex of servers with least tasks: " + "[" + minServer.SNo + "]");
Console.WriteLine("Lowest number of tasks: " + minServer.Tasks+"\n");
//details
details(servers, 0);
details(servers, 1);
details(servers, 2);
details(servers, 3);
details(servers, 4);
details(servers, 5);
details(servers, 6);
details(servers, 7);
details(servers, 8);
details(servers, 9);
}
}
}
Accompanied Server class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace C1._2
{
class Server
{
private int server_number;
private int task;
public Server()
{
this.server_number = (int)0;
this.task = 0;
}
public Server(int sn)
{
this.server_number = sn;
this.task = 0;
}
public int SNo
{
get
{
return this.server_number;
}
set
{
this.server_number = value;
}
}
public int Tasks
{
get
{
return this.task;
}
set
{
this.task = value;
}
}
}
}
Any advice on how to do so?
When you say "random... where the one with the least tasks" means to me not random. But i think that I understand what you want. So we need to select the list of items that have least tasks and chose one of this randomic.
I rewrited a part of the class Program. Let me know if is this the expected result.
class Program
{
static void Main(string[] args)
{
//Random rand = new Random();
int numberOfTasks = 256; //number of tasks
int numberOfServers; //number of servers
numberOfServers = 64;//Convert.ToInt32(Console.ReadLine())
Console.WriteLine("Number of servers(m): " + numberOfServers);
//int d = 1; //random servers to be chosen
Console.WriteLine("Number of tasks(n): " + numberOfTasks);
//Console.WriteLine("Number of randomly selected server(d): " + d);
//Main server setup
Server[] servers = new Server[numberOfServers];
for (int i = 0; i < numberOfServers; i++)
{
servers[i] = new Server(i);
}
for(int i = 0; i < numberOfTasks; i++){
var minimumTasksValue = servers.Min(x => x.Tasks);
var listOfServersToSpread = servers.Where(x => x.Tasks == minimumTasksValue).ToList();
Random rand = new Random();
var randomServer = rand.Next(0, listOfServersToSpread.Count() - 1);
listOfServersToSpread[randomServer].Tasks++;
}
//Server min max
Server maxServer = new Server();
maxServer = servers[0];
for (int i = 0; i < numberOfServers; i++)
{
if (maxServer.Tasks < servers[i].Tasks)
{
maxServer = servers[i];
}
}
Console.WriteLine("\nIndex of servers with most tasks: " + "[" + maxServer.SNo + "]");
Console.WriteLine("Highest number of tasks: " + maxServer.Tasks + "\n");
Server minServer = new Server();
minServer = servers[0];
for (int i = 0; i < numberOfServers; i++)
{
if (minServer.Tasks > servers[i].Tasks)
{
minServer = servers[i];
}
}
Console.WriteLine("\nIndex of servers with least tasks: " + "[" + minServer.SNo + "]");
Console.WriteLine("Lowest number of tasks: " + minServer.Tasks + "\n");
//details
details(servers);
Console.ReadLine();
}
static void details(Server[] server)
{
var numberOfTasksAvailable = server.Select(x => x.Tasks).Distinct().OrderBy(x => x);
foreach(var numberOfTasks in numberOfTasksAvailable)
{
Console.WriteLine("There are " + server.Count(x => x.Tasks == numberOfTasks) + " servers with " + numberOfTasks + " tasks.");
}
}
}
Updated load balancing algorithm
if (d == 2)
{
for(int i = 0; i < n; i++)
{
int a = rand.Next(m);
int b = rand.Next(m);
servers[a < b ? a : b].Tasks++;
}
}
My problem was over-complicating the code. What it does above is that it randomly chooses two random servers from the total servers available. Compares which server has the least burden/tasks, and assigns a task to it.
I have created a piece of code to create an array of 100 elements which will randomize based on the numbers from a set array. However whenever I enter "y" I am looking the array to delete the last element and add a new random element to the start and move everything in between one to the right to allow for this. However at the moment it is completely changing the array every time I enter "y". Can anyone help with this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
int[] values = { 1, 2, 3, 4, 5, 6 };
int Min = values[0];
int Max = values[5] + 1;
int w = 0 ;
int[] rndValues = new int[100];
Random rndNum = new Random();
Console.WriteLine("Random001 " + w);
for (int i = 0; i < rndValues.Length; i++)
{
rndValues[i] = rndNum.Next(Min, Max);
}
Console.WriteLine("Random " + w);
foreach(var item in rndValues)
{
Console.Write(item.ToString() + " ");
}
if (w==0)
{
Console.WriteLine(Environment.NewLine);
prob(rndValues, Min, Max,w);
Console.WriteLine(Environment.NewLine);
w++;
}
if (w>0)
{
while(true)
{
Console.WriteLine("To change elements in the array press y");
// read input
var s = Console.ReadLine();
if(s == "y")
{
//rndValues[99] = 0;
for(int i = 0; i == rndValues.Length; i++)
{
if (i != rndValues.Length)
{
rndValues[rndValues.Length-i] = rndValues[(rndValues.Length-i)-1];
}
else if (i == rndValues.Length)
{
rndValues[0] = rndNum.Next(Min, Max);
}
}
}
else
{
break;
}
prob(rndValues, Min, Max,w);
}
}
}
public static void prob(int[] rndValues, int Min, int Max, int w )
{
double[] count = new double[rndValues.Length];
//Loop through min to max and count the occurances
for (int i = Min; i <Max; i++)
{
for (int j = 0; j < rndValues.Length; j++)
{
if (rndValues[j] == i)
{
count[i] = count[i] + 1;
}
}
}
//For displaying output only
foreach(var item in rndValues)
{
Console.Write(item.ToString() + " ");
}
Console.WriteLine("W " + w);
for (int i = Min; i < Max; i++)
{
count[i] = (count[i] / rndValues.Length) * 100;
Console.WriteLine("Probability of the number " + i + " is " + count[i]);
}
}
}
}
Thanks.
I have a problem with one exercise. Task is to find all subsets within the array which have a sum equal to N and print them. Also I need to find all unique subsets and this is the problem. I am using Gray method to find all combinations but some of them are duplicated. Here's my code:
int matchSum = int.Parse(Console.ReadLine());
int[] numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();
int combinations = (int) Math.Pow(2, numbers.Length);
List<int> currentSequence = new List<int>();
bool foundMatch = false;
for (int i = 1; i < combinations; i++)
{
for (int bit = 0; bit < Convert.ToString(i,2).Length; bit++)
{
int mask = (i >> bit) & 1;
if (mask == 1)
{
currentSequence.Add(numbers[numbers.Length-bit-1]);
}
}
if (currentSequence.Sum() == matchSum)
{
Console.WriteLine("{0} = {1}", string.Join(" + ", currentSequence), matchSum);
foundMatch = true;
}
currentSequence.Clear();
}
if (!foundMatch)
{
Console.WriteLine("No matching subsets.");
}
Best regards!
Here is a backtracking algorithm implementation. It works by first sorting the input set and then producing the subsets and checking the sum. There are 3 key points. First, the algorithm maintains the current sum all the time so it doesn't need to fully calculate it at each step. Second, it early stops if the current sum becomes larger than the target sum. And finally, in order to produce unique subsets, the back step skips the numbers that are equal to the last number of the previous sequence. Hope that helps.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Samples
{
class Sample
{
static void Main(string[] args)
{
int matchSum = 20; // int.Parse(Console.ReadLine());
int[] numbers = { 5, 1, 3, 2, 5, 1, 8, 7, 4 }; // Console.ReadLine().Split().Select(int.Parse).ToArray();
Array.Sort(numbers);
var stack = new Stack<int>();
int matchCount = 0, currentSum = 0, nextPos = 0;
while (true)
{
// Next
for (int nextSum; nextPos < numbers.Length; currentSum = nextSum, nextPos++)
{
nextSum = currentSum + numbers[nextPos];
if (nextSum > matchSum) break;
stack.Push(nextPos);
if (nextSum < matchSum) continue;
matchCount++;
Console.WriteLine("{0} = {1}", matchSum, string.Join(" + ", stack.Reverse().Select(pos => numbers[pos])));
stack.Pop();
break;
}
// Back
if (stack.Count == 0) break;
var lastPos = stack.Pop();
var lastNumber = numbers[lastPos];
currentSum -= lastNumber;
nextPos = lastPos + 1;
while (nextPos < numbers.Length && numbers[nextPos] == lastNumber)
nextPos++;
}
if (matchCount == 0)
{
Console.WriteLine("No matching subsets.");
}
Console.ReadLine();
}
}
}
I found another way with a HashSet (thanks #Eric J.).
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static List<int> currentMatchList = new List<int>();
static void Main()
{
int matchSum = int.Parse(Console.ReadLine());
int[] numbers = Console.ReadLine().Split().Select(int.Parse).ToArray();
int combinations = (int)Math.Pow(2, numbers.Length);
List<int> currentSequence = new List<int>();
HashSet<string> allResults = new HashSet<string>();
bool foundMatch = false;
for (int i = 1; i < combinations; i++)
{
for (int bit = 0; bit < Convert.ToString(i, 2).Length; bit++)
{
int mask = (i >> bit) & 1;
if (mask == 1)
{
currentSequence.Add(numbers[numbers.Length - bit - 1]);
}
}
if (currentSequence.Sum() == matchSum)
{
string temp = "";
currentSequence.OrderBy(a => a).ToList().ForEach(a => temp += a + " ");
if (!allResults.Contains(temp))
{
allResults.Add(temp);
Console.WriteLine("{0} = {1}", string.Join(" + ", currentSequence), matchSum);
}
foundMatch = true;
}
currentSequence.Clear();
}
if (!foundMatch)
{
Console.WriteLine("No matching subsets.");
}
}
}
Im currently trying to create a program that prints the prime numbers from 0 to 10,000 using only for,do while and ifs. I created this program but it doesn't runs
static void Main(string[] args)
{
for (int x = 2; x < 10000; x++)
{
for (int y = 1; y < x; y++)
{
if (x % y != 0)
{
Console.WriteLine(x);
}
}
Console.ReadKey();
}
I don't know where the problem is and also if the for inside resets.
Try this with no bool variable!!!:
static void Main(string[] args)
{
for (int x = 2; x < 10000; x++)
{
int isPrime = 0;
for (int y = 1; y < x; y++)
{
if (x % y == 0)
isPrime++;
if(isPrime == 2) break;
}
if(isPrime != 2)
Console.WriteLine(x);
isPrime = 0;
}
Console.ReadKey();
}
Check Console.ReadKey(); it should be after upper for loop, you can even change condition for upper for loot with <= since 10000 also need to check for prime condition.
Below is the efficient way to print prime numbers between 0 and 10000
using System.IO;
using System;
class Program
{
static void Main()
{
Console.WriteLine("Below are prime numbers between 0 and 10000!");
Console.WriteLine(2);
for(int i=3;i<=10000;i++)
{
bool isPrime=true;
for(int j=2;j<=Math.Sqrt(i);j++)
{
if(i%j==0)
{
isPrime=false;
break;
}
}
if(isPrime)
{
Console.WriteLine(i);
}
}
}
}
Is there any reason that you put Console.ReadKey(); inside of loop?
You should put that out of the loop unless press key during loop.
static void Main(string[] args)
{
for (int x = 2; x < 10000; x++)
{
for (int y = 1; y < x; y++)
{
if (x % y != 0)
{
Console.WriteLine(x);
}
}
}
Console.ReadKey();
}
And probably that code is just print lots of x.
You should to fix it.
The first problem is that x % 1 will always be zero, at least for non-zero x. You need to start the test (inner) loop at one and, for efficiency, stop when you've exceeded the square root of the number itself - if n has a factor f where f > sqrt(n), you would have already found the factor n / f.
The second problem is that you will write out a candidate number every time the remainder is non-zero. So, because 15 % 4 is three, it will be output despite the fact that fifteen is very much a non-prime. It will also be output at 15 % 2, 15 % 4, 15 % 6, 15 % 7, and so on.
The normal (naive) algorithm for prime testing is:
# All numbers to test.
foreach number 2..whatever:
# Assume prime, check all numbers up to squareroot(number).
isPrime = true
foreach test 2..infinity until test * test > number:
# If a multiple, flag as composite and stop inner loop.
if number % test == 0:
isPrime = false
exit foreach
end
end
# If never flagged as composite, output as prime.
if isPrime:
output number
end
Here is simple logic to Print Prime No for any upper limit.
Input : 10 Output : 2 , 3 , 5 ,7
namespace PurushLogics
{
class Purush_PrimeNos
{
static void Main()
{
//Prime No Program
bool isPrime = true;
Console.WriteLine("Enter till which number you would like print Prime Nos\n");
int n = int.Parse(Console.ReadLine());
Console.WriteLine("Prime Numbers : ");
for (int i = 2; i <= n; i++)
{
for (int j = 2; j <= n; j++)
{
if (i != j && i % j == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
Console.Write("\t" + i);
}
isPrime = true;
}
Console.ReadKey();
}
}
}
Here is my code where you can generate and print the prime numbers between two numbers (in between string_starting_number and string_last_number). The lowest possible value for string_starting_number is 0 and the highest possible value for string_last_number is decimal.MaxValue-1=79228162514264337593543950334 and not 79228162514264337593543950335 because of the decimal_a++ command inside a for loop which will result to an overflow error.
Take note that you should input the values in string type in string_starting_number and in string_last_number.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GeneratingPrimeNumbers
{
class Program
{
static void Main(string[] args)
{
string string_starting_number = "1"; //input here your choice of starting number
string string_last_number = "10"; //input here your choice of last number
decimal decimal_starting_number = Convert.ToDecimal(string_starting_number);
decimal decimal_last_number = Convert.ToDecimal(string_last_number);
string primenumbers = "";
ulong ulong_b;
ulong ulong_c;
if (decimal_starting_number <= ulong.MaxValue)
{
ulong ulong_starting_number = Convert.ToUInt64(decimal_starting_number);
ulong ulong_last_number;
if (decimal_last_number > ulong.MaxValue)
{
ulong_last_number = ulong.MaxValue;
}
else
{
ulong_last_number = Convert.ToUInt64(decimal_last_number);
}
if (ulong_starting_number == 0 || ulong_starting_number == 1 || ulong_starting_number == 2 || ulong_starting_number == 3)
{
primenumbers = 2 + " " + 3;
ulong_starting_number = 5;
}
if (ulong_starting_number % 2 == 0)
{
ulong_starting_number++;
}
ulong ulong_a;
for (ulong_a = ulong_starting_number; ulong_a <= ulong_last_number; ulong_a += 2)
{
ulong_b = Convert.ToUInt64(Math.Ceiling(Math.Sqrt(ulong_a)));
for (ulong_c = 3; ulong_c <= ulong_b; ulong_c += 2)
{
if (ulong_a % ulong_c == 0)
{
goto next_value_of_ulong_a;
}
}
primenumbers = primenumbers + " " + ulong_a;
next_value_of_ulong_a:
{
}
}
}
if (decimal_last_number > ulong.MaxValue)
{
string ulong_maximum_value_plus_two = "18446744073709551617";
if (decimal_starting_number <= ulong.MaxValue)
{
decimal_starting_number = Convert.ToDecimal(ulong_maximum_value_plus_two);
}
if (decimal_starting_number % 2 == 0)
{
decimal_starting_number++;
}
decimal decimal_a;
for (decimal_a = decimal_starting_number; decimal_a <= decimal_last_number; decimal_a += 2)
{
ulong_b = Convert.ToUInt64(Math.Ceiling(Math.Sqrt(ulong.MaxValue) * Math.Sqrt(Convert.ToDouble(decimal_a / ulong.MaxValue))));
for (ulong_c = 3; ulong_c <= ulong_b; ulong_c += 2)
{
if (decimal_a % ulong_c == 0)
{
goto next_value_of_decimal_a;
}
}
primenumbers = primenumbers + " " + decimal_a;
next_value_of_decimal_a:
{
}
}
}
Console.WriteLine(primenumbers);
Console.ReadKey();
}
}
}
I am trying to get a count of all the times a byte sequences occurs in another byte sequences. It cannot however re-use a bytes if it already counted them. For example given the string
k.k.k.k.k.k. let's assume the byte sequence was k.k it would then find only 3 occurrences rather than 5 because they would be broke down like: [k.k].[k.k].[k.k]. and not like [k.[k].[k].[k].[k].k] where they over lap and essentially just shift 2 to the right.
Ideally the idea is to get an idea how a compression dictionary or run time encoding might look. so the goal would be to get
k.k.k.k.k.k. down to just 2 parts, as (k.k.k.) is the biggest and best symbol you can have.
Here is source so far:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;
static class Compression
{
static int Main(string[] args)
{
List<byte> bytes = File.ReadAllBytes("ok.txt").ToList();
List<List<int>> list = new List<List<int>>();
// Starting Numbers of bytes - This can be changed manually.
int StartingNumBytes = bytes.Count;
for (int i = StartingNumBytes; i > 0; i--)
{
Console.WriteLine("i: " + i);
for (int ii = 0; ii < bytes.Count - i; ii++)
{
Console.WriteLine("ii: " + i);
// New pattern comes with refresh data.
List<byte> pattern = new List<byte>();
for (int iii = 0; iii < i; iii++)
{
pattern.Add(bytes[ii + iii]);
}
DisplayBinary(bytes, "red");
DisplayBinary(pattern, "green");
int matches = 0;
// foreach (var position in bytes.ToArray().Locate(pattern.ToArray()))
for (int position = 0; position < bytes.Count; position++) {
if (pattern.Count > (bytes.Count - position))
{
continue;
}
for (int iiii = 0; iiii < pattern.Count; iiii++)
{
if (bytes[position + iiii] != pattern[iiii])
{
//Have to use goto because C# doesn't support continue <level>
goto outer;
}
}
// If it made it this far, it has found a match.
matches++;
Console.WriteLine("Matches: " + matches + " Orig Count: " + bytes.Count + " POS: " + position);
if (matches > 1)
{
int numBytesToRemove = pattern.Count;
for (int ra = 0; ra < numBytesToRemove; ra++)
{
// Remove it at the position it was found at, once it
// deletes the first one, the list will shift left and you'll need to be here again.
bytes.RemoveAt(position);
}
DisplayBinary(bytes, "red");
Console.WriteLine(pattern.Count + " Bytes removed.");
// Since you deleted some bytes, set the position less because you will need to redo the pos.
position = position - 1;
}
outer:
continue;
}
List<int> sublist = new List<int>();
sublist.Add(matches);
sublist.Add(pattern.Count);
// Some sort of calculation to determine how good the symbol was
sublist.Add(bytes.Count-((matches * pattern.Count)-matches));
list.Add(sublist);
}
}
Display(list);
Console.Read();
return 0;
}
static void DisplayBinary(List<byte> bytes, string color="white")
{
switch(color){
case "green":
Console.ForegroundColor = ConsoleColor.Green;
break;
case "red":
Console.ForegroundColor = ConsoleColor.Red;
break;
default:
break;
}
for (int i=0; i<bytes.Count; i++)
{
if (i % 8 ==0)
Console.WriteLine();
Console.Write(GetIntBinaryString(bytes[i]) + " ");
}
Console.WriteLine();
Console.ResetColor();
}
static string GetIntBinaryString(int n)
{
char[] b = new char[8];
int pos = 7;
int i = 0;
while (i < 8)
{
if ((n & (1 << i)) != 0)
{
b[pos] = '1';
}
else
{
b[pos] = '0';
}
pos--;
i++;
}
//return new string(b).TrimStart('0');
return new string(b);
}
static void Display(List<List<int>> list)
{
//
// Display everything in the List.
//
Console.WriteLine("Elements:");
foreach (var sublist in list)
{
foreach (var value in sublist)
{
Console.Write("{0,4}", value);
}
Console.WriteLine();
}
//
// Display total count.
//
int count = 0;
foreach (var sublist in list)
{
count += sublist.Count;
}
Console.WriteLine("Count:");
Console.WriteLine(count);
}
static public int SearchBytePattern(byte[] pattern, byte[] bytes)
{
int matches = 0;
// precomputing this shaves some seconds from the loop execution
int maxloop = bytes.Length - pattern.Length;
for (int i = 0; i < maxloop; i++)
{
if (pattern[0] == bytes[i])
{
bool ismatch = true;
for (int j = 1; j < pattern.Length; j++)
{
if (bytes[i + j] != pattern[j])
{
ismatch = false;
break;
}
}
if (ismatch)
{
matches++;
i += pattern.Length - 1;
}
}
}
return matches;
}
}
Refer to the post to get the non binary of the file should be, here is the binary data:
011010110010111001101011001011100110101100101110011010110010111001101011001011100110101100101110 I am hope to have it smaller than how it started.
private static int CountOccurences(byte[] target, byte[] pattern)
{
var targetString = BitConverter.ToString(target);
var patternString = BitConverter.ToString(pattern);
return new Regex(patternString).Matches(targetString).Count;
}
With this solution you'd have access to the individual indexes that matched (while enumerating) or you could call Count() on the result to see how many matches there were:
public static IEnumerable<int> Find<T>(T[] pattern, T[] sequence, bool overlap)
{
int i = 0;
while (i < sequence.Length - pattern.Length + 1)
{
if (pattern.SequenceEqual(sequence.Skip(i).Take(pattern.Length)))
{
yield return i;
i += overlap ? 1 : pattern.Length;
}
else
{
i++;
}
}
}
Call it with overlap: false to solve your problem or overlap: true to see the overlapped matches (if you're interested.)
I have a couple of other methods with slightly different API (along with better performance) here, including one that work directly on streams of bytes.
quick and dirty with no regex. although i'm not sure if it answers the intent of the question, it should be relatively fast. i think i am going to run some timing tests against regex to see for sure the relative speeds:
private int CountOccurrences(string TestString, string TestPattern)
{
int PatternCount = 0;
int SearchIndex = 0;
if (TestPattern.Length == 0)
throw new ApplicationException("CountOccurrences: Unable to process because TestPattern has zero length.");
if (TestString.Length == 0)
return 0;
do
{
SearchIndex = TestString.IndexOf(TestPattern, SearchIndex);
if (SearchIndex >= 0)
{
++PatternCount;
SearchIndex += TestPattern.Length;
}
}
while ((SearchIndex >= 0) && (SearchIndex < TestString.Length));
return PatternCount;
}
private void btnTest_Click(object sender, EventArgs e)
{
string TestString1 = "k.k.k.k.k.k.k.k.k.k.k.k";
string TestPattern1 = "k.k";
System.Console.WriteLine(CountOccurrences(TestString1, TestPattern1).ToString()); // outputs 6
System.Console.WriteLine(CountOccurrences(TestString1 + ".k", TestPattern1).ToString()); // still 6
System.Console.WriteLine(CountOccurrences(TestString1, TestPattern1 + ".").ToString()); // only 5
}