How to analyze strings - c#

I am trying to take a string of numbers each separated by a space, and turn it into a list. The user inputs the string of numbers by typing a number, then a space, as needed. This goes into "myString." I want to take the string and take just the numbers, and add it to myList. The code I want to create is something like this:
for(int i = 0; i < myString.Length; i++)
{
//If its not a space, add it to the list
if (myString[i] != " ")
{
myList.Add(prices[i]);
}
}
The error however says that you cannot use the '!=' operator to the types char, and string. Makes sense, but I am having a hard time finding an alternative. Is there a more efficient way to turn a string of: "1 2 3 4 5" into a List?
This is for the google jams code challenge, as I am just practicing on old questions. The link can be found here:
https://code.google.com/codejam/contest/351101/dashboard#s=p0
Thank you for all the help guys! I'm always amazed at how helpful SO is for High School programmers like me who still really have no clue what they're doing :-)

Use Split method instead
var numbers = myString.Split().Select(x => int.Parse(x)).ToArray();
BTW,in order to represent a char constant single quotes are used in C#. So as already mentioned in the comments, " " is a string literal that contains a space not a char.You should use ' '

Two things:
First, to fix your error change your line to:
if (myString[i] != ' ') // change to single quotes.
Second, there is an easier way:
string.Split(new char[] {' '}); // this will return the array you're seeking...

myString[i] is a char, so instead of " " you should use ' ' single quotes.

You can use the String.Split method to split the string on the spaces, resulting in a list of stirngs representing the numbers.
myList = myString.Split(" ");

You need to split your string on space. You can use LINQ like:
List<int> list = myString.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToList();
If you want a safer option and replace any invalid entry to -1 you can use int.TryParse like:
int temp;
List<int> list = myString.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(r => { return int.TryParse(r, out temp) ? temp : -1; })
.ToList();

Related

how to split a string on every parenthese and keep all text into an array in c#

I'm trying to split a string on every parenthese into an array and keep all text in C#, get everything in the parenthese.
Example: "hmmmmmmmm (asdfhqwe)asasd"
Should become: "hmmmmmmmm", "(asdfhqwe)" and "asasd".
My current setup is only able to take everything inside the parentheses and discards the rest.
var output = input.Split('(', ')').Where((item, index) => index % 2 != 0).ToList();
How would i go forward to do such thing (disregarding my current code) ?
Use regrx split with positive look-ahead and look-behind and an optional space; then filter out empty strings.
var tokens = Regex
.Split(str, #"(?<=[)])\s*|\s*(?=[(])")
.Where(s => s != string.Empty)
.ToList();
Demo.
Oky so I do not know what the real string will look like in your application, but based on the provided string this will be my hack of a solution:
string sample = "hmmmmmmmm (asdfhqwe)asasd";
var result = sample.Replace("(", ",(").Replace(")", "),").Split(',');
So i replaced where the split should be with a comma, but you can use any other char that might never occur in your string, Say like the '~' could also work.
But not knowing all the required functionality, this would work for above scenario.
Try this:
string[] subString = myString.Split(new char[] { '(', ')' });

Converting array of string to string with a defined separator

I have the following code:
var days = new string[] { "1", "2", "3", "4" });
I need to convert days to a string as following:
string daysConverted = "'1','2','3','4'";
I tried using string.Join:
var daysConverted = string.Join("','", days);
but I am getting:
"1','2','3','4" // missing quotes at the beginning and at the end.
I can concatenate a quote at both sides but I was wondering if there is any syntax to do it in one shot.
You should wrap the strings into ' before joining them:
var result = String.Join(",", days.Select(s => "'" + s + "'"));
You have to add it at the end and beginning also because Join will only combine two strings. Having said this when combining "1" and "2" with a speaterator of ',' you get "1','2" where the seperator is just added between the two elements.
As of MSDN:
Concatenates all the elements of a string array, using the specified
separator between each element.
In the end the following solution seems to be best in terms of memory and speed because you have least number of string-concatenations (two for start and end and one for every element --> 2 + n).
var daysConverted = "'" + string.Join("','", days) + "'";
Well, speaking about minimal string concatenations, here is a solution utilizing LINQ Aggregate and StringBuilder. It's not so concise, but performs...zero concatenations.
var daysConverted = days.Aggregate(new StringBuilder(), (sb, s) =>
(sb.Length > 0 ? sb.Append(",") : sb).Append("'").Append(s).Append("'"))
.ToString();
I can concatenate a quote at both sides but I was wondering if there is any syntax to do it in one shot.
Not in an optimized way. string.Join internally uses a StringBuilder to compose the string. Cheating around string.Join would make your code less clear (for example by using tricky LINQ statements) AND slower.
In the end, the classical way that #HimBromBeere suggests is the best one.

