C# binary writing return bigger file - c#

im having a little trouble with a binary writer issue, my program is set to load SHIFT-JIS characters, and write in the same encoding, but it returns a file bigger in size :s although i remove several Characters, here is a sample of the files before and after writing, these are the open and save codes:
private void Openbtn_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
textBox1.Text = "";
menuItem12.Text = "file type is: ";
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Open File";
ofd.Filter = "All Files (*.*)|*.*";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
menuItem13.Enabled = true;
menuItem14.Enabled = true;
menuItem15.Enabled = true;
path = ofd.FileName;
BinaryReader br = new BinaryReader(File.OpenRead(path), Encoding.GetEncoding("SHIFT-JIS"));
foreach (char mychar in br.ReadChars(4)) menuItem12.Text += mychar;
if (menuItem12.Text != "file type is: TXTD")
{
MessageBox.Show("This is not a TXTD file...", "Sorry", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
MessageBox.Show("File opened Succesfully!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
br.BaseStream.Position = 0x8;
int Pntrnum = br.ReadInt16();
menuItem11.Visible = true;
menuItem11.Text = Pntrnum.ToString();
List<int> offsets = new List<int>();
br.BaseStream.Position = 0x10;
for (int i = 0; i < Pntrnum; i++)
{
offsets.Add(br.ReadInt32());
}
Dictionary<int, string> values = new Dictionary<int, string>();
for (int i = 0; i < offsets.Count; i++)
{
int currentOffset = offsets[i];
int nextOffset = (i + 1) < offsets.Count ? offsets[i + 1] : (int)br.BaseStream.Length;
int stringLength = (nextOffset - currentOffset - 1);
br.BaseStream.Position = currentOffset;
var chars = br.ReadChars(stringLength);
values.Add(currentOffset, new String(chars));
}
foreach (int offset in offsets)
{
listView1.Items.Add(offset.ToString("X")).SubItems.Add(values[offset]);
}
br.Close();
br = null;
}
}
ofd.Dispose();
ofd = null;
}
private void Savebtn_Click(object sender, EventArgs e)
{
BinaryWriter bw = new BinaryWriter(File.OpenWrite(path));
int number_pointers = Convert.ToInt32(menuItem11.Text);
Encoding enc = Encoding.GetEncoding("SHIFT-JIS");
bw.BaseStream.Position = 0x10;
int curr_pointer = 16 + number_pointers * 4;
//pointers writing
for (int i = 0; i < number_pointers; i++)
{
bw.Write(curr_pointer);
curr_pointer += enc.GetByteCount(listView1.Items[i].SubItems[1].Text) + '\0';
}
for (int i = 0; i < number_pointers; i++)
{
bw.Write(enc.GetBytes(listView1.Items[i].SubItems[1].Text + '\0'));
}
bw.Flush();
bw.Close();
bw = null;
}
i truly appreciate your help.

Looking inside the "After" file in the Samples.zip you provided seems to indicate that you're outputting the same string twice, or something...
I would suggest you start with smaller files to test on, and to use the debugger to step in.
Actually, having tried that myself, i think i found out what's going on: you're using "nextOffset - currentOffset" as a stringLength, but it's actually a BYTE-Length... The char array will end (have a '\0' inside it) after only half this number, and when outputting you'll also get the second half, that you haven't yet read.
[Edit]
Posting the code from my comment below, for better formatting:
int index;
for (index = 0; index < stringLength; ++index) if (chars[index] == '\0') break;
if (index < stringLength) {
char[] relevantPart = new char[index];
Array.Copy(chars, relevantPart, index);
chars = relevantPart;
}

Related

Read File and store into array and display sum in textbox

