How would I convert this if-code to a for-loop? - c#

I was wondering how I could possibly convert this holy nest of if and && checks, into a simple for-loop?
Any solutions are appreciated, since I'm completely lost and my brain has given up.
if (localModulebytes[i + 1] == convertedByteArray[1]
&& localModulebytes[i + 2] == convertedByteArray[2]
&& localModulebytes[i + 3] == convertedByteArray[3]
&& localModulebytes[i + 4] == convertedByteArray[4]
&& localModulebytes[i + 5] == convertedByteArray[5]
&& localModulebytes[i + 6] == convertedByteArray[6]
&& localModulebytes[i + 7] == convertedByteArray[7]
&& localModulebytes[i + 8] == convertedByteArray[8]
&& localModulebytes[i + 9] == convertedByteArray[9]
)
{
// Code
similarities++;
}
I tried this code, which gave similaries that were way beyond the ones from my bee-nest to code:
for (var j = 1; j < 9; j++)
{
if (localModulebytes[i + j] == convertedByteArray[j])
{
similarities++;
}
}

That's because you increase the similarities more times in the loop. You can try something like this
var sim = true;
for (var j = 1; j < 9; j++) {
if (localModulebytes[i + j] != convertedByteArray[j]) {
sim = false;
break;
}
}
if(sim) similarities++;

GreenChicken's answer is the way to do this with a for loop, but there's also LINQ:
if (Enumerable.Range(1,9).All(j => localModulebytes[i + j] == convertedByteArray[j])) {
++similarities;
}
Which isn't necessarily better, but I'll offer the alternative.

To convert your initial code to a looped check, you could do something like:
var similar = true;
for ( var j = 1; j < 10; j++ )
if ( localModulebytes[i + j] != convertedByteArray[j] )
{
similar = false;
break;
}
if (similar) similarities++;
But, considering you used the variable name similarities I suspected you wanted to count how many of those items were the same, not all of the 9. Your follow-up comment showed my assumption to be incorrect.

Related

Why is the length usually calculated this way for BubbleSort algorithm?

