How to detect the 3rd, 4th, 5th letter in a string C# - c#

I have a string structured like:
string s = "0R 0R 20.0V 100.0V 400.0R 60R 70.0R";
My question is, how would I detect only the 3rd, 4th, 5th letter through if statements like so:
3rd letter = V
4th letter = V
5th letter = R
//pseudocode below
if (3rd letter in string == V)
{
return true;
}
if (4th letter in string == V)
{
return true;
}
if (5th letter in string == R)
{
return true;
}
or through print statements:
3rd letter = V
4th letter = V
5th letter = R
// Pseudocode below:
Console.WriteLine("3rd Letter"); //should return V
Console.WriteLine("4th Letter"); //should return V
Console.WriteLine("5th Letter"); //should return R
I was thinking of using a foreach loop to loop through the string but I am unsure how to detect when it is the 3rd, 4th, 5th letter, I know that regex may help but I'm not sure how to implement the expression
string s = "0R 0R 20.0V 100.0V 400.0R 60R 70.0R";
foreach(char c in s)
{
// detect 3rd 4th 5th letter in here
}

First, let's extract / match letters either with a help of Linq:
using System.Linq;
...
string[] letters = s
.Where(c => c >= 'A' && c <= 'Z')
.Select(c => c.ToString())
.ToArray();
or regular expressions:
using System.Linq;
using System.Text.RegularExpressions;
...
string[] letters = Regex
.Matches(s, "[A-Z]")
.Cast<Match>()
.Select(m => m.Value)
.ToArray();
Then you can put as easy as
string letter3d = letters[3 - 1]; // - 1 : arrays are zero based
string letter4th = letters[4 - 1];
string letter5th = letters[5 - 1];

Related

Find and Count works but not the way I want

byte count = 0;
string word = "muumuu";
string res= word;
bool flg = true;
foreach(char ch in word)
{
res = res.Remove(0,1);
if(res.Contains(ch))
{
flg = false;
count ++;
Console.WriteLine($"there are {count} same chars : {ch}");
}
}
if(flg)
{
Console.WriteLine($"All chars are different in : {word} ");
}
The output is :
there are 1 same chars : m
there are 2 same chars : u
there are 3 same chars : u
there are 4 same chars : u
The question is how to count same chars like :
there are 2 same chars : m
there are 4 same chars : u
You have to separate the counting from the output of the result.
The following solution collects the character counts in a dictionary and after that displays the contents of the dictionary:
string word = "muumuu";
var counts = new Dictionary<char, int>();
foreach (var ch in word)
{
if (counts.ContainsKey(ch))
counts[ch]++;
else
counts[ch] = 1;
}
foreach (var chCount in counts)
{
Console.WriteLine($"{chCount.Value} occurrences of '{chCount.Key}'");
}
A very compact alternative solution using Linq GroupBy method:
string word = "muumuu";
foreach (var group in word.GroupBy(c => c))
{
Console.WriteLine($"{group.Count()} occurrences of '{group.Key}'");
}
GroupBy groups the characters in the word so that each distinct character creates a group and each group contains the collected identical characaters. These can then be counted using Count.
Result:
2 occurrences of 'm'
4 occurrences of 'u'
Klaus' answer might be easier to understand, but you can also use this function which does mostly the same thing:
public static int CountDuplicates(string str) =>
(from c in str.ToLower()
group c by c
into grp
where grp.Count() > 1
select grp.Key).Count();
Usage: var dupes = $"{word} - Duplicates: {CountDuplicates(word)}";

How can I find a certain letter in a String in C#?

How can I search a certain letter (char) in a String?
I have to code a little riddle. You basicalley have to guess the right letters of an unknown word. Only the first letter is shown.
Example: "Apple"
A____ --> that's what you actually see. Now, the player has to input a letter/char and if it is inculded in the String "Apple", the correct letter will be added.
Example: input = e
A___e
Thx.
You can use String.IndexOf.
Example:
var str = "Apple";
var c = 'p';
var i = str.IndexOf(c);
// i will be the index of the first occurrence of 'p' in str, or -1 if not found.
if (i == -1)
{
// not found
}
else
{
do
{
// do something with index i, which is != -1
i = str.IndexOf(c, i + 1);
} while (i != -1);
}
If you want to find all letter indices, you can try this LINQ solution:
var str = "Apple";
var letter = 'p';
var charIndexMap = str
.Select((ch, idx) => (ch, idx))
.GroupBy(pair => pair.ch)
.ToDictionary(entry => entry.Key,
entry => entry.Select(pair => pair.idx));
if (charIndexMap.TryGetValue(letter, out var value))
{
Console.WriteLine("[" + string.Join(", ", value) + "]");
} else
{
// not found
}
Output:
[1, 2]
Explanation:
Use Enumerable.Select to map over the characters and indices and convert them to (character, index) tuples.
Use Enumerable.GroupBy to group tuples by character.
Convert grouped results to a dictionary using Enumerable.ToDictionary, which maps each character to an IEnumerable<int> of indices.
Use Dictionary<TKey,TValue>.TryGetValue(TKey, TValue) to get the associated indices for the letter.

