C# Modularised Conversion utility program mimic of google search when converting measurements - c#

The task that i have is to create a replica of a search engine that converts measurements. The user enters "4cm to inches" and the program makes the appropriate calculations to give the answer in inches. Now this program must be able to convert through a range of different measurements and dimensions eg Volume and area also. So far i have been able to make it convert strictly from cm to inches using properties of strings ie Substring, IndexOf, Convert.Toint16 and i want it to continue doing so but i'm struggling modularising it so that it can do a range of different calculations efficiently. This is what i have so far...
Toconvert = Console.ReadLine();
Cmpos = Toconvert.IndexOf("cm");
Inchespos = Toconvert.IndexOf("inches");
CmUnits = Toconvert.Substring(Cmpos, 2);
InchesUnits = Toconvert.Substring(Inchespos, 6);
number2convert = Convert.ToInt16(Toconvert.Substring(0, Cmpos));
Inches = number2convert / 2.54;
Console.WriteLine("{0}{1} is {2:F2} {3}", number2convert, CmUnits, Inches, InchesUnits);
Console.ReadLine();
This is very problematic/limiting and has me perplexed. Every route ive taken ive encountered an error of some sort.
All i want it to do is read whats been input by the user, and outputs the appropriate value from what the computer has.

Learn Regex, it will be your friend, especially for something like this.
Here's a query that will help for your particular case:
([0-9]+[.]?[0-9]*)[\s]*([\w]+)[\s]+[\w]+[\s]+([\w]+)
Loosely translated: Look for numbers (4), then a space or not, then a word (cm), then space, then a word (to), then space, then a word (inches).
Regex offers "groups" (the items in parentheses). for 4cm to inches in the above Regex, the groups are 4, cm and inches...all the useful bits.
This is an example of it in use. There's also very good explanations for each step of the Regex (Click on the "Explain" tab).
Here's a C# example:
var reg = new System.Text.RegularExpressions.Regex(#"([0-9]+[.]?[0-9]*)[\s]*([\w]+)[\s]+[\w]+[\s]+([\w]+)");
var match = reg.Match("4cm to inches");
double numberToConvert = double.Parse(match.Groups[1].Value);
string fromUnits = match.Groups[2].Value;
string toUnits = match.Groups[3].Value;

Related

Refer to a specific index of an array depending on user input

Trying to make a program where it takes in an equation from user and outputs the answer. Having to develop all code for it to work, and wondering how I could refer to either array index value either side of a specific index?
Example:
User input: X = 5 + 5 * 6
Wanting to be able to locate the ***** and retrieve the value of the 5 & 6 either side of it. Tried multiple things and tried searching here too, cannot find a answer.
Thankyou in advance to anyone who takes the time to help!
One way to do it is to use regular expressions. I would remove all whitespaces first to make it easier. For example:
string input = "X = 5 + 5 * 6";
Regex r = new Regex(#"(\d+)\*(\d+)");
Match m = r.Match(input.Replace(" ", ""));
var a = m.Groups[1].Value; // a = 5
var b = m.Groups[2].Value; // b = 6
Explanation of this regex can be found here: https://regex101.com/r/k7rthI/1
You would have to improve the regex to handle decimals and many other cases when the equation gets more complex. It is a long dark rabbit hole to go down if you get more complex than what you have. So you might be better off finding a math library you can use. No reason to reinvent the wheel.

Right justifying decimal array in c#?

I have a Project for my c# programming class; writing a program that can read an employee file and a sales slip file and process the two. I have completed the 2 arrays I needed and they fill in nicely. My problem is when I go to print out the results in console mode.
My arrays are of type decimal. I need to have all the numbers right justified at a certain position and the only way I know how to do so is with the function .PadRight/.PadLeft , which only work for strings I see. Is there any other way to do this or should I just Convert.ToString each value?
If you simply need to output your values padded using the Console, you can simply format them using Composite Formatting and it's {0,spaces-to-format} syntax :
// Example array of decimals
var input = new decimal[]{ 12.24m, 199.99m, 1.0m, 42.42m, 100321.123m };
// Format each value to 10 digits
foreach(decimal d in input)
{
// Format each value to 10 places (right-justfied)
// You could alternatively use d.ToString("{0,10")
Console.WriteLine("{0,10}",d);
}
You can see a working example of this here and demonstrated below :
You're pretty much looking at
decimal val = 10m;
//Or PadLeft
string formattedVal = val.ToString().PadRight(10, ' ');

Break a Caesar-cipher cipher text without knowing the plaintext or the key through frequency-analysis

I am trying to make a program which can help you to break a cipher text without knowing the plain text and the key.
I want probable plain text at the output which gives the closest statistical values and a set of probable candidates keys
I started doing the frequency analysis,completed it. It helped me in telling the occurrence of each alphabet, but I have no idea how will I generate keys from that.
class Program
{
static void Main()
{
// Array to store frequencies.
int[] c = new int[(int)char.MaxValue];
// Read entire text file.
string s = File.ReadAllText("text.txt");
// Iterate over each character.
foreach (char t in s)
{
// Increment table.
c[(int)t]++;
}
// Write all letters found.
for (int i = 0; i < (int)char.MaxValue; i++)
{
if (c[i] > 0 &&
char.IsLetterOrDigit((char)i))
{
Console.WriteLine("Letter: {0} Frequency: {1}",
(char)i,
c[i]);
}
}
}
}
A Caesar cipher just replaces each plain text character with one a fixed number of places away down the alphabet. Assuming no casing, and English text, then it is trivial to produce all possible 26 decryptions and just pick out the correct one by eye.
For a substitution cipher you need to generalise your solution. A simplified method is to do a frequency count as you've suggested, and sort characters in descending order of frequency. Map those to the letters (again for English) ETAOINSRHOLUCMFYWGPBVKXQJZ (so for example assume the most frequent character represents an E, the next most frequent a T and so on). Use the mapping to do the decryption. The more cipher text you have the better the decryption will be. It is unlikely to be completely accurate but will give you enough information to fill in the gaps manually.
A more sophisticated solution might generate the mapping from the frequency distribution rather than just the sort order, and use known facts about the language e.g. Q is usually followed by U. You can get really fancy and check digraph and and trigram frequencies: http://practicalcryptography.com/cryptanalysis/letter-frequencies-various-languages/english-letter-frequencies/
For a simple letter-substitution cipher, you would want to get a list of letter frequencies in English and try to map them to the most frequent letters in the message. Note that. back before computers, real militaries inserted irrelevant text into messages to throw this off. A strategy cryptographers used, back in those days, was to look for longer repeated strings. In English, they looked for three-letter words like and, the, not or for. In German, they looked for long compound words like the name of the headquarters a unit was reporting to, or tried to guess what weather report it would have sent at a given location and time.

How to check a partial similarity of two strings in C#

Is there any function in C# that check the % of similarity of two strings?
For example i have:
var string1="Hello how are you doing";
var string2= " hi, how are you";
and the
function(string1, string2)
will return similarity ratio because the words "how", "are", "you" are present in the line.
Or even better, return me 60% of similarity because "how", "are", "you" is a 3/5 of string1.
Does any function exist in C# which do that?
A common measure for similarity of strings is the so-called Levenshtein distance or edit distance. In this approach, a certain defined set of edit operation is defined. The Levenshtein distance is the minimum number of edit steps which is necessary to obtain the second string from the first. Closely related is the Damerau-Levenshtein distance, which uses a different set of edit operations.
Algorithmically, the Levenshtein distance can be calculated using Dynamic programming, which can be considered efficient. However, note that this approach does not actually take single words into account and cannot directly express the similarity in percent.
Now i am going to risk a -1 here for my suggestions, but in situations where you are trying to get something which is close but not so complex, then there is a lot of simpler solutions then the Levenshtein distance, which is perfect if you need exakt results and have time to code it.
If you are a bit looser concerning the accuracy, then i would follow this simple rules:
compare literal first (strSearch == strReal) - if match exit
convert search string and real string to lowercase
remove vowels and other chars from strings [aeiou-"!]
now you have two converted strings. your search string:
mths dhlgrn mtbrn
and your real string to compare to
rstrnt mths dhlgrn
compare the converted strings, if they match exit
split only the search strings by its words either with simple split function or using Regular Expressions \W+
calculate the virtual value (weight) of one part by dividing 100 by the number of parts - in this case 33
compare each part of the search string with the
real string, if it is contained, and add the value for each match to your total weight. In this case we have three elements and two matches so the result is 66 - so 66% match
This method is simple and extendable to go more and more in detail, actually you could use steps 1-7 and if step 7 returns anything above 50% then you figure you have a match, and otherwise you use more complex calculations.
ok, now don't -1 me too fast, because other answers are perfect, this is just a solution for lazy developers and might be of value there, where the result fulfills the expectations.
You can create a function that splits both strings into arrays, and then iterate over one of them to check if the word exists in the other one.
If you want percentage of it you would have to count total amount of words and see how many are similar and create a number based on that.

How to compare an array loaded from file with another array loaded from another file c#

I have to do a program in C# Form, which has to load from a file which looks something like that:
100ACTGGCTTACACTAATCAAG
101TTAAGGCACAGAAGTTTCCA
102ATGGTATAAACCAGAAGTCT
...
120GCATCAGTACGTACCCGTAC
20 lines formed with a number (ID) and 20 letters (ADN); the other file looks like that:
TGCAACGTGTACTATGGACC
In few words, this is a game where a murder is done, there are 20 people; i have to load and split the letters and.. i have to compare them and in the end i have to find the best match.
I have no idea how to do that, I don't know how to load the letters in the array and then to split them.. and then to compare them.
What you want to do here, is use something like a calculation of the Levenshtein distance between the strings.
In simple terms, that provides a count of how many single letters you have to change for a string to become equal to another. In the context of DNA or Proteins, this can be interpreted as representing the number of mutations between two individuals or samples. A shorter distance will therefore indicate a closer relationship between the two.
The algorithm can be fairly heavy computationally, but will give you a good answer. It's also quite fun and enlightening to implement. You can find a couple of ways of implementing it under the wikipedia article.
If you find it challenging to understand how it works, I recommend you set up an example grid by hand, with one short string horizontally along the top, and one vertically along the left side, and try going through the calculations manually, just to understand the concept properly (it can be confusing at first, but is really not that difficult).
This is a simple match function. It might not be of the complexity your game requires. This solution does not require an explicit split on the strings in order to get an array of DNA "letters". The DNA is compared in place.
Compare each "suspect" entry to the "evidence one.
int idLength = 3;
string evidence = //read from file
List<string> suspects = //read from file
List<double> matchScores = new List<double>();
foreach (string suspect in suspects)
{
int count = 0;
for (int i = idLength; i < suspect.Length; i++)
{
if (suspect[i + idLength] == evidence[i]) count++;
}
matchScores.Add(count * 100 / evidence.Length);
}
The matchScores list now contains all the individual match scores. I did not save the maximum match score in a separate variable as there can be several "suspects" with the same score. To find out which subject has the best match, just iterate the matchScores list. The index of the best match is the index of the suspect in the suspects list.
Optimization notes:
you could check each "suspect" string to see where (i.e. at what index does) the DNA sequence starts, as it could be variable;
a dictionary could be used here, instead of two lists, with the "suspect string" as key and the match score as value

Categories