Another method to verify an Anagram [duplicate] - c#

This question already has answers here:
Sorting a C# List<> without LINQ or delegates
(1 answer)
Better way to sort array in descending order
(7 answers)
Simple bubble sort c#
(18 answers)
Closed 16 days ago.
I have a very simple and silly test that is to compare two strings and check if it is an anagram.
I found this question, bt besides being old, it has no correct answer.
This using LINQ.
This not solve my question.
I managed to solve it using LINQ and also using a foreach, but the next challenge is to do it using sorting (without using LINQ). An anagram is a word or phrase formed by rearranging the letters of a different word or phrase. We can generalize this in string processing by saying that an anagram of a string is another string with exactly the same quantity of each character in it, in any order.
How can I sort without using LINQ?
private static bool CheckAnagramWithLinq(string texto1, string texto2)
{
return texto1.ToList().Intersect(texto2.ToList()).ToList().Count == texto1.Length;
}
private static bool CheckAnagramaWithoutLinq(string texto1, string texto2)
{
var charArray = texto1.ToCharArray();
foreach (var caracter in charArray)
{
if (texto2.Contains(caracter) && texto1.Count(x => x == caracter) == texto2.Count(x => x == caracter))
continue;
return false;
}
return true;
}

Works for me:
private static bool CheckAnagram(string text1, string text2)
{
var aa = string.Concat(text1.OrderBy(c => c));
var bb = string.Concat(text2.OrderBy(c => c));
return aa == bb;
}

Related

Reverse an Array order and print it C# [duplicate]

This question already has answers here:
How to reverse an array using the Reverse method. C# [closed]
(6 answers)
Closed 6 months ago.
using System;
using System.Linq;
namespace Array.ReversingArrayChar
{
class Program
{
static void Main(string[] args)
{
string input = Console.ReadLine();
char[] symbol = input.Split(' ').Select(char.Parse).ToArray();
symbol.Reverse();
for (int a = 0; a <= symbol.Length - 1; a++)
{
Console.Write(symbol[a] + " ");
}
}
}
}
When I run the code I get the Array printed but not in reversed order even tho I used .Reverse(). It's probably a really simple mistake but it's too late at night for my brain to figure it out.
Enumerable.Reverse is a LINQ extension that returns the sequence reversed, so you have to assign it to a variable. But here you want to use Array.Reverse:
Array.Reverse(symbol);
Use Enumerable.Reverse if you don't want to modify the original collection and if you want to support any kind of sequence. Use List.Reverse or Array.Reverse if you want to support only these collections and you want to modify it directly. Of course this is more efficient since the method knows the size and you need less memory.
Oh Man..! you are almost there, your code is fine but you need to use the output of the .Reverse() method. since the method won't modify the actual collection, it will return the reversed array. you can try the following:
string input = "A S D R F V B G T";
char[] symbols = input.Split(' ').Select(char.Parse).ToArray();
foreach (var symbol in symbols.Reverse())
{
Console.Write(symbol + " ");
}
You will get the output as T G B V F R D S A

LINQ Select with a method that returns a type - creating a new list [duplicate]