How to count 2 or 3 letter words in a string using asp c#

How to count 2 or 3 letter words of a string using asp csharp, eg.
string value="This is my string value";
and output should look like this
2 letter words = 2
3 letter words = 0
4 letter words = 1
Please help, Thanks in advance.
You can try something like this:
split sentence by space to get array of words
group them by length of word (and order by that length)
iterate through every group and write letter count and number of words with that letter count
code
using System.Linq;
using System.Diagnostics;
...
var words = value.Split(' ');
var groupedByLength = words.GroupBy(w => w.Length).OrderBy(x => x.Key);
foreach (var grp in groupedByLength)
{
Debug.WriteLine(string.Format("{0} letter words: {1}", grp.Key, grp.Count()));
}
First of all you need to decide what counts as a word. A naive approach is to split the string with spaces, but this will also count commas. Another approach is to use the following regex
\b\w+?\b
and collect all the matches.
Now you got all the words in a words array, we can write a LINQ query:
var query = words.Where(x => x.Length >= 2 && x.Length <= 4)
.GroupBy(x => x.Length)
.Select(x => new { CharCount = x.Key, WordCount = x.Count() });
Then you can print the query out like this:
query.ToList().ForEach(Console.WriteLine);
This prints:
{ CharCount = 4, WordCount = 1 }
{ CharCount = 2, WordCount = 2 }
You can write some code yourself to produce a more formatted output.
If i understood your question correctly
You can do it using dictionary
First split the string by space in this case
string value = "This is my string value";
string[] words = value.Split(' ');
Then loop trough array of words and set the length of each word as a key of dictionary, note that I've used string as a key, but you can modify this to your needs.
Dictionary<string, int> latteWords = new Dictionary<string,int>();
for(int i=0;i<words.Length;i++)
{
string key = words[i].Length + " letter word";
if (latteWords.ContainsKey(key))
latteWords[key] += 1;
else
latteWords.Add(key, 1);
}
And the output would be
foreach(var ind in latteWords)
{
Console.WriteLine(ind.Key + " = " + ind.Value);
}
Modify this by wish.

Split String to array and Sort Array

