index out of range exception array - c#

I don't understand why I am getting an out of range error. Is my code set up improperly to have the array increase in size with each word entered? Note: I have some classes not shown here. Please tell me what I have to do in order to make the array increase by one every time a new word is entered.
class Program
{
static String[] Parse(String commandLine)
{
string[] stringSeparators = new string[] { "" };
String[] localList = new String[commandLine.Count((char f) => f == ' ') + 1];
localList = commandLine.Split(stringSeparators, StringSplitOptions.None);
return localList;
}
static void Main(string[] args)
{
Verb cVerb = new Verb(); //constructors begin here
Noun cNoun = new Noun();
Item itemName = new Item();
Player myPlayer = new Player();
String commandLine;
Room northRoom = new Room();
Room southRoom = new Room();
northRoom.setRoomDesccription("You stand in the center of the northern room. It smells musty");
southRoom.setRoomDesccription("You stand in the center of the southern room. It is made of crumbling stone");
myPlayer.setRoom(northRoom);
Console.WriteLine("Welcome young hero, to the world of Argandia");
while (cVerb.getName() != "Exit") // continue playing as long as verb entered =/ "exit"
{
//Room Description
myPlayer.getRoom().printDesc();
//Player Input
Console.WriteLine("You can now type a verb then a noun");
commandLine = Console.ReadLine();
int numWords = commandLine.Count((char f) => f == ' ') + 1;
String[] verbNounList = new String[numWords];
verbNounList = Parse(commandLine);
//process input
if (numWords > 0)
{
cVerb.setName(verbNounList[0]);
if (cVerb.getName() == "Exit")
{
Console.WriteLine("Thanks for playing\nSee you next time\nPress any key to exit...");
Console.ReadKey();
Environment.Exit(0);
}
if (numWords > 1)
{
cNoun.setName(verbNounList[1]);
}
if (numWords == 2)
{
}
else
{
Console.WriteLine("We are only able to support 2 words at this time, sorry\nPress any key to continue...");
}
}
}
}
}

Perhaps you should use a collection like List<string>. A dynamic alternative to an array:
public static IEnumerable<string> Parse(string commandLine)
{
foreach (var word in commandLine.Split(' '))
yield return word;
}
static void Main(string[] args)
{
string testCommandLine = "Hello World";
var passedArgs = Parse(testCommandLine);
foreach (var word in passedArgs)
{
//do some work
Console.WriteLine(word);
}
Console.Read();
}

Related

Searching for words in a string and comparing them

I can't come up with a word search code that would still output the word when the position of the word changes
class Program
{
static void Main(string[] arg)
{
Console.OutputEncoding = System.Text.Encoding.Unicode;
Console.InputEncoding = System.Text.Encoding.Unicode;
var srd = new MultiSet<Garders>()
{
new Garders("ірис, троянда, айстра, півонія, жоржин"),
new Garders("ірис, троянда, айстра, півонія, жоржин, хризантема, гладіолус"),
new Garders("ірис, троянда, айстра, півонія, гладіолус")
};
MultiSet<Garders>.Enumerator e = srd.GetEnumerator();
string[] temp = new string[3];
for (int i = 0; i < temp.Length; i++)
{
e.MoveNext();
temp[i] = e.Current.flower;
}
e.Reset();
while (e.MoveNext())
{
string[] srt = e.Current.flower.Split();
foreach (var item in srt)
{
if (temp[0].Contains(item) == temp[1].Contains(item)
&& temp[1].Contains(item) == temp[2].Contains(item))
Console.WriteLine(item);
}
Console.WriteLine();
}
}
}
}
My code only outputs the same words if they are in the same positions
You have written very complex logic, it should be very easy if you read the problem statement carefully.
Based on the discussion in a comment, you want to compare two collections whether they have the same items in the same order.
You could use List.
and compare like this.
List<string> ls1 = new List<string>() { "1", "2"};
List<string> ls2 = new List<string>() { "1", "2" };
bool isEqual = ls1.SequenceEqual(ls2);

Creating lists with loops by an user in C#

