Convert string list to corresponding int c# - c#

I am making a quiz and have pulled a series of strings from a text file and added them a list, further separating the file info into individual strings. My question is, how would I make the individual strings correspond to a numerical value? For example A = 1, B = 2, so on and so forth.
The following code depicts the creation of the list and the adding of elements:
List<string> keyPool = new List<string>();
OpenFileDialog keyLoad = new OpenFileDialog();
keyLoad.Multiselect = false;
if (keyLoad.ShowDialog() == DialogResult.OK)
{
foreach (String fileName in keyLoad.FileNames)
{
key = File.ReadAllText(fileName);
kLabel.Text = ("Key:" + System.Environment.NewLine);
k1 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[0];
keyPool.Add(k1);
k2 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[1];
keyPool.Add(k2);
k3 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[2];
keyPool.Add(k3);
k4 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[3];
keyPool.Add(k4);
k5 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[4];
keyPool.Add(k5);
k6 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[5];
keyPool.Add(k6);
k7 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[6];
keyPool.Add(k7);
k8 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[7];
keyPool.Add(k8);
k9 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[8];
keyPool.Add(k9);
k10 = key.Split(new string[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries)[9];
keyPool.Add(k10);
}
}
How would this be done?

In general terms, you are looking for a dictionary. In this case, we are using it to define the mapping between strings and numbers:
Dictionary<string, int> mapping = new Dictionary<string, int>();
mapping.Add("A", 1);
...
int value = mapping["A"];
You could take advantage of the ASCII table if you just want to convert the first few capital letters to numbers:
int value = (int)stringValue[0] - (int)'A' + 1;

Assuming each "string" is a single letter, such as A, B, and so on, you can set up an enum and parse each letter into it's appropriate enum value:
public enum Letter
{
A = 1,
B = 2,
C = 3,
D = 4,
E = 5,
F = 6,
G = 7,
H = 8,
I = 9,
J = 10
}
You only have to split the string once, it puts all values into an array, and you can foreach through that and build up your list:
List<Letter> keyPool = new List<Letter>();
var letters = key.Split(new string[] { System.Environment.NewLine },
System.StringSplitOptions.RemoveEmptyEntries);
foreach(var letter in letters)
{
keyPool.Add((Letter)Enum.Parse(typeof(Letter), letter);
}
To convert and use it as an int, you can just cast it:
Letter letter = Letter.A;
int a = (int)letter;

use an enum
enum Keys
{
A=1,
B,
C,
//continue onward
}
To convert to/from string:
string s = Keys.B.ToString();
Keys key = (Keys)Enum.Parse(typeof(Keys), s);
To convert to/from int:
int i = (int)Keys.B;
Keys keyFromI = (Keys)i;

You don't need to add enum or dictionary for the alphabet !
static void Main(string[] args)
{
string intialString = "abc".ToUpper();
string numberString = "";
foreach (char c in intialString)
{
numberString += (int)c - 64;
}
Console.WriteLine(numberString);
}
Here is clear example. If you want use it !

Related

How to combine values of several lists into one in C#?

I'm trying to merge several values of diffrent lists into one line.
for example:
list A = [1,2,3,4,5,6,7,8,9]
list B = [A,B,C,D]
list C = [!,?,-]
then ill go with a loop through all lists and the output should be:
line = [1,A,!]
line = [2,B,?]
line = [3,C,-]
line = [4,D,NULL]
line = [5,NULL, NULL]
line = [6 ,NULL ,NULL]...
The result will be added into one object
So far I tried to iterate through my lists with foreach loops but after I debugging it's clear that my approach cant work:
foreach (var item in list1){
foreach (var item2 in list2){
foreach (var item3 in list3){
string line = makeStringFrom(item, item2, item3);
}
}
}
But I dont know how to make it work.
You can also use LINQ functions.
var listA = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var listB = new List<string> { "A", "B", "C", "D" };
var listC = new List<string> { "!", "?", "-" };
var result = Enumerable.Range(0, Math.Max(Math.Max(listA.Count, listB.Count), listC.Count))
.Select(i => new
{
a = listA.ElementAtOrDefault(i),
b = listB.ElementAtOrDefault(i),
c = listC.ElementAtOrDefault(i)
}).ToList();
foreach (var item in result)
{
Console.WriteLine("{0} {1} {2}", item.a, item.b, item.c);
}
Result:
1 A !
2 B ?
3 C -
4 D
5
6
7
8
9
The general method would be:
Find the maximum length of all of the lists
Then create a loop to go from 0 to the max length-1
Check if each list contains that index of the item, and if so,
retrieve the value, otherwise return null
Build your line from those values
You can use this:
var A = new List<string>() { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
var B = new List<string>() { "A", "B", "C", "D" };
var C = new List<string>() { "!", "?", "-"};
var lists = new List<List<string>>() { A, B, C };
int count = 0;
foreach ( var list in lists )
count = Math.Max(count, list.Count);
var result = new List<List<string>>();
for ( int index = 0; index < count; index++ )
{
var item = new List<string>();
result.Add(item);
foreach ( var list in lists )
item.Add(index < list.Count ? list[index] : null);
}
foreach ( var list in result )
{
string str = "";
foreach ( var item in list )
str += ( item == null ? "(null)" : item ) + " ";
str.TrimEnd(' ');
Console.WriteLine(str);
}
We create a list of the lists so you can use that for any number of lists.
Next we take the max count of these lists.
Then we parse them as indicated by the algorithm:
We create a new list.
We add this list to the result that is a list of lists.
We add in this new list each of others lists items while taking null is no more items available.
You can use a StringBuilder if you plan to manage several and big lists to optimize memory strings concatenation.
Fiddle Snippet
Output
1 A !
2 B ?
3 C -
4 D (null)
5 (null) (null)
6 (null) (null)
7 (null) (null)
8 (null) (null)
9 (null) (null)

Extract text with iText with embedded fonts

I am trying to use iTextSharp (v5.5.12.1) to extract the text from the following PDF:
https://structure.mil.ru/files/morf/military/files/ENGV_1929.pdf
Unfortunately, it seems like they are using a number of embedded custom fonts, which are defeating me.
For now, I have a working solution using OCR, but the OCR can be imprecise, reading some characters wrongly and also adding additional spaces between characters. It would be ideal if I could extract the text directly.
public static string ExtractTextFromPdf(Stream pdfStream, bool addNewLineBetweenPages = false)
{
using (PdfReader reader = new PdfReader(pdfStream))
{
string text = "";
for (int i = 1; i <= reader.NumberOfPages; i++)
{
text += PdfTextExtractor.GetTextFromPage(reader, i);
if (addNewLineBetweenPages && i != reader.NumberOfPages)
{
text += Environment.NewLine;
}
}
return text;
}
}
The issue here is that the glyphs in the embedded font programs have non-standard glyph names (G00, G01, ...) and are identified only by glyph name. Thus, one has to establish a mapping from these glyph names to Unicode characters. One can do so e.g. by inspecting the fonts programs in the PDF (for example with font forge) and visually recognizing the glyphs by name. E.g. like here
(As you can recognize, there are some gaps for glyphs of the font in question which are not used in the document at hand. Some missing glyphs you can guess, some not.)
Then you have to inject these mappings into iText. As the mappings are hidden (private static members of the GlyphList class), you either have to patch iText itself or use reflection:
void InitializeGlyphs()
{
FieldInfo names2unicodeFiled = typeof(GlyphList).GetField("names2unicode", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
Dictionary<string, int[]> names2unicode = (Dictionary<string, int[]>) names2unicodeFiled.GetValue(null);
names2unicode["G03"] = new int[] { ' ' };
names2unicode["G0A"] = new int[] { '\'' };
names2unicode["G0B"] = new int[] { '(' };
names2unicode["G0C"] = new int[] { ')' };
names2unicode["G0F"] = new int[] { ',' };
names2unicode["G10"] = new int[] { '-' };
names2unicode["G11"] = new int[] { '.' };
names2unicode["G12"] = new int[] { '/' };
names2unicode["G13"] = new int[] { '0' };
names2unicode["G14"] = new int[] { '1' };
names2unicode["G15"] = new int[] { '2' };
names2unicode["G16"] = new int[] { '3' };
names2unicode["G17"] = new int[] { '4' };
names2unicode["G18"] = new int[] { '5' };
names2unicode["G19"] = new int[] { '6' };
names2unicode["G1A"] = new int[] { '7' };
names2unicode["G1B"] = new int[] { '8' };
names2unicode["G1C"] = new int[] { '9' };
names2unicode["G1D"] = new int[] { ':' };
names2unicode["G23"] = new int[] { '#' };
names2unicode["G24"] = new int[] { 'A' };
names2unicode["G25"] = new int[] { 'B' };
names2unicode["G26"] = new int[] { 'C' };
names2unicode["G27"] = new int[] { 'D' };
names2unicode["G28"] = new int[] { 'E' };
names2unicode["G29"] = new int[] { 'F' };
names2unicode["G2A"] = new int[] { 'G' };
names2unicode["G2B"] = new int[] { 'H' };
names2unicode["G2C"] = new int[] { 'I' };
names2unicode["G2D"] = new int[] { 'J' };
names2unicode["G2E"] = new int[] { 'K' };
names2unicode["G2F"] = new int[] { 'L' };
names2unicode["G30"] = new int[] { 'M' };
names2unicode["G31"] = new int[] { 'N' };
names2unicode["G32"] = new int[] { 'O' };
names2unicode["G33"] = new int[] { 'P' };
names2unicode["G34"] = new int[] { 'Q' };
names2unicode["G35"] = new int[] { 'R' };
names2unicode["G36"] = new int[] { 'S' };
names2unicode["G37"] = new int[] { 'T' };
names2unicode["G38"] = new int[] { 'U' };
names2unicode["G39"] = new int[] { 'V' };
names2unicode["G3A"] = new int[] { 'W' };
names2unicode["G3B"] = new int[] { 'X' };
names2unicode["G3C"] = new int[] { 'Y' };
names2unicode["G3D"] = new int[] { 'Z' };
names2unicode["G42"] = new int[] { '_' };
names2unicode["G44"] = new int[] { 'a' };
names2unicode["G45"] = new int[] { 'b' };
names2unicode["G46"] = new int[] { 'c' };
names2unicode["G46._"] = new int[] { 'c' };
names2unicode["G47"] = new int[] { 'd' };
names2unicode["G48"] = new int[] { 'e' };
names2unicode["G49"] = new int[] { 'f' };
names2unicode["G4A"] = new int[] { 'g' };
names2unicode["G4B"] = new int[] { 'h' };
names2unicode["G4C"] = new int[] { 'i' };
names2unicode["G4D"] = new int[] { 'j' };
names2unicode["G4E"] = new int[] { 'k' };
names2unicode["G4F"] = new int[] { 'l' };
names2unicode["G50"] = new int[] { 'm' };
names2unicode["G51"] = new int[] { 'n' };
names2unicode["G52"] = new int[] { 'o' };
names2unicode["G53"] = new int[] { 'p' };
names2unicode["G54"] = new int[] { 'q' };
names2unicode["G55"] = new int[] { 'r' };
names2unicode["G56"] = new int[] { 's' };
names2unicode["G57"] = new int[] { 't' };
names2unicode["G58"] = new int[] { 'u' };
names2unicode["G59"] = new int[] { 'v' };
names2unicode["G5A"] = new int[] { 'w' };
names2unicode["G5B"] = new int[] { 'x' };
names2unicode["G5C"] = new int[] { 'y' };
names2unicode["G5D"] = new int[] { 'z' };
names2unicode["G62"] = new int[] { 'Ш' };
names2unicode["G63"] = new int[] { 'Р' };
names2unicode["G6A"] = new int[] { 'И' };
names2unicode["G6B"] = new int[] { 'А' };
names2unicode["G6C"] = new int[] { 'М' };
names2unicode["G6D"] = new int[] { 'в' };
names2unicode["G6E"] = new int[] { 'Ф' };
names2unicode["G70"] = new int[] { 'Е' };
names2unicode["G72"] = new int[] { 'Б' };
names2unicode["G73"] = new int[] { 'Н' };
names2unicode["G76"] = new int[] { 'С' };
names2unicode["G7A"] = new int[] { 'К' };
names2unicode["G7B"] = new int[] { 'В' };
names2unicode["G7C"] = new int[] { 'О' };
names2unicode["G7D"] = new int[] { 'к' };
names2unicode["G7E"] = new int[] { 'З' };
names2unicode["G80"] = new int[] { 'Г' };
names2unicode["G81"] = new int[] { 'П' };
names2unicode["G82"] = new int[] { 'у' };
names2unicode["G85"] = new int[] { '»' };
names2unicode["G88"] = new int[] { 'т' };
names2unicode["G8D"] = new int[] { '’' };
names2unicode["G90"] = new int[] { 'У' };
names2unicode["G91"] = new int[] { 'Т' };
names2unicode["GA1"] = new int[] { 'Ц' };
names2unicode["GA2"] = new int[] { '№' };
names2unicode["GAA"] = new int[] { 'э' };
names2unicode["GAB"] = new int[] { 'я' };
names2unicode["GAC"] = new int[] { 'і' };
names2unicode["GAD"] = new int[] { 'б' };
names2unicode["GAE"] = new int[] { 'й' };
names2unicode["GAF"] = new int[] { 'р' };
names2unicode["GB0"] = new int[] { 'с' };
names2unicode["GB2"] = new int[] { 'х' };
names2unicode["GB5"] = new int[] { '“' };
names2unicode["GB9"] = new int[] { 'п' };
names2unicode["GBA"] = new int[] { 'о' };
names2unicode["GBD"] = new int[] { '«' };
names2unicode["GC1"] = new int[] { 'ф' };
names2unicode["GC8"] = new int[] { 'а' };
names2unicode["GCB"] = new int[] { 'е' };
names2unicode["GCE"] = new int[] { 'ж' };
names2unicode["GCF"] = new int[] { 'з' };
names2unicode["GD2"] = new int[] { 'и' };
names2unicode["GD3"] = new int[] { 'н' };
names2unicode["GDC"] = new int[] { '–' };
names2unicode["GE3"] = new int[] { 'л' };
}
After executing that method you can extract the text using your method:
InitializeGlyphs();
using (FileStream pdfStream = new FileStream(#"ENGV_1929.pdf", FileMode.Open))
{
string result = ExtractTextFromPdf(pdfStream, true);
File.WriteAllText(#"ENGV_1929.txt", result);
Console.WriteLine("\n\nENGV_1929.pdf\n");
Console.WriteLine(result);
}
The result:
From Notices to Mariners
Edition No 29/2019
(English version)
Notiсes to Mariners from Seсtion II «Сharts Сorreсtion», based on the original sourсe information, and
NAVAREA XIII, XX and XXI navigational warnings are reprinted hereunder in English. Original Notiсes to
Mariners from Seсtion I «Misсellaneous Navigational Information» and from Seсtion III «Nautiсal
Publiсations Сorreсtion» may be only briefly annotated and/or a referenсe may be made to Notiсes from
other Seсtions. Information from Seсtion IV «Сatalogues of Сharts and Nautiсal Publiсations Сorreсtion»
сonсerning the issue of сharts and publiсations is presented with details.
Digital analogue of English version of the extracts from original Russian Notices to Mariners is available
by: http://structure.mil.ru/structure/forces/hydrographic/info/notices.htm
СНАRTS СОRRЕСTIОN
Вarents Sea
3493 Сharts 18012, 17052, 15005, 15004
Amend 1. Light to light Fl G 4s 1M at
front leading lightbeacon 69111’32.2“N 33129’48.0“E
2. Light to light Fl G 4s 1M at
rear leading lightbeacon 69111’34.85“N 33129’44.25“E
Cancel coastal warning
MURMANSK 71/19
...
Beware, you will see that quite often instead of a Latin character a similar looking Cyrillic character is used. Apparently the document was created manually by someone who didn't consider typographical correctness very important..
So, if you want to search in the text, you should first normalize the text and your search terms (e.g. use the same character for the Latin 'c' and the Cyrillic 'с').

Conversion of array string to array ulong in c#

I have a array of strings having values
string[] words = {"0B", "00", " 00", "00", "00", "07", "3F", "14", "1D"};
I need it to convert into array of ulong
ulong[] words1;
How should I do it in c#
I think I should add some background.
The data in the string is coming from textbox and I need to write the content of this textbox in the hexUpDown.Value parameter.
var ulongs = words.Select(x => ulong.Parse(x, NumberStyles.HexNumber)).ToArray();
If you need to combine the bytes into 64 bit values then try this (assumes correct endieness).
string[] words = { "0B", "00", " 00", "00", "00", "07", "3F", "14", "1D" };
var words64 = new List<string>();
int wc = 0;
var s = string.Empty;
var results = new List<ulong>();
// Concat string to make 64 bit words
foreach (var word in words)
{
// remove extra whitespace
s += word.Trim();
wc++;
// Added the word when it's 64 bits
if (wc % 4 == 0)
{
words64.Add(s);
wc = 0;
s = string.Empty;
}
}
// If there are any leftover bits, append those
if (!string.IsNullOrEmpty(s))
{
words64.Add(s);
}
// Now attempt to convert each string to a ulong
foreach (var word in words64)
{
ulong r;
if (ulong.TryParse(word,
System.Globalization.NumberStyles.AllowHexSpecifier,
System.Globalization.CultureInfo.InvariantCulture,
out r))
{
results.Add(r);
}
}
Results:
List<ulong>(3) { 184549376, 474900, 29 }

How to make matrix from string in c#

I have string:
string t = "{ { 1, 3, 23 } , { 5, 7, 9 } , { 44, 2, 3 } }"
Can I make a string matrix using string input like this?
I can't simply assign:
int [ , ] matrix = t
Is there some function I could use or do I have to split my string in some way?
PS: 't' string could have various number of rows and columns.
This should serve your purpose
string t = "{ { 1, 3, 23 } , { 5, 7, 9 } , { 44, 2, 3 } }";
var cleanedRows = Regex.Split(t, #"}\s*,\s*{")
.Select(r => r.Replace("{", "").Replace("}", "").Trim())
.ToList();
var matrix = new int[cleanedRows.Count][];
for (var i = 0; i < cleanedRows.Count; i++)
{
var data = cleanedRows.ElementAt(i).Split(',');
matrix[i] = data.Select(c => int.Parse(c.Trim())).ToArray();
}
I came up with something rather similar but with some test cases you might want to think about - hope it helps :
private void Button_Click(object sender, RoutedEventArgs e)
{
int[][] matrix;
matrix = InitStringToMatrix("{ { 1, 3, 23 } , { 5, 7, 9 } , { 44, 2, 3 } }");
matrix = InitStringToMatrix("{ {0,1, 2 ,-3 ,4}, {0} }");
matrix = InitStringToMatrix("{} ");
matrix = InitStringToMatrix("{ {}, {1} } ");
matrix = InitStringToMatrix("{ { , 1,2,3} } ");
matrix = InitStringToMatrix("{ {1} ");
matrix = InitStringToMatrix("{ {1}{2}{3} }");
matrix = InitStringToMatrix(",,,");
matrix = InitStringToMatrix("{1 2 3}");
}
private int[][] InitStringToMatrix(string initString)
{
string[] rows = initString.Replace("}", "")
.Split('{')
.Where(s => !s.Trim().Equals(String.Empty))
.ToArray();
int [][] result = new int[rows.Count()][];
for (int i = 0; i < rows.Count(); i++)
{
result[i] = rows[i].Split(',')
.Where(s => !s.Trim().Equals(String.Empty))
.Select(val => int.Parse(val))
.ToArray();
}
return result;
}
If you like optimizations here's a solution with only one expression:
string text = "{ { 1, 3, 23 } , { 5, 7, 9 } , { 44, 2, 3 } }";
// remove spaces, makes parsing easier
text = text.Replace(" ", string.Empty) ;
var matrix =
// match groups
Regex.Matches(text, #"{(\d+,?)+},?").Cast<Match>()
.Select (m =>
// match digits in a group
Regex.Matches(m.Groups[0].Value, #"\d+(?=,?)").Cast<Match>()
// parse digits into an array
.Select (ma => int.Parse(ma.Groups[0].Value)).ToArray())
// put everything into an array
.ToArray();
Based on Arghya C's solution, here is a function which returns a int[,] instead of a int[][] as the OP asked.
public int[,] CreateMatrix(string s)
{
List<string> cleanedRows = Regex.Split(s, #"}\s*,\s*{")
.Select(r => r.Replace("{", "").Replace("}", "").Trim())
.ToList();
int[] columnsSize = cleanedRows.Select(x => x.Split(',').Length)
.Distinct()
.ToArray();
if (columnsSize.Length != 1)
throw new Exception("All columns must have the same size");
int[,] matrix = new int[cleanedRows.Count, columnsSize[0]];
string[] data;
for (int i = 0; i < cleanedRows.Count; i++)
{
data = cleanedRows[i].Split(',');
for (int j = 0; j < columnsSize[0]; j++)
{
matrix[i, j] = int.Parse(data[j].Trim());
}
}
return matrix;
}

Get many values in a loop

I have a 4 arrays:
var array1[] = {1,2,3,4}
var array2[] = {a,b,c,d}
var array3[] = {A,B,C,D}
var array4[] = {10,20,30,40}
Now, I want to GET 4 values from this 4 array in 1 loop, so how can do it, like this output for 1 loop:
"1,a,A,10"
I guess you wanted :
var array2[] = {'a','b','c','d'};
var array3[] = {'A','B','C','D'};
by your 2nd and 3rd arrays
anyway you can loop through them as mentioned in the comment
for(int i=0; i<4; i++)
{
Console.WriteLine("\"{0},{1},{2},{3}\"", array1[i], array2[i], array3[i], array4[i]);
}
for(int i=0; i<4; i++)
{
String a = String.Format("\"{0},{1},{2},{3}\"", array1[i], array2[i], array3[i], array4[i]);
// Do what you want with the value here
}
another way is to put all arrays into one array and loop through it:
static void Main(string[] args)
{
Object[] array1 = { 1, 2, 3, 4 };
Object[] array2 = { 'a', 'b', 'c', 'd' };
Object[] array3 = { 'A', 'B', 'C', 'D' };
Object[] array4 = { 10, 20, 30, 40 };
var arrays = new Object[][] { array1, array2, array3, array4 };
string str = "";
for (int i = 0; i < arrays.Length; i++)
{
str += arrays[i][0].ToString()+',';
}
str = str.Remove(str.Length - 1);
Console.WriteLine(str);
Console.ReadLine();
}
Output: 1,a,A,10

Categories

Resources