matching characters in strings in visual C# - c#

I'm working on visual C#
to calculate the word error rate
I have one textbox for the refrence which is the correct sentance
and one for the hypothesis which is wrong one.
in order to calculate WER I need to calculate :
substitution : the word that has been changed which was my first question
Insert : the words that had been inserted in the sentence
Deleted: the words that had been deleted from the original sentence
For EX:
refrence: This is a NPL program.
hypothesis: it is an NPL cool.
it: substitution
is: correct
an :substitution
NPL:correct
program: deleted
cool: inserted
I tried the algorithm that dasblinkenlight proposed ( thank you so much by the way )
I worked but there is a runtime error I couldn't figure it out, in line
int x= Compute(buffer[j], buffer_ref[i]);
Index was outside the bounds of the array.
and here is my code :
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 WindowsFormsApplication1
{
public partial class Form1 : Form
{
string [] hyp = new string[20];
string [] refrence = new string[20];
string [] Anser= new string[20];
string[] buffer = new string[20];
string[] buffer_ref = new string[20];
int count = 0; // number of words
string ref2=" " ;
string hyp2 = " ";
string Anser2 = " ";
string buffer2 = " ";
int corecct_c=0;
int corecct_d = 0;
int corecct_i = 0;
//====================================================================
public Form1()
{
InitializeComponent();
for (int i = 0; i <= 19; ++i)
{
hyp[i] = null;
buffer[i] = null;
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
refrence = this.textBox2.Text.Split(' ');
buffer_ref = this.textBox2.Text.Split(' ');
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
hyp = this.textBox1.Text.Split(' ');
buffer = this.textBox1.Text.Split(' ');
//hyp = this.textBox1.Text;
// fname1.Add(this.textBox1.Text);
}
public void correct(string[] R)
{
for (int i = 0; (i <= 19) && (R[i] != "."); ++i)
{
if (buffer[i] == refrence[i])
{ buffer[i] = "0";
buffer_ref[i] = "0";
corecct_c = corecct_c + 1;
Anser[i] = "C";
}
}
}
// function that compute 2 strings
public static int Compute(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
public void sub(){
for (int j = 0;j<=19;j++)
{
if (buffer[j].IndexOf("0") != -1)
{
for (int i = 0; i <= 19; i++)
{
if (buffer_ref[j].IndexOf("0") != -1)
{
int x= Compute(buffer[j], buffer_ref[i]);
if (x > 3)
{
buffer[j] = "0";
Anser[j] = "S";
}
}//end if
}
}//end if
}//end for
}// end fun
private void button1_Click(object sender, EventArgs e)
{
correct(refrence);
sub();
for (int i = 0; (i <= 19) && (refrence[i] != "."); ++i)
{
//loop intialize
ref2 = ref2 + " " + refrence[i];
hyp2 = hyp2 + " " + hyp[i];
Anser2 = Anser2 + " " + Anser[i];
buffer2 = buffer2 + " " + buffer[i];
count++;
}
listBox1.Items.Add(" Refrence :" + ref2);
listBox1.Items.Add(" HYp :" + hyp2);
listBox1.Items.Add(" Anser:" + Anser2);
listBox1.Items.Add(" buffer:" + buffer2);
listBox1.Items.Add(count);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
can you help me please ?

There is a built-in way to test if two lines are identical, but there is no built-in way to tell if two lines are similar. You need to implement an algorithm that measures string similarity, such as the Levenshtein Distance - a very common Edit Distance algorithm. Lines with small edit distance can be declared similar depending on some threshold specific to your requirements.

You'll need to use an algorithm that compares the "distance" between two strings:
The closeness of a match is measured in terms of the number of
primitive operations necessary to convert the string into an exact
match. This number is called the edit distance between the string and
the pattern. The usual primitive operations are:
insertion: cot → coat
deletion: coat → cot
substitution: coat → cost

Related

How to calculate letters 'u' count in given map

Using Visual Studio C# ASP.NET I need to calculate how many letters 'u' does each path has.
Input :
zzzzzzzzzuzuzzz
uuzuuzuuzuuuzzz
zuzuzzuzuuzuzuz
zuzuzzuzzuzuuuz
zuuuuuuuzuzzzzz
zzzzzuuuzzzzzzz
Picture of the map and given data for better quality
Output :
2
21
14
I have this code right now.
It finds the paths (there's 2 total), but now I need to find how many letters 'u' does each path has.
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string path = "App_Data/Map.txt";
string[] lines = File.ReadAllLines(HttpContext.Current.Server.MapPath(path));
int Width = int.Parse(lines[0]);
int Height = int.Parse(lines[1]);
Label4.Text = "Width: " + Width.ToString();
Label5.Text = "Height: " + Height.ToString();
}
protected void Button1_Click(object sender, EventArgs e)
{
string path = "App_Data/Map.txt";
string map = File.ReadAllText(HttpContext.Current.Server.MapPath(path));
char[][] grid = GetGridGFromMap(map);
int NumberOfMoles = TaskUtils.LettersIsU(grid);
Label1.Text = "Letters U count: " + NumberOfMoles.ToString();
}
private char[][] GetGridGFromMap(string map)
{
string[] lines = map.Split('\n');
char[][] grid = new char[lines.Length][];
for(int i =0; i < lines.Length; i++)
{
grid[i] = lines[i].ToCharArray();
}
return grid;
}
}
class TaskUtils
{
public static int LettersIsU(char[][] grid)
{
int count = 0;
for (int i = 0; i < grid.Length; i++)
{
for (int j = 0; j < grid[i].Length; j++)
{
if (grid[i][j] == 'u')
{
count++;
SetCountedLetters(grid, i, j);
}
}
}
return count;
}
private static void SetCountedLetters(char[][] grid, int i, int j)
{
if (i < 0 || i >= grid.Length || j < 0 || j >= grid[i].Length || grid[i][j] == 'z')
return;
grid[i][j] = 'z';
SetCountedLetters(grid, i + 1, j);
SetCountedLetters(grid, i - 1, j);
SetCountedLetters(grid, i, j + 1);
SetCountedLetters(grid, i, j - 1);
}
}
}

How to find indexes of the most small duplicated value in a ListBox?

I tried everything i could find online and spent a lot of time on this but I cant do it.
It's a form with a ListBox with random numbers from 20 to 30 and I need to find the min and show its position. The hard part is that if i have 2 of the same number or 3 of them, then I don't know what to do and I tried almost everything.
This is the code i did so far:
Random r = new Random();
int[] a;
private void button2_Click(object sender, EventArgs e)
{
int i;
a = new int[10];
listBox1.Items.Clear();
for (i = 0; i < 10; i++)
{
a[i] = r.Next(20, 31);
listBox1.Items.Add(a[i]);
}
}
private void button1_Click(object sender, EventArgs e)
{
int[] b;
b = new int[10];
int mini=3435, i,index=0;
b = (int[])a.Clone();
for (i = 1; i < 10; i++)
{
if (b[i] < mini)
{
mini = b[i];
}
}
index = Array.IndexOf(b, mini);
label2.Text = Convert.ToString("la pozitia: " + index);
label1.Text = Convert.ToString("Minimul este: " +mini );
}
This is how it should look:
Since you simply want to output the positions as a comma seperate list, you can use a separate string for the list of positions that match:
int[] b;
b = new int[10];
int mini = int.MaxValue, i, index = 0;
string miniList = "";
b = (int[])a.Clone();
for (i = 0; i < 10; i++)
{
if (b[i] < mini)
{
mini = b[i];
miniList = "";
}
if (b[i] == mini)
{
if (!string.IsNullOrEmpty(miniList))
{
miniList += ", ";
}
miniList += i;
}
}
label1.Text = Convert.ToString("Minimul este: " + mini);
label2.Text = Convert.ToString("la pozitia: " + miniList);
NOTE: I also set the mini value to int.MaxValue to begin with so code should work with any number range

Why the loops wont work in my Windows Form Application? [duplicate]

This question already has an answer here:
Why do I only see some of my text output when my Window Forms application has a loop?
(1 answer)
Closed 7 years ago.
I am trying to combine prime numbers, even numbers and odd numbers and their results in a Windows Form Application. I have tested the code in Console but in Windows Form it will not loop to the next applicable number. For example: In console 1 - 10 in primes would result in "2, 3, 5, 7", however in Windows Form Application it will result in "2"
public partial class NumberCalc : Form
{
public NumberCalc()
{
InitializeComponent();
}
private void Primes_CheckedChanged(object sender, EventArgs e)
{
{
int f = Convert.ToInt32(Min.Text);
int i = Convert.ToInt32(Max.Text);
bool isPrime = true;
for (f = 0; f <= i; f++)
{
for (int j = 2; j <= i; j++)
{
if (f != j && f % j == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
string final;
final = ("The Prime Numbers Are:" + f);
Result.Text = final;
}
isPrime = true;
}
}
}
private void Result_TextChanged(object sender, EventArgs e)
{
}
private void Min_TextChanged(object sender, EventArgs e)
{
}
private void Evens_CheckedChanged(object sender, EventArgs e)
{
int f = Convert.ToInt32(Min.Text);
int i = Convert.ToInt32(Max.Text);
for (f = 0; f >= i; f++)
{
if (f % 2 == 0)
{
{
string final;
final = ("The Even Numbers Are:" + f);
Result.Text = final;
}
}
}
}
private void Odds_CheckedChanged(object sender, EventArgs e)
{
int f = Convert.ToInt32(Min.Text);
int i = Convert.ToInt32(Max.Text);
for (f = 0; f <= i; f++)
{
if (f % 2 != 0)
{
{
string final;
final = ("The Even Numbers Are:" + f);
Result.Text = final;
}
}
}
}
}
}
Change your code to:
private void Primes_CheckedChanged(object sender, EventArgs e)
{
{
string final = "The Prime Numbers Are:";// you need to keep the result out of the loop instead of reset it everytime
int f = Convert.ToInt32(Min.Text);
int i = Convert.ToInt32(Max.Text);
bool isPrime = true;
for (f = 0; f <= i; f++)// why set f=0 here ? Does not f = min already ?
{
for (int j = 2; j <= i; j++)// maybe j < f not j <= i
{
if (f != j && f % j == 0)// then remove f != j here
{
isPrime = false;
break;
}
}
if (isPrime)
final = final + " " + f;// then add your found number to the result here
isPrime = true;
}
Result.Text = final;
}
}
Even and Odd goes the same.BTW 1 is not prime number, am I right ?
I would combine your loops/checks into one method like this:
private void Form1_Load(object sender, EventArgs e)
{
this.Primes.CheckedChanged += Options_CheckedChanged;
this.Evens.CheckedChanged += Options_CheckedChanged;
this.Odds.CheckedChanged += Options_CheckedChanged;
this.Min.TextChanged += Range_Changed;
this.Max.TextChanged += Range_Changed;
CheckNumbers();
}
private void Range_Changed(object sender, EventArgs e)
{
CheckNumbers();
}
private void Options_CheckedChanged(object sender, EventArgs e)
{
CheckNumbers();
}
private void CheckNumbers()
{
int min, max;
try
{
min = Convert.ToInt32(Min.Text);
max = Convert.ToInt32(Max.Text);
}
catch (Exception)
{
Results.Text = "Invalid Range!";
return;
}
List<int> lstPrimes = new List<int>();
List<int> lstEvens = new List<int>();
List<int> lstOdds = new List<int>();
if (Primes.Checked || Evens.Checked || Odds.Checked)
{
bool isPrime;
for (int f = min; f <= max; f++)
{
if (Primes.Checked)
{
isPrime = true;
for (int j = 2; j <= max; j++)
{
if (f != j && f % j == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
lstPrimes.Add(f);
}
}
int modResult = f % 2;
if (Evens.Checked && modResult == 0)
{
lstEvens.Add(f);
}
if (Odds.Checked && modResult != 0)
{
lstOdds.Add(f);
}
}
}
StringBuilder sb = new StringBuilder();
if (Primes.Checked)
{
sb.AppendLine("The Prime Numbers Are:" + String.Join(",", lstPrimes));
}
if (Evens.Checked)
{
sb.AppendLine("The Even Numbers Are:" + String.Join(",", lstEvens));
}
if (Odds.Checked)
{
sb.AppendLine("The Odd Numbers Are:" + String.Join(",", lstOdds));
}
Results.Text = sb.ToString();
}
I think LINQ is more suitable here, You can try this:
int[] numbers = Enumerable.Range(f, i-f).ToArray<int>();
string oddNumbers=string.Join(",", from number in numbers
where (number % 2)!=0
select number);
string evenNumbers = string.Join(",", from number in numbers
where (number % 2) == 0
select number);
Result.Text = "The Even Numbers Are:" + evenNumbers;
Result.Text = "The Odd Numbers Are:" + oddNumbers;
Updates for Prime number:
var primeNumbers= string.Join(",",from number in numbers
where (IsPrime(number))
select number);
Where IsPrime() method is defined as follows?
private static bool IsPrime(int number)
{
for (int i = 2; i < number; i ++)
if (number % i == 0) return false;
return true;
}

Cartesian Product

I am currently writing a program dealing with Cartesian Product. I have figured out the first part of inputting two numbers and getting the set for each number inputted. But what i need is the final product of both numbers.
In other words I am looking for my product to look something like this:
{ (1,1), (1,2), (1,3), ... }
Here is my code for right now with the last part of where I need help.
private void btnCal_Click(object sender, EventArgs e)
{
int iN, iM, i, j;
string strOut1, strOut2, strOut;
bool bN, bM;
bN = int.TryParse(txtN.Text, out iN);
bM = int.TryParse(txtM.Text, out iM);
if (bN && bM && iM > 0 && iM > 0)
{
strOut1 = "{1";
for (i = 2; i <= iM; i++)
strOut1 += "," + i;
txtFirst.Text = strOut1 + "}";
strOut2 = "{1";
for (j = 2; j <= iN; j++)
strOut2 += "," + j;
txtSecond.Text = strOut2 + "}";
}
//HERE IS WHERE THE PRODUCT CODE WILL BE AT
if (bN && bM && iM > 0 && iM > 0)
{
for (i = 2; i <= iM; i++)
for (j = 2; j <= iN; j++)
strOut = ("strOut1");
txtProduct.Text = strOut + " }";
}
else
txtProduct.Text = "Please enter valid number.";
}
With LINQ, all things are possible:
using System;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCal_Click(object sender, EventArgs e)
{
var tuples = from m in Enumerable.Range(1, int.Parse(txtM.Text))
from n in Enumerable.Range(1, int.Parse(txtN.Text))
select Tuple.Create(m, n);
txtProduct.Text = "{" + String.Join(",", tuples) + "}";
}
}
}

c# writing x's using a loop

i have made textbox 1 and 2 to create a row of x's starting with one x, then enter and then xx and so on..
now i need textbox 3 and 4 to display the same but it has to do it beginning from 10 x's.
this is what i have:
namespace Vierkant
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button_Click_1(object sender, RoutedEventArgs e)
{
string x = "X";
for (int i = 0; i < 10; i++)
{
if ( i == 0)
{
x = "X";
}
else
{
x += "X";
}
txt_box1.Text += (x) + "\n";
txt_box2.Text += (x) + "\n";
}
for (int j = 10; j > 0; j--)
{
if (j == 10)
{
x = x.Remove(x.Length - 1);
}
else
{
x = x.Remove(x.Length - 1);
}
txt_box3.Text += (x) + "\n";
txt_box4.Text += (x) + "\n";
// txt_box4.Text displays correct but starts from 9 x's?
}
}
}
}
You are removing one of the x's before displaying it.
if (j == 10)
{
x = x.Remove(x.Length - 1);
}
Perhaps a better solution would be:
if (j < 10)
{
x = x.Remove(x.Length - 1);
}
Try with this:
private void button_Click_1(object sender, RoutedEventArgs e)
{
int i;
string allLines = "";
for (i = 1; i <= 10; i++)
allLines += new string('X', i) + (i < 10 ? "\n" : "");
txt_box1.Text = allLines;
txt_box2.Text = allLines;
allLines = "";
while (--i > 0)
allLines += new string('X', i) + (i > 1 ? "\n" : "");
txt_box3.Text = allLines;
txt_box4.Text = allLines;
}
This way is much clearer and more efficient, you are creating MUCH LESS strings in memory.

Categories

Resources