So I want to make a list of names. I want this list to go on until user inputs 0 to quit, after user types 0 I want all names to be displayed. You probably see what I'm trying to do from the code below...that "typedName" is there just so you see what I'm trying to do.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string>();
Console.WriteLine("Type in 0 to end.");
bool over = false;
while (over != true)
{
names.Add(Console.ReadLine());
if(typedName == "0")
{
over = true;
}
}
Console.WriteLine("Entered names : ");
names.ForEach(Console.WriteLine);
Console.ReadLine();
}
}
}
First you need the typedName to be captured and then check if it is equal to 0.
if it is not add it to the list
List<string> names = new List<string>();
Console.WriteLine("Type in 0 to end.");
while (true)
{
var typedName = Console.ReadLine();
if (typedName.Equals("0"))
{
break;
}
names.Add(typedName);
}
Console.WriteLine("Entered names : ");
foreach(var name in names)
{
Console.WriteLine(name);
}
Console.ReadLine();
if(typedName == "0")
Well, what is typedName? Or what should it be? I suspect it should be the input entered by the user, something like this:
var typedName = Console.ReadLine();
You can then add it to the list by using that variable:
names.Add(typedName);
And compare it with "0" as you already do, etc.
your code is not complete that is why is not working...
you are missing the most important part:
populate the list if and only if typedName != "0"
while (!over)
{
var typedName =Console.ReadLine();
if(typedName == "0")
{
over = true;
}else
{
Console.WriteLine("Enter a name... ");
names.Add(Console.ReadLine());
}
...
}

Produce List with intent items from row text