I'm trying to get data from a file and store them in an array then display the data in a listbox the find then sum and display it in a text box. Here's my code and it doesn't work. I'm not sure what i'm doing wrong.
private void findClick(object sender, EventArgs e)
{
int sum;
using (OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
{
using (StreamReader InputFile = new StreamReader(ofd.FileName))
{
while (InputFile.EndOfStream == false)
{
int[] array = new int[listBox.Items.Count];
for (int i = 0; i < listBox.Items.Count; i++)
{
// array[i] = Convert.ToInt32(listBox.Items[i].ToString());
array[i] = int.Parse(listBox.Items[i].ToString());
sum = array.Sum();
TotalAmtlabel.Text = sum.ToString("N0");
TotalNumberslabel.Text = listBox.Items.Count.ToString();
TotalAmountlabel.Text = string.Format("{0:N0}", sum);
}
}
}
}
}
}
listBox.Items.AddRange(File.ReadAllLines(ofd.FileName));
Try this and modify according to your needs:
string[] amounts = File.ReadAllLines(ofd.FileName);
int currentSum = 0;
int totalSum = 0;
ListItem[] amountItems = new ListItem[amounts.Length];
for (int i = 0; i < amounts.Length; i++)
{
if (int.TryParse(amounts[i], out currentSum))
{
totalSum += currentSum;
}
amountItems[i] = amounts[i];
}
listBox.Items.AddRange(amountItems);
TotalAmountlabel.Text = string.Format("{0}", totalSum);
You can also datasource to bind the list. Please go through below MSDN references once atleast to understand security cautions:
ListItem
ListBox

C# Iterate through binary file and build a text file with found bytes

I try to be more specific.
I have a binary file which has some portions of text inside.
I want to search for some byte sequence in the binary file, if the sequences are found take the byte arrays and build a text file with them.
So the step has to be repeated till the end of the binary file.
I used BinaryReader to search for a byte sequence, in order to validate the binary file, but now I am stuck on how to proceed with this combination.
My other issue is that I have to skip certain portions of the binary file until the next sequence is found.
So for example, I find the first sequence at 0x10 and it lasts for 10 bytes. Then I have to skip 32 bytes where another byte sequence then starts for x bytes till a tail byte that marks the end of the sequence.
Each time a byte sequence is found I have to save it in a text file, finally writing it to disk.
Any help?
Something like this, then:
class Program
{
const string filename = "some file";
static void Main(string[] args)
{
byte[] bytes = System.IO.File.ReadAllBytes(filename);
string[] find = new string[] { "me", "you" };
int offsetAfterFind = 32;
int pos = 0;
while (pos < bytes.Length)
{
bool isFound = false;
int index = 0;
while (!isFound && index < find.Length)
{
bool isMatch = true;
for (int n = 0; n < find[index].Length; n++)
{
if (pos + n >= bytes.Length)
{
isMatch = false;
}
else
{
if (bytes[pos + n] != find[index][n]) isMatch = false;
}
}
if (isMatch)
{
isFound = true;
break;
}
index++;
}
if (isFound)
{
Console.WriteLine(String.Format("Found {0} at {1}", find[index], pos));
pos += find[index].Length + offsetAfterFind;
}
else
{
pos++;
}
}
}
}
All right. I managed to do it and maybe this will be useful to someone else:
public static void ConvertToSRTSubs()
{
byte [] openingTimeWindow = Encoding.ASCII.GetBytes("["); \\Timespan in the binary is wrapped around square brackets
byte [] nextOpening = Encoding.ASCII.GetBytes("[00"); \\ I need this as a point to get the end of the sentence, because there is a fixed size between sentences and next timespan.
byte [] closingTimeWindow = Encoding.ASCII.GetBytes("]"); \\End of the timespan
int found = 0; \\This will iterate through every timespan match
int backPos = 0; \\Pointer to the first occurrence
int nextPos = 0;
int sentenceStartPos = 0;
int newStartFound = 0;
string srtTime = String.Empty;
string srtSentence = String.Empty;
byte[] array = File.ReadAllBytes(Path.Combine(coursePath, hashedSubFileName));
try
{
using (StreamWriter s = new StreamWriter(Video.outPath + ext, false))
{
for (int i = 0; i < array.Length; i++)
{
if (openingTimeWindow[0] == array[i] && closingTimeWindow[0] == array[i + 12])
{
found++;
s.WriteLine(found);
try
{
backPos = i;
for (i = backPos + 12; i < array.Length; i++ )
{
if (newStartFound == 1)
break;
if (nextOpening[0] == array[i] && nextOpening[1] == array[i + 1] && nextOpening[2] == array[i + 2])
{
nextPos = i - 19;
newStartFound++;
}
}
i = backPos;
newStartFound = 0;
sentenceStartPos = backPos + 27;
sentenceSize = nextPos - sentenceStartPos;
if (sentenceSize < 0) sentenceSize = 1;
byte[] startTime = new byte[11];
byte[] sentence = new byte[sentenceSize];
Array.Copy(array, backPos + 1, startTime, 0, 11);
Array.Copy(array, sentenceStartPos, sentence, 0, sentenceSize);
srtTimeRaw = srtTime = Encoding.UTF8.GetString(startTime);
srtTime = srtTimeRaw.Replace('.', ',') + "0" + " --> " + span;
s.WriteLine(srtTime);
srtSentence = Encoding.UTF8.GetString(sentence);
s.WriteLine(srtSentence);
s.WriteLine();
}
catch (ArgumentException argex)
{
MessageBox.Show(argex.ToString());
}
}
}
}
}
catch (DirectoryNotFoundException dex)
{
MessageBox.Show(dex.ToString());
}
}
Maybe not the cleanest code, but it works :)