I am trying to sort a string split by comma. But it is not behaving as expected
var classes = "10,7,8,9";
Console.Write(string.Join(",", classes.Split(',').OrderBy(x => x)));
Console.ReadKey();
and output is
10,7,8,9
But I want the expected output to be like:
7,8,9,10
Classes can have a section along with them. like 7a,7b
and I want to achieve it on one line of code.
You can use Regex like this
var classes = "10,7,8,9";
Regex number = new Regex(#"^\d+");
Console.Write(string.Join(",", classes.Split(',').OrderBy(x => Convert.ToInt32(number.Match(x).Value)).ThenBy(x => number.Replace(x, ""))));
Console.ReadKey();
CODE:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
var l = new List<string> { "1D", "25B", "30A", "9C" };
l.Sort((b, a) =>
{
var x = int.Parse(Regex.Replace(a, "[^0-9]", ""));
var y = int.Parse(Regex.Replace(b, "[^0-9]", ""));
if (x != y) return y - x;
return -1 * string.Compare(a, b);
});
foreach (var item in l) Console.WriteLine(item);
}
}
}
OUTPUT:
1D
9C
25B
30A
ONLINE COMPILE:
http://rextester.com/CKKQK66159
Use the following using-directive:
using System.Text.RegularExpressions;
And try the following:
var input = "7,7a,8,9a,9c,9d,10";
var sorted = from sp in input.Split(',')
let reg = Regex.Match(sp, #"(?<num>[0-9]+)(?<char>[a-z]*)", RegexOptions.IgnoreCase | RegexOptions.Compiled)
let number = int.Parse(reg.Groups["num"].ToString())
orderby reg.Groups["char"].ToString() ascending // sort first by letter
orderby number ascending // then by number
select sp;
var result = string.Join(",", sorted);
Console.WriteLine(result);
//output (tested): 7,7a,8,9a,9c,9d,10
It uses regex to determine the numeric and alphabetic part of the input string.
The regex pattern uses named groups, which are noted as follows: (?<group_name> regex_expr ).
The time complexity of the code above is O(n log(n)), in case you are worried about big collections of numbers.
More information about named Regex groups.
More information about LINQ.
... and about the orderby-clause.
All on one line, also supports '4a' etc.
edit: On testing this, a string such as 1,2,111,3 would display as 111,1,2,3, so may not quite be what you're looking for.
string str = "1,2,3,4a,4b,5,6,4c";
str.Split(',').OrderBy(x => x).ToList().ForEach(x=> Console.WriteLine(x));
Console.ReadKey();
Here is my implementation:
IEnumerable<Tuple<string, string[]>> splittedItems =
items.Select(i => new Tuple<string, string[]>(i, Regex.Split(i, "([0-9]+)")));
List<string> orderedItems = splittedItems.OrderBy(t => Convert.ToInt16(t.Item2[1]))
.ThenBy(t => t.Item2.Length > 1 ? t.Item2[2] : "1")
.Select(t => t.Item1).ToList();
Split the input to a number and non numeric characters
Store the splitted strings with their parent string
Order by number
Then order by non numeric characters
Take the parent string again after sorting
The result is like required: { "10", "7", "8b", "8a", "9" } is sorted to { "7", "8a", "8b", "9", "10" }
You are sorting strings (alphabetically), so yes, "10" comes before "7".
My solution converts "10,7b,8,7a,9b" to "7a,7b,8,9b,10" (first sort by the integer prefix, then by the substring itself).
Auxiliary method to parse the prefix of a string:
private static int IntPrefix(string s)
=> s
.TakeWhile(ch => ch >= '0' && ch <= '9')
.Aggregate(0, (a, c) => 10 * a + (c - '0'));
Sorting the substrings by the integer prefix then by the string itself:
classes.Split(',') // string[]
.Select(s => new { s, i = IntPrefix(s) }) // IEnumerable<{ s: string, i: int }>
.OrderBy(si => si.i) // IEnumerable<{ s: string, i: int }>
.ThenBy(si => si.s) // IEnumerable<{ s: string, i: int }>
.Select(si => si.s) // IEnumerable<string>
One liner (with string.Join):
var result = string.Join(",", classes.Split(',').Select(s => new {s, i = IntPrefix(s)}).OrderBy(si => si.i).ThenBy(si => si.s).Select(si => si.s));

How to find 1 in my string but ignore -1 C#

I have a string
string test1 = "255\r\n\r\n0\r\n\r\n-1\r\n\r\n255\r\n\r\n1\r";
I want to find all the 1's in my string but not the -1's. So in my string there is only one 1. I use string.Contain("1") but this will find two 1's. So how do i do this?
You can use regular expression:
string test1 = "255\r\n\r\n0\r\n\r\n-1\r\n\r\n255\r\n\r\n1\r";
// if at least one "1", but not "-1"
if (Regex.IsMatch(test1, "(?<!-)1")) {
...
}
the pattern is exactly 1 which is not preceed by -. To find all the 1s:
var matches = Regex
.Matches(test1, "(?<!-)1")
.OfType<Match>()
.ToArray(); // if you want an array
Try this simple solution:
Note : You can convert this to extension Method Easily.
static List<int> FindIndexSpecial(string search, char find, char ignoreIfPreceededBy)
{
// Map each Character with its Index in the String
var characterIndexMapping = search.Select((x, y) => new { character = x, index = y }).ToList();
// Check the Indexes of the excluded Character
var excludeIndexes = characterIndexMapping.Where(x => x.character == ignoreIfPreceededBy).Select(x => x.index).ToList();
// Return only Indexes who match the 'find' and are not preceeded by the excluded character
return (from t in characterIndexMapping
where t.character == find && !excludeIndexes.Contains(t.index - 1)
select t.index).ToList();
}
Usage :
static void Main(string[] args)
{
string test1 = "255\r\n\r\n0\r\n\r\n-1\r\n\r\n255\r\n\r\n1\r";
var matches = FindIndexSpecial(test1, '1', '-');
foreach (int index in matches)
{
Console.WriteLine(index);
}
Console.ReadKey();
}
You could use String.Split and Enumerable.Contains or Enumerable.Where:
string[] lines = test1.Split(new[] {Environment.NewLine, "\r"}, StringSplitOptions.RemoveEmptyEntries);
bool contains1 = lines.Contains("1");
string[] allOnes = lines.Where(l => l == "1").ToArray();
String.Contains searches for sub-strings in a given string instance. Enumerable.Contains looks if there's at least one string in the string[] which equals it.

Categories

Resources