This question already has answers here:
Convert a list to a string in C#
(14 answers)
Closed 9 months ago.
I am a mere beginner and I am trying to learn a bit of LINQ. I have a list of values and I want to receive a different list based on some computation. For example, the below is often quoted in various examples across the Internet:
IEnumerable<int> squares = Enumerable.Range(1, 10).Select(x => x * x);
here the "computation" is done by simply multiplying a member of the original list by itself.
I wanted to actually use a method that returns a string and takes x as an argument.
Here is the code I wrote:
namespace mytests{
class program {
static void Main (string[] args)
{
List<string> nums = new List<string>();
nums.Add("999");
nums.Add("888");
nums.Add("777");
IEnumerable<string> strings = nums.AsEnumerable().Select(num => GetStrings(num));
Console.WriteLine(strings.ToString());
}
private static string GetStrings (string num){
if (num == "999")
return "US";
else if (num == "888")
{
return "GB";
}
else
{
return "PL";
}
}
}
}
It compiles but when debugging, the method GetStrings is never accessed and the strings object does not have any members. I was expecting it to return "US", "GB", "PL".
Any advice on what I could be doing wrong?
Thanks.
IEnumerable<string>.ToString() method does not work as you expected. Result will be
System.Collections.Generic.List`1[System.String]
If you want to see the values which are held in the collection, you should create iteration.
foreach (var i in strings)
Console.WriteLine(i);
This line does two things for you. One of them is writing the values which are held in the collection to console. The other operation is iterating the collection. During iteration, values are needed and linq will execute the necessary operation (in your case GetStrings method).
Currently your code does not use the collection values, so the code does not evaluate the values and does not trigger GetStrings method.

Double.TryParse doesn't allow to use divisions (fractions) as input [duplicate]

This question already has answers here:
Convert a text fraction to a decimal
(5 answers)
Parse Math Expression [duplicate]
(9 answers)
Closed 3 years ago.
I have created a method that splits a string a^b and converts a and b to doubles. However, if I input the value of either a or b using a fraction (for example 3/5 instead of 0.6) the method doesn't work; it only allows me to input it like 0.6. Why is this, and is it possible to fix it?
The code is shown below:
public static double Coefficient()
{
while (true)
{
string input = Console.ReadLine();
string[] items = input.Split('^');
if (items.Length == 1)
{
if (double.TryParse(items[0], out double A))
return A;
}
else if (items.Length == 2)
{
if (double.TryParse(items[0], out double A) &
double.TryParse(items[1], out double B))
return Math.Pow(A, B);
}
Console.WriteLine("\nPlease follow the specified input form.");
}
}
You're trying to parse expressions with methods that only know how to handle specifically formatted numbers as inputs. You need to either write an equation parser or split your inputs appropriately. You are already doing this by splitting ^ - you can do the same with /.
In fact, there are libraries that already do this.

C# Equivalent to Python's map()? [duplicate]

This question already has answers here:
Assign values of array to separate variables in one line
(8 answers)
Closed 4 years ago.
Normally in Python 2/3 we may use the following code to split two space-separated integers into two variables:
a,b = map(int,input().split())
Is there a short C# equivalent to this? (i.e nothing as long as below)
string[] template = Console.ReadLine().Split();
a = Convert.ToInt32(template[0]);
b = Convert.ToInt32(template[1]);
You could try this:
var result = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
However, the above code would crash if the input is not valid.
A more fault tolerant approach would be the following:
var result = Console.ReadLine()
.Split(' ')
.Select(input =>
{
int? output = null;
if(int.TryParse(input, out var parsed))
{
output = parsed;
}
return output;
})
.Where(x => x != null)
.Select(x=>x.Value)
.ToArray();
It's called Select(). You need to import Linq:
using System.Linq;
Then you can use it similar to map. Be aware that it is an extension function and is not the exact equivalent.
var integers = Console.ReadLine().Split().Select(s => Convert.ToInt32(s)).ToArray();
var a = integers[0];
var b = integers[1];
This example lacks any proper error handling.
Edit
Add ToArray()
Write out lambda, which is needed due to the overloads of Convert.ToInt32

How to count from a sentence in C# [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So, I am creating a word filter for a game server in C# and basically I am trying to scourer the sentence for banned words and replace them with clean words. I've already done so, but now I'm up to the part where I want to scan the sentence for a list of sentence banned words. I'm hopeless at this bit, and I can't seem to wrap my head around it.
Basically I am CheckSentence(Message) in the ChatManager, and need the following code to count and return continue; if the value is more than 5. So far I have:
public bool CheckSentence(string Message)
{
foreach (WordFilter Filter in this._filteredWords.ToList())
{
if (Message.ToLower().Contains(Filter.Word) && Filter.IsSentence)
{
// count Message, if message contains >5
// from (Message.Contains(Filter.Word))
// continue; else (ignore)
}
}
return false;
}
I'm not too sure if that makes much sense, but I want it to continue; if there are more than 5 Message.Contains(Filter.Word)
public bool CheckSentence(string rawMessage)
{
var lower = rawMessage.ToLower();
var count = 0;
foreach (WordFilter Filter in this._filteredWords.ToList())
{
if (lower.Contains(Filter.Word) && Filter.IsSentence)
{
count++;
}
}
return count >= 5;
}
If this becomes too slow, you may be better of caching the list of filtered words in a HashSet, and iterating over each word in the message, checking if it exists in the HashSet, which would give you O(n) speed, where N is the number of words.
LINQ Version
public bool CheckSentenceLinq(string rawMessage)
{
var lower = rawMessage.ToLower();
return _filteredWords
.Where(x => x.IsSentence)
.Count(x => lower.Contains(x.Word)) >= 5;
}
EDIT 2: LINQ Updated As per #S.C. Comment
By #S.C.
For the linq version, there's no need to count past the first five. return _filteredWords.Where(x => x.IsSentence && lower.Contains(x.Word)).Skip(5).Any();
public bool CheckSentenceLinq(string rawMessage)
{
var lower = rawMessage.ToLower();
return _filteredWords
.Where(x => x.IsSentence)
.Where(x => lower.Contains(x.Word))
.Skip(5)
.Any();
}
ToUpper vs ToLower
As #DevEstacion mentioned and per Microsoft best practices for using string recommendations here it is best to use ToUpperInvariant() for string comparisons rather than ToLowerInvariant().
EDIT:Using Continue
public bool CheckSentenceWithContinue(string rawMessage)
{
var lower = rawMessage.ToLower();
var count = 0;
foreach (WordFilter Filter in this._filteredWords.ToList())
{
if (!Filter.IsSentence)
continue; // Move on to the next filter, as this is not a senetece word filter
if (!lower.Contains(Filter.Word))
continue; // Move on to the next filter, as the message does not contain this word
// If you are here it means filter is a Sentence filter, and the message contains the word, so increment the counter
count++;
}
return count >= 5;
}
I believe someone already posted a correct answer, I'm just here to provide an alternative.
So instead of doing a forloop or foreach, I'll be providing you with Regex solution.
public bool CheckSentence(string rawMessage)
{
/*
The string.Join("|", _filteredWords) will create the pattern for the Regex
the '|' means or so from the list of filtered words, it will look it up on
the raw message and get all matches
*/
return new Regex(string.Join("|", _filteredWords.Where(x => x.IsSentence)),
RegexOptions.IgnoreCase | RegexOptions.Compiled).Match(rawMessage).Length >= 5;
}
Benefits? much shorter, prevents loop and could be faster :)
Don't forget to add these two lines of using declaration on top of the .cs file
using System.Linq;
using System.Text.RegularExpressions;

Categories