Extract a table from PDF

I need a help with iText in C#. I'm trying to extract a table from a PDF file and save this into a new CSV file, keeping the values in the correct places. For this, I thought the solution was to create a two-dimensional array to organize the data.
Extracting all information from PDF with iText, I saw it was possible to get some numerical data that seemed to be the position of a piece of text on the page and I organized my array based these indexes. It didn’t work, the text was completely dispersed in various different cells. Now, I want to know what this values means, because they don't follow a "correct" order and I want to know if is possible to organize the future table with this.
I'm using ";" as delimiter cell.
For testing, I'm using this PDF
http://www.americana.sp.gov.br/americanaV5/download/contasPublicas/Despesa_Categoria_Economica_2014.pdf
Here's my code:
protected void Button2_Click(object sender, EventArgs e)
{
try
{
TextBox2.Text = "";
byte[] conteudo = download(TextBox1.Text);
if (conteudo != null)
{
PdfReader leitorp = new PdfReader(conteudo);
ITextExtractionStrategy estrategia = new SimpleTextExtractionStrategy();
List<Celula> celulas = new List<Celula>();
int i, j;
for (i = 1; i <= leitorp.NumberOfPages; i++)
{
//Total and crude extraction of all information from text in PDF via iText, separate lines in an array of strings.
string[] linhas = (Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8, leitorp.GetPageContent(i)))).Split('\n');
for (j = 1; j < linhas.Length; j++)
{
if (linhas[j].Length > 2)
{
if (linhas[j].Substring(0, 2).Equals("BT"))
{
string[] campos = linhas[j].Split(' ');
Celula umacelula = new Celula();
umacelula.coluna = float.Parse(campos[1]);
umacelula.linha = float.Parse(campos[2]);
linhadodebug = j;
int t1 = linhas[j].IndexOf('(');
int t2 = linhas[j].LastIndexOf(')');
umacelula.conteudo = System.Text.RegularExpressions.Regex.Replace((linhas[j].Substring(linhas[j].IndexOf('(') + 1, (linhas[j].LastIndexOf(')') - 1 - linhas[j].IndexOf('(')))), #"\s\s+", "");
celulas.Add(umacelula);
}
}
}
}
leitorp.Close();
string[] totallinhas = new string[celulas.Count];
string[] totalcolunas = new string[celulas.Count];
for (i = 0; i < celulas.Count; i++)
{
totallinhas[i] = celulas[i].linha.ToString();
totalcolunas[i] = celulas[i].coluna.ToString();
}
totallinhas = totallinhas.Distinct().ToArray();
totalcolunas = totalcolunas.Distinct().ToArray();
Array.Sort(totallinhas);
Array.Reverse(totallinhas);
Array.Sort(totalcolunas);
Array.Reverse(totalcolunas);
string[,] matriz = new string[totallinhas.Length + 1, totalcolunas.Length + 1];
for (i = 1; i < totallinhas.Length; i++)
{
matriz[i, 0] = totallinhas[i - 1].ToString();
}
for (i = 1; i < totalcolunas.Length; i++)
{
matriz[0, i] = totalcolunas[i - 1].ToString();
}
int z;
for (i = 0; i < celulas.Count(); i++)
{
for (j = 1; j < matriz.GetLength(0); j++)
{
for (z = 1; z < matriz.GetLength(1); z++)
{
if ((celulas[i].linha.ToString().Equals(matriz[j, 0])) && (celulas[i].coluna.ToString().Equals(matriz[0, z])))
{
matriz[j, z] = celulas[i].conteudo.ToString();
}
}
}
}
StringWriter texto = new StringWriter();
for (i = 0; i < matriz.GetLength(0); i++)
{
for (j = 0; j < matriz.GetLength(1); j++)
{
texto.Write(matriz[i, j] + ";");
}
texto.WriteLine();
}
Response.ContentType = "text/plain";
Response.AddHeader("content-disposition", "attachment;filename=" + string.Format("teste-{0}.csv", string.Format("{0:ddMMyyyy}", DateTime.Today)));
Response.Clear();
using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8))
{
writer.Write(texto.ToString());
}
Response.End();
}
}
catch (Exception E)
{
TextBox2.Text = "Erro Button2_Click: " + E.Message + " # " + linhadodebug.ToString();
}
}
And here, the struct of celula (cell) and method to download the file:
public struct Celula
{
public float coluna;
public float linha;
public string conteudo;
public Celula(float coluna, float linha, string conteudo)
{
this.coluna = coluna;
this.linha = linha;
this.conteudo = conteudo;
}
public Celula(Celula celula)
{
this.coluna = celula.coluna;
this.linha = celula.linha;
this.conteudo = celula.conteudo;
}
}
protected byte[] download(string url)
{
try
{
WebRequest endereco = HttpWebRequest.Create(url);
Stream leitor = endereco.GetResponse().GetResponseStream();
MemoryStream memoria = new MemoryStream();
byte[] conteudo = null;
int count = 0;
do
{
byte[] buffer = new byte[1024];
count = leitor.Read(buffer, 0, 1024);
memoria.Write(buffer, 0, count);
}
while (leitor.CanRead && count > 0);
// Converte da memória direto para bytes
conteudo = memoria.ToArray();
if (conteudo != null)
{
return conteudo;
}
else
{
TextBox2.Text = "Error: download null.";
return null;
}
}
catch (Exception E)
{
TextBox2.Text = "Error download: " + E.Message;
return null;
}
}
This is a non-profit project. I hope you can help me. Thank you!