So I'm just trying to understand how bubblesort (it may help me with other algorithms when I see this kind of stuff as well) works with the nested for loop.
I noticed that most people will do the loops like so:
public static void BubbleSort(int[] arr, int arr_size)
{
int i, j, temp;
bool swapped;
for (i = 0; i < arr_size - 1; i++)
{
swapped = false;
for (j = 0; j < arr_size - i -1; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
if (swapped == false)
{
break;
}
}
}
I have done it like this (only slightly different; note the nested loop size check:
public static void BubbleSort(int[] arr, int arr_size)
{
int i, j, temp;
bool swapped;
for (i = 0; i < arr_size - 1; i++)
{
swapped = false;
for (j = 0; j < arr_size - 1; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
if (swapped == false)
{
break;
}
}
}
And it seems to work with every check I've done so far.
I guess to sum it up, I am wondering why the first loop would be the size - 1 (I know this is because of the whitespace at the end) and the nested loop will be the size - i - 1 (at least I have seen this a lot). Thanks for any feedback !
The effect of the inner loop:
for (j = 0; j < arr_size - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
is finding the maximum element in the array and placing it to the last position. Hence, for i == 0 (the index from the outer loop), it moves it to the last array position. For i == 1, the array's overall maximum element is already at the last array position, and hence it does not need to be processed again. For i == 2 etc. the situation is the same. In other words, the array is being sorted from 'backward' by 'bubbling' (hence the algorithm's name) the maximum elements up each iteration.
There is a nice step-by-step example on Wikipedia.
In your second example, by omitting the - i in the for loop clause, you are just unnecessarily checking array elements that are already in place from previous (outer loop) iterations and hence cannot change anymore.

Assigning value in 2D array not working - swapping indices

Basically I have a 2D array of which looks like this:
0 x x -1
x 0 x x
x x 0 x
-1 x x 0
If using two for loops (nested) with indices 'i' and 'j' and if they equal each other, e.g. i and j = 2, then the value placed in array[i, j] will be '0'. If 'i' = array.Length - 1 and 'j' = 0 (or vice versa) then value in array[i, j] will be -1.
What I'm trying to do is place random numbers between 1 and 20 in the places denoted by 'x'. I know how to do this, but, I want the numbers in the 'x' on the other side of the '0's to be equal. For example,
value # i = 2, j = 3 is equal to value # i = 3, j = 2.
Now I've already done this in a previous program by doing:
array[j, i] = array[i, j]
But for some reason in this new program this no longer works, at all.
What's wrong?
Here's the actual code:
size = r.Next(4, 8);
V = new int[size, size];
for (int i = 0; i < size; i++)
{
s = "";
for (int j = 0; j < size; j++)
{
if (i == j)
{
V[i, j] = 0;
}
else if ((i == size - 1 && j == 0) || (i == 0 && j == size - 1))
{
V[i, j] = -1;
}
else
{
V[i, j] = r.Next(1, 20);
}
V[j, i] = V[i, j];
s += "|" + V[i, j] + "|";
}
Console.WriteLine(s);
}
Console.Read();
the problem with the algorithm is that its re-overwriting (overwriting twice) the lower half of the matrix.
try this loop instead:
for (var i = 0; i < size; i++)
{
s = "|";
for (int j = 0; j < size; j++)
{
if (i == j)
{
V[i, j] = 0;
}
else if (i == size - 1 && j == 0 || i == 0 && j == size - 1)
{
V[i, j] = -1;
}
else if (i < j)
{
V[i, j] = r.Next(1, 20);
V[j, i] = V[i, j];
}
s += $"{V[i, j],2}|";
}
Console.WriteLine(s);
}

How can I change the name of the object in this case?

I want to make my own calendar with C#.
Because of that i want to create as much panels as the month has days.
I tried to do it with a for loop, but it doesn't work.
I think the problem is, that the name of the object never changes.
But how can I change the name of the object every time it loops through?
public void createPanel()
{
if (DateTime.Now.Month == 1 || DateTime.Now.Month == 3 || DateTime.Now.Month == 5 || DateTime.Now.Month == 7 || DateTime.Now.Month == 8 || DateTime.Now.Month == 10 || DateTime.Now.Month == 12)
{
for (int i = 0; i == 31; i++)
{
int locationX = 12;
int locationY = 74;
//Create Panel
Panel test = new Panel();
//Fill Panel
test.Name = "panel" + i;
test.Width = 200;
test.Height = 100;
test.BackColor = Color.White;
test.Location = new System.Drawing.Point(locationX, locationY);
this.Controls.Add(test);
test.Show();
if(i == 7 || i == 14 || i == 21)
{
locationY += 106;
locationX = 12;
}
locationX += 206;
}
}
for (int i = 0; i == 31; i++)
is wrong. You will never reach the inside of the for loop, since i is equal to 0 and expected to be 31.
Maybe you meant:
for (int i = 0; i <= 31; i++)
I'm assuming there's lots of other issues with your code, but fix this first and maybe open new and more specific questions.
Instead of hard coding the months in your if statement, you might want to use this instead:
DateTime.DaysInMonth(year, month);
So your loop should look something like:
var numDays = DateTime.DaysInMonth(selectedYear, selectedMonth);
for (int i = 0; i < numDays; i++)
{
// your code here
}
You can get the selected year and month from DateTime.Today, or just let the user select it for themselves.

Bubble sort string array c#

I have this project where I have to sort some txt files, most of them are numbers but one of them is a collection of months. I have the code that sorts the others but not the file containing the months. So i need this code to be changed so I can sort a string array any advice would be brilliant thank you!
public void SortArray(decimal[] numbers)
{
bool swap;
decimal temp;
do
{
swap = false;
for(int index = 0; index < (numbers.Length - 1); index ++)
{
if ( numbers[index] > numbers[index+1])
{
//swap
temp = numbers[index];
numbers[index] = numbers[index + 1];
numbers[index + 1] = temp;
swap = true;
}
}
} while (swap == true);
}
If you have an string array like this:
string[] s = {"bbb", "ccc", "aaa"};
The shorter way to sort it, using:
Array.Sort(s);
and the long way to sort it, using:
for (var i = 1; i < s.Length; i++)
{
for (var j = 0; j < s.Length - i; j++)
{
if (string.Compare(s[j], s[j + 1], StringComparison.Ordinal) <= 0) continue;
var temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
public void BubbleSortArrayString(string[] letters) //change here
{
bool swap;
string temp; //change this too
do
{
swap = false;
for (int index = 0; index < (letters.Length - 1); index++)
{
if (letters[index] > letters[index + 1]) //if first number is greater then second then swap
{
//swap
temp = letters[index];
letters[index] = letters[index + 1];
letters[index + 1] = temp;
swap = true;
}
}
} while (swap == true);
}
used this code... forgot some answered last time i tried this

Damerau–Levenshtein distance algorithm, disable counting of delete

How can i disable counting of deletion, in this implementation of Damerau-Levenshtein distance algorithm, or if there is other algorithm already implemented please point me to it.
Example(disabled deletion counting):
string1: how are you?
string2: how oyu?
distance: 1 (for transposition, 4 deletes doesn't count)
And here is the algorithm:
public static int DamerauLevenshteinDistance(string string1, string string2, int threshold)
{
// Return trivial case - where they are equal
if (string1.Equals(string2))
return 0;
// Return trivial case - where one is empty
if (String.IsNullOrEmpty(string1) || String.IsNullOrEmpty(string2))
return (string1 ?? "").Length + (string2 ?? "").Length;
// Ensure string2 (inner cycle) is longer_transpositionRow
if (string1.Length > string2.Length)
{
var tmp = string1;
string1 = string2;
string2 = tmp;
}
// Return trivial case - where string1 is contained within string2
if (string2.Contains(string1))
return string2.Length - string1.Length;
var length1 = string1.Length;
var length2 = string2.Length;
var d = new int[length1 + 1, length2 + 1];
for (var i = 0; i <= d.GetUpperBound(0); i++)
d[i, 0] = i;
for (var i = 0; i <= d.GetUpperBound(1); i++)
d[0, i] = i;
for (var i = 1; i <= d.GetUpperBound(0); i++)
{
var im1 = i - 1;
var im2 = i - 2;
var minDistance = threshold;
for (var j = 1; j <= d.GetUpperBound(1); j++)
{
var jm1 = j - 1;
var jm2 = j - 2;
var cost = string1[im1] == string2[jm1] ? 0 : 1;
var del = d[im1, j] + 1;
var ins = d[i, jm1] + 1;
var sub = d[im1, jm1] + cost;
//Math.Min is slower than native code
//d[i, j] = Math.Min(del, Math.Min(ins, sub));
d[i, j] = del <= ins && del <= sub ? del : ins <= sub ? ins : sub;
if (i > 1 && j > 1 && string1[im1] == string2[jm2] && string1[im2] == string2[jm1])
d[i, j] = Math.Min(d[i, j], d[im2, jm2] + cost);
if (d[i, j] < minDistance)
minDistance = d[i, j];
}
if (minDistance > threshold)
return int.MaxValue;
}
return d[d.GetUpperBound(0), d.GetUpperBound(1)] > threshold
? int.MaxValue
: d[d.GetUpperBound(0), d.GetUpperBound(1)];
}
public static int DamerauLevenshteinDistance( string string1
, string string2
, int threshold)
{
// Return trivial case - where they are equal
if (string1.Equals(string2))
return 0;
// Return trivial case - where one is empty
// WRONG FOR YOUR NEEDS:
// if (String.IsNullOrEmpty(string1) || String.IsNullOrEmpty(string2))
// return (string1 ?? "").Length + (string2 ?? "").Length;
//DO IT THIS WAY:
if (String.IsNullOrEmpty(string1))
// First string is empty, so every character of
// String2 has been inserted:
return (string2 ?? "").Length;
if (String.IsNullOrEmpty(string2))
// Second string is empty, so every character of string1
// has been deleted, but you dont count deletions:
return 0;
// DO NOT SWAP THE STRINGS IF YOU WANT TO DEAL WITH INSERTIONS
// IN A DIFFERENT MANNER THEN WITH DELETIONS:
// THE FOLLOWING IS WRONG FOR YOUR NEEDS:
// // Ensure string2 (inner cycle) is longer_transpositionRow
// if (string1.Length > string2.Length)
// {
// var tmp = string1;
// string1 = string2;
// string2 = tmp;
// }
// Return trivial case - where string1 is contained within string2
if (string2.Contains(string1))
//all changes are insertions
return string2.Length - string1.Length;
// REVERSE CASE: STRING2 IS CONTAINED WITHIN STRING1
if (string1.Contains(string2))
//all changes are deletions which you don't count:
return 0;
var length1 = string1.Length;
var length2 = string2.Length;
// PAY ATTENTION TO THIS CHANGE!
// length1+1 rows is way too much! You need only 3 rows (0, 1 and 2)
// read my explanation below the code!
// TOO MUCH ROWS: var d = new int[length1 + 1, length2 + 1];
var d = new int[2, length2 + 1];
// THIS INITIALIZATION COUNTS DELETIONS. YOU DONT WANT IT
// or (var i = 0; i <= d.GetUpperBound(0); i++)
// d[i, 0] = i;
// But you must initiate the first element of each row with 0:
for (var i = 0; i <= 2; i++)
d[i, 0] = 0;
// This initialization counts insertions. You need it, but for
// better consistency of code I call the variable j (not i):
for (var j = 0; j <= d.GetUpperBound(1); j++)
d[0, j] = j;
// Now do the job:
// for (var i = 1; i <= d.GetUpperBound(0); i++)
for (var i = 1; i <= length1; i++)
{
//Here in this for-loop: add "%3" to evey term
// that is used as first index of d!
var im1 = i - 1;
var im2 = i - 2;
var minDistance = threshold;
for (var j = 1; j <= d.GetUpperBound(1); j++)
{
var jm1 = j - 1;
var jm2 = j - 2;
var cost = string1[im1] == string2[jm1] ? 0 : 1;
// DON'T COUNT DELETIONS! var del = d[im1, j] + 1;
var ins = d[i % 3, jm1] + 1;
var sub = d[im1 % 3, jm1] + cost;
// Math.Min is slower than native code
// d[i, j] = Math.Min(del, Math.Min(ins, sub));
// DEL DOES NOT EXIST
// d[i, j] = del <= ins && del <= sub ? del : ins <= sub ? ins : sub;
d[i % 3, j] = ins <= sub ? ins : sub;
if (i > 1 && j > 1 && string1[im1] == string2[jm2] && string1[im2] == string2[jm1])
d[i % 3, j] = Math.Min(d[i % 3, j], d[im2 % 3, jm2] + cost);
if (d[i % 3, j] < minDistance)
minDistance = d[i % 3, j];
}
if (minDistance > threshold)
return int.MaxValue;
}
return d[length1 % 3, d.GetUpperBound(1)] > threshold
? int.MaxValue
: d[length1 % 3, d.GetUpperBound(1)];
}
here comes my explanation why you need only 3 rows:
Look at this line:
var d = new int[length1 + 1, length2 + 1];
If one string has the length n and the other has the length m, then your code needs a space of (n+1)*(m+1) integers. Each Integer needs 4 Byte. This is waste of memory if your strings are long. If both strings are 35.000 byte long, you will need more than 4 GB of memory!
In this code you calculate and write a new value for d[i,j]. And to do this, you read values from its upper neighbor (d[i,jm1]), from its left neighbor (d[im1,j]), from its upper-left neighbor (d[im1,jm1]) and finally from its double-upper-double-left neighbour (d[im2,jm2]). So you just need values from your actual row and 2 rows before.
You never need values from any other row. So why do you want to store them? Three rows are enough, and my changes make shure, that you can work with this 3 rows without reading any wrong value at any time.
I would advise not rewriting this specific algorithm to handle specific cases of "free" edits. Many of them radically simplify the concept of the problem to the point where the metric will not convey any useful information.
For example, when substitution is free the distance between all strings is the difference between their lengths. Simply transmute the smaller string into the prefix of the larger string and add the needed letters. (You can guarantee that there is no smaller distance because one insertion is required for each character of edit distance.)
When transposition is free the question reduces to determining the sum of differences of letter counts. (Since the distance between all anagrams is 0, sorting the letters in each string and exchanging out or removing the non-common elements of the larger string is the best strategy. The mathematical argument is similar to that of the previous example.)
In the case when insertion and deletion are free the edit distance between any two strings is zero. If only insertion OR deletion is free this breaks the symmetry of the distance metric - with free deletions, the distance from a to aa is 1, while the distance from aa to a is 1. Depending on the application this could possibly be desirable; but I'm not sure if it's something you're interested in. You will need to greatly alter the presented algorithm because it makes the mentioned assumption of one string always being longer than the other.
Try to change var del = d[im1, j] + 1; to var del = d[im1, j];, I think that solves your problem.

Categories