I have some row text. I want from this text to create Events and intent activities, put them on lists and then import them on a db. Let me be more specific. Let’s assume that I have the following sentence:
“On Party1 we will take some drinks, eat very good food and play ps3 games. On Party2 we will do karaoke and dance with hip hop songs.”
My desire output want to be:
Event 1: Party1
Activitie1: take some drinks
Activitie2: eat very good food
Activitie3: play ps3 games
Event2: Party2
Activitie1: do karaoke
Activitie2: dance with hip hop songs
What I have done until now, is allowing special characters “#,*” . So when I have * I produce an event and when I have # I produce an activity. As a result I can produce events and activities but I can’t match them. I need to find a way to match(intent) the produced elements. My code:
string astring = Convert.ToString(lblrowtext.Text);
if (astring.IndexOf("#") >= 0 || astring.IndexOf("*") >= 0)
{
string[] Eventsarray;
string[] Activitiessarray;
List<string> listofEvents = new List<string>();
List<string> listofActivities = new List<string>();
Activitiessarray = Regex.Matches(astring, #"#([^\*#]*)").Cast<Match>()
.Select(m => m.Groups[1].Value).ToArray();
Eventsarray = Regex.Matches(astring, #"\*([^\*#]*)").Cast<Match>()
.Select(m => m.Groups[1].Value).ToArray();
if (Activitiessarray != null)
{
if (Activitiessarray.Count() > 0)
{
listofActivities = new List<string>(Activitiessarray);
ViewState["listofActivities"] = listofActivities;
Repeater1.DataSource = listofActivities;
Repeater1.DataBind();
}
if (Eventsarray != null)
{
if (Eventsarray.Count() > 0)
{
listofEvents = new List<string>(Eventsarray);
ViewState["listofEvents"] = listofEvents;
Repeater2.DataSource = listofEvents;
Repeater2.DataBind();
}
}
}
}
You can achieve this like below:
private static void Main(string[] args)
{
var updationIndex = 0;
const string inputString = "On *Party1 #we will take some drinks, #eat very good food and #play ps3 games.# ";
Func<string, char, char, string> getMyString = (givenString, skipTill, takeTill) =>
{
var opString =
new string(
givenString.ToCharArray()
.SkipWhile(x => x != skipTill)
.Skip(1)
.TakeWhile(x => x != takeTill)
.ToArray());
updationIndex = inputString.IndexOf(givenString, StringComparison.CurrentCultureIgnoreCase)
+ opString.Length;
return opString;
};
var eventName = getMyString(inputString, '*', '#');
Console.WriteLine("Event" + eventName);
Console.WriteLine("Activities: ");
while (updationIndex < inputString.Length)
{
var activity = getMyString(inputString.Remove(0, updationIndex), '#', '#');
Console.WriteLine(activity);
if (string.IsNullOrWhiteSpace(activity))
{
break;
}
}
}
Create an Event class to which you add Activities. Each time you encounter a *, create a new Event instance.
Psuedo-C#:
class Event
{
string Description;
List<Activity> Activities;
}
class Activity
{
string Description;
}
List<Event> ParseEventLines(IEnumerable<string> allLines)
{
var result = new List<Event>();
Event currentEvent = null;
foreach (var line in allLines)
{
if (line.StartsWith("*"))
{
currentEvent = new Event { Description = line };
result.Add(currentEvent);
}
else if (line.StartsWith("#"))
{
currentEvent.Activities.Add(new Activity { Description = line });
}
}
return result;
}

Dictionary with multiple keys isn't working as expected

I'm making a console program where I've got multiple values mapped to dictionary keyLookup. I'm using if commands that use the key to output some console.writeline = ("stuff"); but it only works if I have the value and the key the same (in the dictionary). I don't know why this is. I've been mucking about with list and foreach and some variables trying to figure out what I've done wrong but even though it continues to work how it works now it still doesn't work how I want.
Also if I have a word in my console.readline(); that isn't in my dictionary the whole thing crashes. Which I don't want, and I'm not sure of why its doing that either as at some point it didn't. Also my mathFunction dictionary works just how I want my keyLookup dictionary to work. Though I think the difference is in how I'm using a list to cross reference through keyLookup.
class MainClass
{
public static string Line;
static string foundKey;
public static void Main (string[] args)
{
while (true)
{
if (Line == null)
{Console.WriteLine ("Enter Input"); }
WordChecker ();
}
}
public static void WordChecker()
{
string inputString = Console.ReadLine ();
inputString = inputString.ToLower();
string[] stripChars = { ";", ",", ".", "-", "_", "^", "(", ")", "[", "]",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "\n", "\t", "\r" };
foreach (string character in stripChars)
{
inputString = inputString.Replace(character, "");
}
// Split on spaces into a List of strings
List<string> wordList = inputString.Split(' ').ToList();
// Define and remove stopwords
string[] stopwords = new string[] { "and", "the", "she", "for", "this", "you", "but" };
foreach (string word in stopwords)
{
// While there's still an instance of a stopword in the wordList, remove it.
// If we don't use a while loop on this each call to Remove simply removes a single
// instance of the stopword from our wordList, and we can't call Replace on the
// entire string (as opposed to the individual words in the string) as it's
// too indiscriminate (i.e. removing 'and' will turn words like 'bandage' into 'bdage'!)
while ( wordList.Contains(word) )
{
wordList.Remove(word);
}
}
// Create a new Dictionary object
Dictionary<string, int> dictionary = new Dictionary<string, int>();
// Loop over all over the words in our wordList...
foreach (string word in wordList)
{
// If the length of the word is at least three letters...
if (word.Length >= 3)
{
// ...check if the dictionary already has the word.
if ( dictionary.ContainsKey(word) )
{
// If we already have the word in the dictionary, increment the count of how many times it appears
dictionary[word]++;
}
else
{
// Otherwise, if it's a new word then add it to the dictionary with an initial count of 1
dictionary[word] = 1;
}
}
List<string> dicList = new List<string>();
dicList = dictionary.Keys.ToList ();
Dictionary<string, string> keyLookup = new Dictionary<string, string>();
keyLookup["hey"] = "greeting";
keyLookup["hi"] = "greeting";
keyLookup["greeting"] = "greeting";
keyLookup["math"] = "math";
keyLookup["calculate"] = "math";
keyLookup["equation"] = "math";
foundKey = keyLookup[word];
List<string> keyList = new List<string>();
foreach (string keyWord in dicList)
{
if(keyWord == foundKey)
{keyList.Add (keyWord); }
}
foreach (string mKey in keyList)
{
if(mKey == "greeting")
{Greetings ();}
if (mKey == "math")
{Math ();}
}
}
}
public static void Math()
{
Console.WriteLine ("What do you want me to math?");
Console.WriteLine ("input a number");
string input = Console.ReadLine ();
decimal a = Convert.ToDecimal (input);
Console.WriteLine("Tell me math function");
string mFunction = Console.ReadLine();
Console.WriteLine ("tell me another number");
string inputB = Console.ReadLine();
decimal b = Convert.ToDecimal (inputB);
Dictionary<string, string> mathFunction = new Dictionary<string, string>();
mathFunction["multiply"] = "multiply";
mathFunction["times"] = "multiply";
mathFunction["x"] = "multiply";
mathFunction["*"] = "multiply";
mathFunction["divide"] = "divide";
mathFunction["/"] = "divide";
mathFunction["subtract"] = "subtract";
mathFunction["minus"] = "subtract";
mathFunction["-"] = "subtract";
mathFunction["add"] = "add";
mathFunction["+"] = "add";
mathFunction["plus"] = "add";
string foundKey = mathFunction[mFunction];
if (foundKey == "add")
{
Console.WriteLine (a + b);
}
else if (foundKey == "subtract")
{
Console.WriteLine (a - b);
}
else if (foundKey == "multiply")
{
Console.WriteLine (a * b);
}
else if (foundKey == "divide")
{
Console.WriteLine (a / b);
}
else
{
Console.WriteLine ("not a math");
}
}
public static void Greetings()
{
Console.WriteLine("You said hello");
}
}'
You should iterate through the dictionary differently (Dont use ToList-Function).
Try this instead:
foreach (KeyValuePair kvp (Of String, String) In testDictionary)
{
Debug.WriteLine("Key:" + kvp.Key + " Value:" + kvp.Value);
}
And your application is crashing if the word doesn't match, because of this code (You're not creating a new entry that way):
// Otherwise, if it's a new word then add it to the dictionary with an initial count of 1
dictionary[word] = 1;
EDIT: I was wrong about that dictionary[word] = 1 would not create a new element. It's perfectly fine like this.
foundKey = keyLookup[word];
If word doesn't exist in keyLookup then it will crash.
string foundKey = mathFunction[mFunction];
if mFunction doesn't exist in mathFunction then it will crash.
If you're trying to make this a "conversational" program, then the word look-up is the most important part. You don't use predicates or LINQ, both can make string functions extremely easy. Currently you use a Dictionary. Why not use Lists for each keyword?
List<string> GreetingKeywords;
GreetingKeywords.Add("hello"); // ...
List<string> MathKeywords;
MathKeywords.Add("math"); // ...
foreach (var word in dicList)
{
if (GreetingKeywords.Contains(word))
{ Greetings(); }
if (MathKeywords.Contains(word))
{ Maths(); }
}
I'd suggest you read up on predicate and List/Dictionary functions such as Find, IndexOf, etc. etc. That knowledge is invaluable to C#.

display format for results in console

I am trying to display my results as follows:
-.-|- [tab] kt
-.|-- [tab] nm
-.|-|- [tab] ntt
But this is my current output
-.-|-| kt
-.|--| nm
-.|-|-| [tab]ntt
There is a | at the end of every Morse code which I would like to remove since it is at the end.
Also because the user can input Morse code with space between dots and dashes - i noticed that it affects the alignment of the characters and not all of them get tabbed properly. The word tab isn't supposed to show i just wrote it in because I didn't know how to place a real tab.
private static readonly IDictionary<char, string> morseCode_alpha = new Dictionary<char, string>
{
{'a', ".-"},{'b',"-..."}, {'c',"-.-."}, {'d',"-.."}, {'e',"."},
{'f',"..-."}, {'g',"--."}, {'h',"...."},{'i',".."}, {'j',".---"},
{'k',"-.-"}, {'l',".-.."}, {'m',"--"}, {'n',"-."}, {'o',"---"},
{'p',".--."}, {'q',"--.-"}, {'r',".-."}, {'s',"..."}, {'t',"-"},
{'u',"..-"}, {'v',"...-"}, {'w',".--"}, {'x',"-..-"}, {'y',"-.--"}, {'z',"--.."}
};
private static string ConvertMorseToText(string symbolCode)
{
var builder = new StringBuilder(4 * symbolCode.Length);
foreach (char c in symbolCode)
builder.Append(morseCode_alpha[c]);
return builder.ToString();
}
private static string ConvertTextToMorse(char ch)
{
if (morseCode_alpha.Keys.Contains(ch))
return morseCode_alpha[ch];
else
return string.Empty;
}
private static string ConvertStringToMorse(string letters)
{
StringBuilder sb = new StringBuilder();
foreach (char ch in letters)
{
if (sb.Length != 0 && sb[sb.Length - 1] != ' ')
sb.Append("|");
sb.Append(ConvertTextToMorse(ch));
}
return sb.ToString();
}
private static IEnumerable<string> Permutations( string symbolCode)
{
int n = symbolCode.Length;
if (n == 0 || symbolCode.Length == 0)
yield return " ";
else
foreach (var entry in morseCode_alpha)
if (symbolCode.StartsWith(entry.Value))
foreach (string next in Permutations(symbolCode.Substring(entry.Value.Length)))
yield return entry.Key + next;
}
private static void Write( string rest)
{
string result = ConvertStringToMorse(rest);
Console.Write(result+"\t");
Console.WriteLine(rest);
}
static void Main(string[] args)
{
string morseInput;
string entered = "";
do
{
Console.WriteLine("Enter Morse Code: \n");
morseInput = Console.ReadLine().Replace(" ","");
bool isValid = Regex.IsMatch(morseInput, #"^[-.]+$");
if (isValid)
{
Console.WriteLine("\nAll permutations:\n");
string morse = ConvertMorseToText(entered);
string permutations = morseInput.Substring(morse.Length);
Write(permutations);
var nexts = new List<string>(Permutations(permutations));
foreach (string next in nexts)
Write(next);
}
else
{
Console.WriteLine("\nFormat of morse must be only dots and dashes.");
Console.WriteLine("Parameter name: "+morseInput+"\n");
}
}
while (morseInput.Length != 0);
}
And, to answer the other part of the question...
Tabstops are fixed for console writing, so it would be better to use something like String.PadRight
so, your code could be:
private static void Write(string rest)
{
string result = ConvertStringToMorse(rest);
Console.Write(result.PadRight(20));
Console.WriteLine(rest);
}
Draft version of the method:
private static string ConvertStringToMorse(string letters)
{
var result = string.Join("|",
letters
.Select(ConvertTextToMorse)
.Where(morse => !string.IsNullOrEmpty(morse)));
return result;
}
Update:
Please note that the entered variable is used only once: when defined - empty string is assigned. Then the ConvertMorseToText(entered) method is called: it always returns empty string for the empty string argument. After this assignment string permutations = morseInput.Substring(morse.Length); the permutations variable will store exactly the same value as morse variable (because morse.Length is always 0).
So, it seems that the entered variable and the ConvertMorseToText() method are useless (both can be safely removed):
static void Main(string[] args)
{
do
{
Console.WriteLine("Enter Morse Code: ");
string morseInput = Console.ReadLine();
if (string.IsNullOrWhiteSpace(morseInput))
{
// Empty or consists only of white-space characters
break;
}
morseInput = morseInput.Replace(" ", "");
bool isValid = Regex.IsMatch(morseInput, #"^[-.]+$");
if (isValid)
{
Console.WriteLine("All permutations:");
Console.WriteLine();
var nexts = Permutations(morseInput).ToList();
foreach (string next in nexts)
Write(next);
}
else
{
Console.WriteLine();
Console.WriteLine("Format of morse must be only dots and dashes.");
Console.WriteLine("Parameter name: {0}", morseInput);
}
}
while (true);
}
Update 2:
Consider using TryGetValue() method of Dictionary<TKey, TValue> instead of Keys.Contains and [] (indexer) i.e. do not perform look-up twice:
private static string ConvertTextToMorse(char ch)
{
string result;
return morseCode_alpha.TryGetValue(ch, out result) ? result : string.Empty;
}
Instead this code:
Console.Write(result+"\t");
Console.WriteLine(rest);
Use
Console.WriteLine("{0,-10}{1,-10}", result, rest);
Then you will see two columns (each max 10 charachters) with left alignment. Or remove "-" sign if you want right alignment.

Categories