How to read binary file and insert strings to listView and each string to one line - C#

I want to read binary file and insert strings to listView and each string to one line
I have made a code but i don`t know why the code is not working
String input = string.Empty;
OpenFileDialog openFileDialog3 = new OpenFileDialog();
openFileDialog3.Filter = "bin files (*.bin)|*.bin";
if (openFileDialog3.ShowDialog() == DialogResult.OK)
if (openFileDialog3.FileName == String.Empty)
return;
BinaryReader br = new BinaryReader(File.OpenRead(openFileDialog3.FileName), Encoding.Unicode);
br.BaseStream.Position = 0x8;
int Pntrnum = br.ReadInt16();
menuItem11.Visible = true;
menuItem11.Text = Pntrnum.ToString();
List<int> offsets = new List<int>();
br.BaseStream.Position = 0x10;
for (int i = 0; i < Pntrnum; i++)
{
offsets.Add(br.ReadInt32());
}
Dictionary<int, string> values = new Dictionary<int, string>();
for (int i = 0; i < offsets.Count; i++)
{
int currentOffset = offsets[i];
int nextOffset = (i + 1) < offsets.Count ? offsets[i + 1] : (int)br.BaseStream.Length;
int stringLength = (nextOffset - currentOffset - 1) / 2;
br.BaseStream.Position = currentOffset;
var chars = br.ReadChars(stringLength);
values.Add(currentOffset, new String(chars));
}
foreach (int offset in offsets)
{
listView1.Items.Add(offset.ToString("X")).SubItems.Add(values[offset]);
}
br.Close();
br = null;
Is there an other code or there is mistakes

how to make a dictionary that can hold more than 1 data?

i've been trying to modify the program so that it could accept more than one data for a single alphabet character for example letter "A". there were some sort of ContainsKey function that allow only one key from keyboard to hold only one data. how to make it possible to hold more than one data?
I'm gonna make it very clear, this is an online OCR program using unsupervised neural network. when a user draw a character in the drawing space, they will have the option to add the character into the learning data to be train later. when they add a character, they have to define what character they just entered using the key on the keyboard. for example, they draw letter 'A' and a popup window will show up asking the user to enter the key from the keyboard for that letter.
the problem here, when there is already a letter 'A' in the learning data, i cannot add another letter 'A' bcause the key A is already hold the previous 'A'. i wanted to make the key A is able to hold more than one letter 'A'.
im gonna post the whole code for the program here and i hope u guys bear with me. this isnt my program, it is from Heaton Research and i just intend to modify it. thank in advance.
public partial class Form1 : Form
{
/**
* The downsample width for the application.
*/
const int DOWNSAMPLE_WIDTH = 10;
/**
* The down sample height for the application.
*/
const int DOWNSAMPLE_HEIGHT = 12;
private Bitmap entryImage;
private Graphics entryGraphics;
private int entryLastX;
private int entryLastY;
private Pen blackPen;
private bool[] downsampled;
private Dictionary<char, List<bool[]>> letterData = new Dictionary<Char, List<bool[]>>();
private double[][] trainingSet;
private SelfOrganizingMap network;
public Form1()
{
InitializeComponent();
blackPen = new Pen(Color.Black);
entryImage = new Bitmap(entry.Width, entry.Height);
entryGraphics = Graphics.FromImage(entryImage);
downsampled = new bool[Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH];
ClearEntry();
}
private void entry_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawImage(entryImage, 0, 0);
Pen blackPen = new Pen(Color.Black);
g.DrawRectangle(blackPen, 0, 0, entry.Width - 1, entry.Height - 1);
}
private void btnDelete_Click(object sender, EventArgs e)
{
string str = (string)this.letters.Items[this.letters.SelectedIndex];
char ch = str[0];
this.letterData.Remove(ch);
this.letters.Items.Remove(str);
ClearEntry();
}
private void btnLoad_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Data File (*.dat)|*.dat";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
TextReader f = new StreamReader(openFileDialog1.FileName);
String line;
this.letterData.Clear();
this.letters.Items.Clear();
while ((line = f.ReadLine()) != null)
{
int sampleSize = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
char ch = char.ToUpper(line[0]);
bool[] sample = new bool[sampleSize];
int idx = 2;
for (int i = 0; i < sampleSize; i++)
{
if (line[idx++] == '1')
sample[i] = true;
else
sample[i] = false;
}
this.letterData.Add(ch, sample);
this.letters.Items.Add("" + ch);
}
f.Close();
}
MessageBox.Show(this, "File Loaded");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
private void btnSave_Click(object sender, EventArgs e)
{
try
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Data File (*.dat)|*.dat";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
TextWriter f = new StreamWriter(saveFileDialog1.FileName);
int size = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
for (int i = 0; i < this.letters.Items.Count; i++)
{
char ch = ((string)this.letters.Items[i])[0];
bool[] data = this.letterData[ch];
f.Write(ch + ":");
for (int j = 0; j < size; j++)
{
f.Write(data[j] ? "1" : "0");
}
f.WriteLine("");
}
f.Close();
MessageBox.Show("File Saved");
}
}
catch (Exception e2)
{
MessageBox.Show("Error: " + e2.Message, "Training");
}
}
private void btnBeginTraining_Click(object sender, EventArgs e)
{
int inputCount = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
int letterCount = this.letters.Items.Count;
this.trainingSet = new double[letterCount][];
int index = 0;
foreach (char ch in this.letterData.Keys)
{
this.trainingSet[index] = new double[inputCount];
bool[] data = this.letterData[ch];
for (int i = 0; i < inputCount; i++)
{
this.trainingSet[index][i] = data[i] ? 0.5 : -0.5;
}
index++;
}
network = new SelfOrganizingMap(inputCount, letterCount, NormalizationType.Z_AXIS);
this.ThreadProc();
}
private void btnAdd_Click(object sender, EventArgs e)
{
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
String Prompt = "Enter the letter you just draw (from the keyboard)";
String Title = "Letter definition Required";
String Default = " ";
Int32 XPos = ((SystemInformation.WorkingArea.Width / 2) - 200);
Int32 YPos = ((SystemInformation.WorkingArea.Height / 2) - 100);
bool valid = false;
for (int i = 0; i < this.downsampled.Length; i++)
{
if (this.downsampled[i])
{
valid = true;
}
}
if (!valid)
{
MessageBox.Show("Please draw a letter before adding it.");
return;
}
String Result = Microsoft.VisualBasic.Interaction.InputBox(Prompt, Title, Default, XPos, YPos);
if (Result != null)
{
Result = Result.ToUpper();
if (Result.Length == 0)
{
MessageBox.Show("Please enter a character.");
}
else if (Result.Length < 1)
{
MessageBox.Show("Please enter only a single character.");
}
//else if (this.letterData.ContainsKey(Result[0]))
//{
// MessageBox.Show("That letter is already defined, please delete first.");
//}
else
{
if (this.letterData.ContainsKey(Result[0]))
{
this.letterData[Result[0]].Add(this.downsampled);
}
else
{
this.letterData.Add(Result[0], new List<bool[]>() {this.downsampled});
}
this.letters.Items.Add(Result);
//this.letterData.Add(Result[0], this.downsampled);
this.ClearEntry();
}
}
}
private void btnRecognize_Click(object sender, EventArgs e)
{
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
if (this.network == null)
{
MessageBox.Show("The program needs to be trained first");
return;
}
int sampleSize = Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH;
double[] input = new double[sampleSize];
for (int i = 0; i < sampleSize; i++)
{
input[i] = this.downsampled[i] ? 0.5 : -0.5;
}
int best = this.network.Winner(input);
char[] map = mapNeurons();
this.result.Text = " " + map[best];
MessageBox.Show(" " + map[best] + " (Neuron #"
+ best + " fired)", "That Letter You Enter Is");
//ClearEntry();
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearEntry();
}
private void btnSample_Click(object sender, EventArgs e)
{
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
}
public void ClearEntry()
{
Brush whiteBrush = new SolidBrush(Color.White);
entryGraphics.FillRectangle(whiteBrush, 0, 0, entry.Width, entry.Height);
entry.Invalidate();
DownSample ds = new DownSample(this.entryImage);
this.downsampled = ds.downSample(Form1.DOWNSAMPLE_WIDTH, Form1.DOWNSAMPLE_HEIGHT);
this.sample.Invalidate();
}
private void entry_MouseDown(object sender, MouseEventArgs e)
{
entry.Capture = true;
entryLastX = e.X;
entryLastY = e.Y;
}
private void entry_MouseUp(object sender, MouseEventArgs e)
{
entryGraphics.DrawLine(blackPen, entryLastX, entryLastY, e.X, e.Y);
entry.Invalidate();
entry.Capture = false;
}
private void entry_MouseMove(object sender, MouseEventArgs e)
{
if (entry.Capture == true)
{
entryGraphics.DrawLine(blackPen, entryLastX, entryLastY, e.X, e.Y);
entry.Invalidate();
entryLastX = e.X;
entryLastY = e.Y;
}
}
private void sample_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
int x, y;
int vcell = sample.Height / Form1.DOWNSAMPLE_HEIGHT;
int hcell = sample.Width / Form1.DOWNSAMPLE_WIDTH;
Brush whiteBrush = new SolidBrush(Color.White);
Brush blackBrush = new SolidBrush(Color.Black);
Pen blackPen = new Pen(Color.Black);
g.FillRectangle(whiteBrush, 0, 0, sample.Width, sample.Height);
for (y = 0; y < Form1.DOWNSAMPLE_HEIGHT; y++)
{
g.DrawLine(blackPen, 0, y * vcell, sample.Width, y * vcell);
}
for (x = 0; x < Form1.DOWNSAMPLE_WIDTH; x++)
{
g.DrawLine(blackPen, x * hcell, 0, x * hcell, sample.Height);
}
int index = 0;
for (y = 0; y < Form1.DOWNSAMPLE_HEIGHT; y++)
{
for (x = 0; x < Form1.DOWNSAMPLE_WIDTH; x++)
{
if (this.downsampled[index++])
{
g.FillRectangle(blackBrush, x * hcell, y * vcell, hcell, vcell);
}
}
}
g.DrawRectangle(blackPen, 0, 0, sample.Width - 1, sample.Height - 1);
}
private void letters_SelectedIndexChanged(object sender, EventArgs e)
{
if (this.letters.SelectedIndex >= 0)
{
string str = (string)this.letters.Items[this.letters.SelectedIndex];
char ch = str[0];
this.downsampled = this.letterData[ch];
this.sample.Invalidate();
}
}
public void ThreadProc()
{
TrainSelfOrganizingMap train = new TrainSelfOrganizingMap(
this.network, this.trainingSet, TrainSelfOrganizingMap.LearningMethod.SUBTRACTIVE, 0.5);
int tries = 1;
do
{
train.Iteration();
this.txtTries.Text = "" + tries;
this.txtBestError.Text = "" + train.BestError;
this.txtLastError.Text = "" + train.TotalError;
tries++;
Application.DoEvents();
} while (train.TotalError > 0.01 && (tries <= 100));
MessageBox.Show("Training complete.");
}
/**
* Used to map neurons to actual letters.
*
* #return The current mapping between neurons and letters as an array.
*/
public char[] mapNeurons()
{
char[] map = new char[this.letters.Items.Count];
for (int i = 0; i < map.Length; i++)
{
map[i] = '?';
}
for (int i = 0; i < this.letters.Items.Count; i++)
{
double[] input = new double[Form1.DOWNSAMPLE_HEIGHT * Form1.DOWNSAMPLE_WIDTH];
char ch = ((string)(this.letters.Items[i]))[0];
bool[] data = this.letterData[ch];
for (int j = 0; j < input.Length; j++)
{
input[j] = data[j] ? 0.5 : -0.5;
}
int best = this.network.Winner(input);
map[best] = ch;
}
return map;
}
}
Dictionary<> is created in a such way that you can access Key Value pair in most efficient way. Now in Dictionary<> you can not have two pairs with same key. To do so,
what you can do, you create a dictionary like Dictionary<char, List<bool[]>>, now in this dictionary you can store one key with more than one value.
Update
If you change the dictionary to Dictionary<char, List<bool[]>> then to store one key with more than one value you will have to as follows
private bool[] downsampled;
private Dictionary<char, List<bool[]>> letterData = new Dictionary<Char, List<bool[]>>();
//
// Your Code
//
if (Result != null)
{
Result = Result.ToUpper();
if (Result.Length == 0)
{
MessageBox.Show("Please enter a character.");
}
else if (Result.Length < 1)
{
MessageBox.Show("Please enter only a single character.");
}
else
{
if (this.letterData.ContainsKey(Result[0]))
{
this.letterData[Result[0]].Add(this.downsampled);
}
else
{
this.letterData.Add(Result[0], new List<bool[]>() { this.downsampled });
}
this.letters.Items.Add(Result);
this.ClearEntry();
}
}
If you want to string as key, instead of char, use Dictionary<string, List<bool[]>>.
Hope this answers your question.
Take a look at the Lookup class in .Net. This lets you have the same "key" value multiple times.

Categories

Resources