Using string.ToUpper on substring

Have an assignment to allow a user to input a word in C# and then display that word with the first and third characters changed to uppercase. Code follows:
namespace Capitalizer
{
class Program
{
static void Main(string[] args)
{
string text = Console.ReadLine();
char[] delimiterChars = { ' ' };
string[] words = text.Split(delimiterChars);
string Upper = text.ToUpper();
Console.WriteLine(Upper);
Console.ReadKey();
}
}
}
This of course generates the entire word in uppercase, which is not what I want. I can't seem to make text.ToUpper(0,2) work, and even then that'd capitalize the first three letters. Only solution I can think of now that would make the word appear on one line (and I don't know if it works) is to move the capitalized letters and lowercase letters into a character array and try to get that to print all values in a modified order.
The simplest way I can think of to address your exact question as described — to convert to upper case the first and third characters of the input — would be something like the following:
StringBuilder sb = new StringBuilder(text);
sb[0] = char.ToUpper(sb[0]);
sb[2] = char.ToUpper(sb[2]);
text = sb.ToString();
The StringBuilder class is essentially a mutable string object, so when doing these kinds of operations is the most fluid way to approach the problem, as it provides the most straightforward conversions to and from, as well as the full range of string operations. Changing individual characters is easy in many data structures, but insertions, deletions, appending, formatting, etc. all also come with StringBuilder, so it's a good habit to use that versus other approaches.
But frankly, it's hard to see how that's a useful operation. I can't help but wonder if you have stated the requirements incorrectly and there's something more to this question than is seen here.
You could use LINQ:
var upperCaseIndices = new[] { 0, 2 };
var message = "hello";
var newMessage = new string(message.Select((c, i) =>
upperCaseIndices.Contains(i) ? Char.ToUpper(c) : c).ToArray());
Here is how it works. message.Select (inline LINQ query) selects characters from message one by one and passes into selector function:
upperCaseIndices.Contains(i) ? Char.ToUpper(c) : c
written as C# ?: shorthand syntax for if. It reads as "If index is present in the array, then select upper case character. Otherwise select character as is."
(c, i) => condition
is a lambda expression. See also:
Understand Lambda Expressions in 3 minutes
The rest is very simple - represent result as array of characters (.ToArray()), and create a new string based off that (new string(...)).
Only solution I can think of now that would make the word appear on one line (and I don't know if it works) is to move the capitalized letters and lowercase letters into a character array and try to get that to print all values in a modified order.
That seems a lot more complicated than necessary. Once you have a character array, you can simply change the elements of that character array. In a separate function, it would look something like
string MakeFirstAndThirdCharacterUppercase(string word) {
var chars = word.ToCharArray();
chars[0] = chars[0].ToUpper();
chars[2] = chars[2].ToUpper();
return new string(chars);
}
My simple solution:
string text = Console.ReadLine();
char[] delimiterChars = { ' ' };
string[] words = text.Split(delimiterChars);
foreach (string s in words)
{
char[] chars = s.ToCharArray();
chars[0] = char.ToUpper(chars[0]);
if (chars.Length > 2)
{
chars[2] = char.ToUpper(chars[2]);
}
Console.Write(new string(chars));
Console.Write(' ');
}
Console.ReadKey();

How can I compare a string to a "filter" list in linq?

I'm trying to filter a collection of strings by a "filter" list... a list of bad words. The string contains a word from the list I dont want it.
I've gotten so far, the bad Word here is "frakk":
string[] filter = { "bad", "words", "frakk" };
string[] foo =
{
"this is a lol string that is allowed",
"this is another lol frakk string that is not allowed!"
};
var items = from item in foo
where (item.IndexOf( (from f in filter select f).ToString() ) == 0)
select item;
But this aint working, why?
You can use Any + Contains:
var items = foo.Where(s => !filter.Any(w => s.Contains(w)));
if you want to compare case-insensitively:
var items = foo.Where(s => !filter.Any(w => s.IndexOf(w, StringComparison.OrdinalIgnoreCase) >= 0));
Update: If you want to exlude sentences where at least one word is in the filter-list you can use String.Split() and Enumerable.Intersect:
var items = foo.Where(sentence => !sentence.Split().Intersect(filter).Any());
Enumerable.Intersect is very efficient since it uses a Set under the hood. it's more efficient to put the long sequence first. Due to Linq's deferred execution is stops on the first matching word.
( note that the "empty" Split includes other white-space characters like tab or newline )
The first problem you need to solve is breaking up the sentence into a series of words. The simplest way to do this is based on spaces
string[] words = sentence.Split(new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
From there you can use a simple LINQ expression to find the profanities
var badWords = words.Where(x => filter.Contains(x));
However this is a bit of a primitive solution. It won't handle a number of complex cases that you likely need to think about
There are many characters which qualify as a space. My solution only uses ' '
The split doesn't handle punctuations. So dog! won't be viewed as dog. Probably much better to break up words on legal characters
The reason your initial attempt didn't work is that this line:
(from f in filter select f).ToString()
evaluates to a string of the Array Iterator type name that's implied by the linq expression portion. So you're actually comparing the characters of the following string:
System.Linq.Enumerable+WhereSelectArrayIterator``2[System.String,System.String]
rather than the words of the filter when examining your phrases.

String is not splitting correctly

I am trying to split a string into a string[] made of the words the string originally held using the fallowing code.
private string[] ConvertWordsFromFile(String NewFileText)
{
char[] delimiterChars = { ' ', ',', '.', ':', '/', '|', '<' , '>','/','#','#','$','%','^','&','*','"','(',')',';'};
string[] words = NewFileText.Split(delimiterChars);
return words;
}
I am then using this to add the words to a dictionary that keeps up with word keys and their frequency value. All other duplicated words are not added as keys and only the value is affected. However the last word is counted as a different word and is therefore made into a new key. How can i fix this?
This is the code I have for adding words to the dictionary :
public void AddWord(String newWord)
{
newWord = newWord.ToLower();
try
{
MyWords.Add(newWord, 1);
}
catch (ArgumentException)
{
MyWords[newWord]++;
}
}
To clarify the problem i am having is that even if the word at the end of a string is a duplicate it is still treated like a new word and therefore a new string.
Random guess - space at the end makes empty word that you don't expect. If yes - use correct option for Split:
var words = newFileText.Split(delimiterChars,
StringSplitOptions.RemoveEmptyEntries);
Split is not the best choice to do what you want to do because you end having this kind of problems and you also have to specify all the delimiters, etc.
A much better option is using a regular expressions instead of your ConvertWordsFromFile method as follow:
Regex.Split(theTextToBeSplitted, #"\W+")
This line will return an array containing all the 'words'. Once you have that, the next step should be create your dictionary so, if you can use linq in your code, the easiest and cleaner way to do what you want is this one:
var theTextToBeSplitted = "#Hi, this is a 'little' test: <I hope it is useful>";
var myDictionary = Regex.Split(theTextToBeSplitted, #"\W+")
.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
That´s all that you need.
Good luck!

Categories

Resources