Finding highest number in text file - algorithm

I have a text file that contains 50 student names and scores for each student in the format.
foreName.Surname:Mark
I have figured out how to split up each line into a forename, surname and mark using this code.
string[] Lines = File.ReadAllLines(#"StudentExamMarks.txt");
int i = 0;
var items = from line in Lines
where i++ != 0
let words = line.Split(' ', '.', ':')
select new
{
foreName = words[0],
Surname = words[1],
Mark = words[2]
};
I am unsure of how i would incorporate a findMax algorithm into to find the highest mark and display the pupil with the highest mark. this as i have not used text files that often.

You can use any sorting algorithm there is a Pseudo Code available to find maximum number in any list or array..

Try this code, required just parse all files.
string[] lines = File.ReadAllLines(#"StudentExamMarks.txt");
string maxForeName = null;
string maxSurName = null;
var maxMark = 0;
for (int i = 0; i < lines.Length; i++)
{
var tmp = lines[i].Split(new char[] { ' ', '.', ':' }, StringSplitOptions.RemoveEmptyEntries);
if (tmp.Length == 3)
{
int value = int.Parse(tmp[2]);
if (i == 0 || value > maxMark)
{
maxMark = value;
maxForeName = tmp[0];
maxSurName = tmp[1];
}
}
}

Related

How to chech if the string characters have equal duplicates

I want to Check if the characters of a string have equal duplicate
if I enter :"abaababb"
returns true because I have 4 'a' and 4 'b' in that string
if I enter : "addda"
returns false because I have 2 'a' and 3 'd'
I tryed to check the duplicates but I found out I have to do it for some characters
just need to create an empty object and loop through each character and increment the value associated with the key. Keep track of the highest value so we can easily use every on the array from Object.values and check if all character counts match this value
let check = "abaababb";
let check2 = "addda";
function hasEqualCharacters( input ) {
let characters = {};
let highestCount = 0;
for( let i =0; i < input.length; i++) {
if( characters[input[i]]) {
characters[input[i]]++;
if( highestCount < characters[input[i]]) {
highestCount = characters[input[i]];
}
} else {
characters[input[i]] = 1;
}
}
return Object.values(characters).every( (charCount) => {
return charCount === highestCount;
});
}
console.log(hasEqualCharacters(check));
console.log(hasEqualCharacters(check2));
Can see it working here
https://playcode.io/1024243

rank items in list of string in dart

Let's consider a list:
List<String> recipeNamesList = [
'Burger',
'French Fries',
'Pizza',
'Bengali Lamb Curry',
'Chingri Malai Curry',
]
If the user searches Bengali Lamb Fries I need to return Bengali lamb curry and French Fries.
Benagli Lamb Curry will have the highest rank since it has 2 words matching and French Fries has only one word that matches.
So the returned list will be something like this:
List<String> result = [
'Bengali Lamb Curry',
'French Fries'
]
My current code:
Future<List<String>> getSuggestions(String search) async {
List<String> results = [];
List<String> searchSplit =
search.toLowerCase().split(" "); // split the search query
for (int i = 0; i < searchSplit.length; i++) {
// iterate over search query
for (int j = 0; j < recipeNamesList.length; j++) {
// iterate over the recipe names list
List<String> recipeNamesListSplit =
recipeNamesList[j].split(" "); // split the recipe names
for (int k = 0; k < recipeNamesListSplit.length; k++) {
// iterate over the list of splitted name
if (recipeNamesListSplit[k]
.toLowerCase()
.startsWith(searchSplit[i])) {
// convert to lower case and check if the query is present in splitted name
results
.add(recipeNamesList[j]); // if contains == true add to results
}
}
}
}
// Avoid repeated values
results = results.toSet().toList();
return results;
}
It's a completely ad-hoc that only matches if the query word is present in the recipeNamesList. And if so adds them to the results list. It does not rank which recipe has the most matched words from the search query.
How am I supposed to rank? Is it possible with my current code with modifications? Or do I need to completely change my code?
You need to modify your method as
Future<List<String>> getSuggestions(String search) async {
List<String> result = [];
recipeNamesList.forEach((word){
int value = getMatching(search,word);
if(value > 0){
if(result.isNotEmpty){
if(getMatching(search,result[0]) > value){
//only insert the maximum matched value at starting. it is some type of sorting
result.add(word);
}else{
result.insert(0,word);
}
}else{
result.add(word);
}
}
});
}
A basic function to count the exact matched words
int getMatching(String input, String word){
List<String> inn = input.split(' ');
List<String> words = word.split(' ');
int temp = 0;
inn.forEach((inWord){
if(words.contains(inWord)){
temp++;
}
});
return temp;
}
Output with the input getSuggestions('Bengali Lamb Fries')

Split and format text output with separators Xamarin Forms

I have an entry and label I want to format my text to my label like this:
"email#gmail.com", "email2#gmail.com", "email3#gmail.com"
this is what I enter in my entry field:
email#gmail.com /space/ email2#gmail.com /space/ email3#gmail.com or
email#gmail.com,email2#gmail.com,email3#gmail.com
The separator is a space or comma. How can I format my output to the one above?
Good question!
string entry = Entry.Text;
List<string> arrayfromEntry = new List<string>();
if (entry.Contains(" ") == true){
arrayfromEntry = entry.Split(new char[] { ' ' }).ToList();
}
else{
arrayfromEntry = entry.Split(new char[] { ',' }).ToList();
}
for (int i = 0; i < arrayfromEntry.Count(); i++){
arrayfromEntry[i] = '"' + arrayfromEntry[i] + '"';
}
string f = (string.Join(", ",arrayfromEntry));
f = f.Remove(f.Count()-2,2);
f = f+'"';
textToLabel = f;
Where Entry.Text is the text from your entry and textToLabel changes the text of your label, this should work.
Based on the #jamesfdearborn answer, but using StringBuilder instead
string entry == "aaaa#ttttt.com,bbbb#ttttttyyy.com,tttt#errrer.com,yyyyyy#rrrttr.com,uuuuu#yuyuy.com";
var inputSeparator = ','; //comma is the separator in this case you can change it
var outputSeparator = ',';
var arrayfromEntry = entry.Split(inputSeparator).ToList();
var sb = new StringBuilder();
for (int i = 0; i < arrayfromEntry.Count(); i++)
{
sb.AppendFormat("\"{0}\"{1}",arrayfromEntry[i],outputSeparator);
}
sb.Remove(sb.ToString().Count()-1, 1);
sb.ToString() //result here
//output
//"aaaa#ttttt.com","bbbb#ttttttyyy.com","tttt#errrer.com","yyyyyy#rrrttr.com","uuuuu#yuyuy.com"
you can change the output or the the input separator

InDesign Text Modification Script Skips Content

This InDesign Javascript iterates over textStyleRanges and converts text with a few specific appliedFont's and later assigns a new appliedFont:-
var textStyleRanges = [];
for (var j = app.activeDocument.stories.length-1; j >= 0 ; j--)
for (var k = app.activeDocument.stories.item(j).textStyleRanges.length-1; k >= 0; k--)
textStyleRanges.push(app.activeDocument.stories.item(j).textStyleRanges.item(k));
for (var i = textStyleRanges.length-1; i >= 0; i--) {
var myText = textStyleRanges[i];
var converted = C2Unic(myText.contents, myText.appliedFont.fontFamily);
if (myText.contents != converted)
myText.contents = converted;
if (myText.appliedFont.fontFamily == 'Chanakya'
|| myText.appliedFont.fontFamily == 'DevLys 010'
|| myText.appliedFont.fontFamily == 'Walkman-Chanakya-905') {
myText.appliedFont = app.fonts.item("Utsaah");
myText.composer="Adobe World-Ready Paragraph Composer";
}
}
But there are always some ranges where this doesn't happen. I tried iterating in the forward direction OR in the backward direction OR putting the elements in an array before conversion OR updating the appliedFont in the same iteration OR updating it a different one. Some ranges are still not converted completely.
I am doing this to convert the Devanagari text encoded in glyph based non-Unicode encoding to Unicode. Some of this involves repositioning vowel signs etc and changing the code to work with find/replace mechanism may be possible but is a lot of rework.
What is happening?
See also: http://cssdk.s3-website-us-east-1.amazonaws.com/sdk/1.0/docs/WebHelp/app_notes/indesign_text_frames.htm#Finding_and_changing_text
Sample here: https://www.dropbox.com/sh/7y10i6cyx5m5k3c/AAB74PXtavO5_0dD4_6sNn8ka?dl=0
This is untested since I'm not able to test against your document, but try using getElements() like below:
var doc = app.activeDocument;
var stories = doc.stories;
var textStyleRanges = stories.everyItem().textStyleRanges.everyItem().getElements();
for (var i = textStyleRanges.length-1; i >= 0; i--) {
var myText = textStyleRanges[i];
var converted = C2Unic(myText.contents, myText.appliedFont.fontFamily);
if (myText.contents != converted)
myText.contents = converted;
if (myText.appliedFont.fontFamily == 'Chanakya'
|| myText.appliedFont.fontFamily == 'DevLys 010'
|| myText.appliedFont.fontFamily == 'Walkman-Chanakya-905') {
myText.appliedFont = app.fonts.item("Utsaah");
myText.composer="Adobe World-Ready Paragraph Composer";
}
}
A valid approach is to use hyperlink text sources as they stick to the genuine text object. Then you can edit those source texts even if they were actually moved elsewhere in the flow.
//Main routine
var main = function() {
//VARS
var doc = app.properties.activeDocument,
fgp = app.findGrepPreferences.properties,
cgp = app.changeGrepPreferences.properties,
fcgo = app.findChangeGrepOptions.properties,
text, str,
found = [], srcs = [], n = 0;
//Exit if no documents
if ( !doc ) return;
app.findChangeGrepOptions = app.findGrepPreferences = app.changeGrepPreferences = null;
//Settings props
app.findChangeGrepOptions.properties = {
includeHiddenLayers:true,
includeLockedLayersForFind:true,
includeLockedStoriesForFind:true,
includeMasterPages:true,
}
app.findGrepPreferences.properties = {
findWhat:"\\w",
}
//Finding text instances
found = doc.findGrep();
n = found.length;
//Looping through instances and adding hyperlink text sources
//That's all we do at this stage
while ( n-- ) {
srcs.push ( doc.hyperlinkTextSources.add(found[n] ) );
}
//Then we edit the stored hyperlinks text sources 's texts objects contents
n = srcs.length;
while ( n-- ) {
text = srcs[n].sourceText;
str = text.contents;
text.contents = str+str+str+str;
}
//Eventually we remove the added hyperlinks text sources
n = srcs.length;
while ( n-- ) srcs[n].remove();
//And reset initial properties
app.findGrepPreferences.properties = fgp;
app.changeGrepPreferences.properties = cgp;
app.findChangeGrepOptions.properties =fcgo;
}
//Running script in a easily cancelable mode
var u;
app.doScript ( "main()",u,u,UndoModes.ENTIRE_SCRIPT, "The Script" );

Algorithm to generate all variants of a word

i would like to explain my problem by the following example.
assume the word: abc
a has variants: ä, à
b has no variants.
c has variants: ç
so the possible words are:
abc
äbc
àbc
abç
äbç
àbç
now i am looking for the algorithm that prints all word variantions for abritray words with arbitray lettervariants.
I would recommend you to solve this recursively. Here's some Java code for you to get started:
static Map<Character, char[]> variants = new HashMap<Character, char[]>() {{
put('a', new char[] {'ä', 'à'});
put('b', new char[] { });
put('c', new char[] { 'ç' });
}};
public static Set<String> variation(String str) {
Set<String> result = new HashSet<String>();
if (str.isEmpty()) {
result.add("");
return result;
}
char c = str.charAt(0);
for (String tailVariant : variation(str.substring(1))) {
result.add(c + tailVariant);
for (char variant : variants.get(c))
result.add(variant + tailVariant);
}
return result;
}
Test:
public static void main(String[] args) {
for (String str : variation("abc"))
System.out.println(str);
}
Output:
abc
àbç
äbc
àbc
äbç
abç
A quickly hacked solution in Python:
def word_variants(variants):
print_variants("", 1, variants);
def print_variants(word, i, variants):
if i > len(variants):
print word
else:
for variant in variants[i]:
print_variants(word + variant, i + 1, variants)
variants = dict()
variants[1] = ['a0', 'a1', 'a2']
variants[2] = ['b0']
variants[3] = ['c0', 'c1']
word_variants(variants)
Common part:
string[] letterEquiv = { "aäà", "b", "cç", "d", "eèé" };
// Here we make a dictionary where the key is the "base" letter and the value is an array of alternatives
var lookup = letterEquiv
.Select(p => p.ToCharArray())
.SelectMany(p => p, (p, q) => new { key = q, values = p }).ToDictionary(p => p.key, p => p.values);
A recursive variation written in C#.
List<string> resultsRecursive = new List<string>();
// I'm using an anonymous method that "closes" around resultsRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
// Recursive anonymous methods must be declared in this way in C#. Nothing to see.
Action<string, int, char[]> recursive = null;
recursive = (str, ix, str2) =>
{
// In the first loop str2 is null, so we create the place where the string will be built.
if (str2 == null)
{
str2 = new char[str.Length];
}
// The possible variations for the current character
var equivs = lookup[str[ix]];
// For each variation
foreach (var eq in equivs)
{
// We save the current variation for the current character
str2[ix] = eq;
// If we haven't reached the end of the string
if (ix < str.Length - 1)
{
// We recurse, increasing the index
recursive(str, ix + 1, str2);
}
else
{
// We save the string
resultsRecursive.Add(new string(str2));
}
}
};
// We launch our function
recursive("abcdeabcde", 0, null);
// The results are in resultsRecursive
A non-recursive version
List<string> resultsNonRecursive = new List<string>();
// I'm using an anonymous method that "closes" around resultsNonRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
Action<string> nonRecursive = (str) =>
{
// We will have two arrays, of the same length of the string. One will contain
// the possible variations for that letter, the other will contain the "current"
// "chosen" variation of that letter
char[][] equivs = new char[str.Length][];
int[] ixes = new int[str.Length];
for (int i = 0; i < ixes.Length; i++)
{
// We start with index -1 so that the first increase will bring it to 0
equivs[i] = lookup[str[i]];
ixes[i] = -1;
}
// The current "workin" index of the original string
int ix = 0;
// The place where the string will be built.
char[] str2 = new char[str.Length];
// The loop will break when we will have to increment the letter with index -1
while (ix >= 0)
{
// We select the next possible variation for the current character
ixes[ix]++;
// If we have exausted the possible variations of the current character
if (ixes[ix] == equivs[ix].Length)
{
// Reset the current character to -1
ixes[ix] = -1;
// And loop back to the previous character
ix--;
continue;
}
// We save the current variation for the current character
str2[ix] = equivs[ix][ixes[ix]];
// If we are setting the last character of the string, then the string
// is complete
if (ix == str.Length - 1)
{
// And we save it
resultsNonRecursive.Add(new string(str2));
}
else
{
// Otherwise we have to do everything for the next character
ix++;
}
}
};
// We launch our function
nonRecursive("abcdeabcde");
// The results are in resultsNonRecursive
Both heavily commented.

Resources