I'm learning and currently trying to write a simple multiple choice quiz. I am not allowed to write it simply with if else statements.
I'm trying to make it so that it asks the question the user inputs the answer (that's all fine) but a separate class works out if it's right or not.
Where my code has the array with a blank index I'm wondering how after the first iteration it would check the next index when that method was called upon again in the next question. I tried to use a for each but then get an error regarding not every path has an outcome.
private static readonly string[] answerArray = new string[5] { "C", "A", "B", "A", "C" };
public static bool AnswerCalc(string ain)
{
if (ain == answerArray[])
{
Console.WriteLine("Correct");
return true;
}
else
{
Console.WriteLine("Sorry that's wrong");
return false;
}
}
I had it as a bool as that's how I was keeping score.
If you want to check if an array contains an item simply:
var aInArr = arr.Contains("A");
This is a LINQ expression built into .net.
One way to implement this as a non-extension method targeting array is like so:
public bool Contains(string[] arr, string inputStr)
{
for(int i = 0; i < arr.Length; i++)
{
if (item == inputStr[i])
return true;
}
return false;
}
Once it runs out of items in the array it will break out of the for loop curly brackets and return false.
Note: for brevity I reduced the result but the .net way to do this is to use an IEnumerable on a generic input instead of an array and use foreach instead of for.
public static Contains<T>(this IEnumerable<T> input, T compared)
{
foreach (var item in input)
{
if (item == compared)
return true;
}
return false;
}
If you store an integer in the class containing this method, you can increment it at the end of the function call (make sure you reset it to 0 when it reaches the length of the array). Use this integer between the square braces like so: if (ain == answerArray[intValue])
If you need more help then let me know and I'll be happy to update this with more information.
Related
I want to create a function which will return the matrix, but I have a problem with limit the time of put the data to console.
public static List<List<int>> CreateMatrix()
{
List<List<int>> matrix = new List<List<int>>();
List<int> row = new List<int>();
do
{
row = Array.ConvertAll<string, int>(Console.ReadLine().Split(" ", StringSplitOptions.RemoveEmptyEntries), int.Parse).OfType<int>().ToList();
matrix.Add(row);
} while (matrix[0].Count == row.Count);
return matrix;
}
I want to create a loop which will accept the row of numbers, but when nothing is put inside the row at least five seconds for example, then the loop should be break
Using one of the examples from This Post, I've created a simple example for you which will add items entered on the console to a List collection. Hopefully it will be a good starting point for you to be able to do what you need.
public static void Main()
{
int waitTimeInSeconds = 10;
List<string> matrix = new();
do
{
var task = Task.Factory.StartNew(Console.ReadLine);
var result = Task.WaitAny(new Task[] { task }, TimeSpan.FromSeconds(waitTimeInSeconds)) == 0
? task.Result : string.Empty;
if (!String.IsNullOrEmpty(result))
{
matrix.Add(result);
}
else
{
break;
}
} while (true);
if (matrix is not null)
{
Console.WriteLine($"# Items Added to Array: {matrix.Count}\n");
foreach (var m in matrix)
{
Console.Write(m);
}
}
}
Reviewing your code however, I'm not sure what you're trying to achieve in your while loop.
Your row variable looks to take the input of the console.ReadLine() and convert it to an integer, but you haven't considered if the input isn't of type integer, as if not, it will cause a System.FormatException.
Secondly, it seems like you're returning a list of list simply because that's the type which Array.ConvertAll().ToList() returns and you want a to return multiple values. I suspect you just want to return the list of values that you've read from the console instead.
Just some food for thought
i am new to c# and i have been trying to make a string[] that changes its contents depending on the int value of a different variable. i've tried switches and ifs but when i try to call the variable afterwards the program states that the variable does not exist in current context.
Im sorry for the bad description but here's a sample code regarding what i mean.
int flag = 0; //Value Changes
if (flag == 1)
{
string[] mainoptions = {"Return"};
}
else if (flag == 0)
{
string[] mainoptions = { "Grab Shovel", "Return" };
}
WriteLine(mainoptions); //The name 'mainoptions' does not exist in current context
For the vast majority of cases, any variables (eg. string name; or string name = "Roger";) that are created inside curly braces { } can only be accessed using their identifier from inside those braces.
Take this example:
int a = 0;
if (condition)
{
int b = 1;
}
Console.WriteLine(a); // can see the 'a' variable -> works fine
Console.WriteLine(b); // can NOT see the 'b' variable -> compilation error
The variable a can be accessed from the "main scope" (for lack of a better term), and also inside the if statement because the if statement defines a sub-scope, per se.
Variable b however, can only be accessed from within the if statement it was declared in, and also any sub-scopes that might occur inside there. It can NOT be accessed outside that if statement, because as soon as the program exits the block (reaches the closing brace }) you can imagine that variable b's reference is deleted.
With that, you can edit your program to define the variable mainoptions outside the if statements, and that will solve your issue
Let's get to the bottom of this:
You didn't declare a variable/property behind the if-construction. Anything that is declared in a logical construct does not exist for the compiler behind it. You've probably seen this before in the "access level" here: link.
If you want to print the variable array in a logical construct, you should do it like this:
if (a == someValue1)
{
string[] b = { "Return" };
System.Console.WriteLine(b);
}
else if (a == someValue2)
{
string[] b = { "Grab Shovel", "Return" };
System.Console.WriteLine(b);
}
But there's a mistake here: you can't assign something to an array just in curly braces { }, you have to declare it correctly:
string[] arr; // array is not initialized
arr = new string[] { "text", "text", "text" } // the array is now initialized
But that's not really convenient and the code gets bloated, so you should define this variable before the logical construct:
string[] b = new string[] { };
if (a == someValue1)
{
b = new string[] { "Return" };
}
else if (a == someValue2)
{
b = new string[] { "Grab Shovel", "Return" };
}
System.Console.WriteLine(b);
That's more convincing, isn't it?
Now let's think what we can improve here...
The flag variable is of type int, but it takes 0 and 1, which is more like a bool, so let's make it a bool.
Flag can still be made a property to make it easier to use, let's do that!
Let's replace if-else with a switch-case, so there are no unnecessary checks.
And we get the following:
class Program
{
public static bool Flag { get; set; }
public static void Main(string[] args)
{
string[] mainoptions = new string[] { };
Flag = false;
switch (Flag)
{
case true:
mainoptions = new string[] { "Return" };
break;
case false:
mainoptions = new string[] { "Grab Shovel", "Return" };
break;
}
foreach (var option in mainoptions)
System.Console.WriteLine(option);
}
}
Oh, did you also notice that I printed the result differently, and there is a new foreach construct?
foreach (var option in mainoptions)
System.Console.WriteLine(option);
Well, you can't just print the array because you just get its type, not its content. To print the whole array, we have to go through it from index 0 to the end, printing out every value.
You can address the array using the index:
var arr = new int[] { 1, 2, 3, 4 };
Console.WriteLine(arr[0]); // => print 1
Let's make it even cooler, shall we? We use a ternary operator, it's an analogue of if-else when we only have 2 execution paths:
class Program
{
public static bool Flag { get; set; }
public static void Main(string[] args)
{
string[] mainoptions = new string[] { };
Flag = false;
mainoptions = Flag ? new string[] { "Return" } : new string[] { "Grab Shovel", "Return" };
foreach (var option in mainoptions)
System.Console.WriteLine(option);
}
}
I hope this will be useful! Have a nice day!
so what i have learned you can use a If to check a var! you can also use a switch statement witch are super useful!
int Flag = 0;
String mainoptions;
Static void Main()
{
switch(Flag)
{
case 1:
// case means the if this is the var then run this block of code.
// the 1 is the int number so if we put 100 in the place of the 1 then the switch statment would check if the var (Flag) is 100. and if it the code just moves on. you can add whatever you want in the case 1. so if you wanted your string to be "Example" if the int Flag was 1 then you would put:
mainoptions = "mainoption's";
// you can as as many cases as you want as well.
Brake;
}
}
also your mainoptions does not exist bc its a temp var. your int Flag works bc its outside of the method AKA in the class. so in other words you cant use temp vars outside of the method it is put into or initialised in.
Outside of implementing collections yourself, arrays are generally a poor choice for storing a collection of objects. Consider instead using List<string>:
int flag = 0; //Value Changes
var mainOptions = new List<string>{
"Return"
};
if (flag == 0)
{
mainoptions.Insert(0,"Grab Shovel");
}
WriteLine(mainoptions);
(If WriteLine is your own method, you may have to change its signature to accept List<string> instead of string[] and there may be further cascading changes)
Part of what makes arrays awkward to work with is that they have a fixed number of elements. But you're already working in a scenario where you want to easily change the number of elements. So use a type that makes that easy to do.
I have a number of elements in an array, I would like to check if a string is equal to any of these elements in the array. The number of elements in the array can change in number.
I have counted the number of elements in the array hoping to get somewhat of an advantage but haven't been able to come up with a solution.
int ArrayCount = FinalEncryptText.Count();
foreach (string i in FinalEncryptText)
{
}
Using the foreach implementation you have provided, you could include an if condition with String.Equals(string) - as Sean pointed out earlier.
But it's worth noting that String.Equals(string) without additional arguments is equivalent to using the == operator. So it's better if you specify the StringComparison type so that you express what kind of comparison you wish to perform.
For example, you could do something like this:
foreach (string element in myStringArray)
{
if(element.Equals("foo", StringComparison.CurrentCultureIgnoreCase))
...
}
You could even include the evaluation as a predicate in a LINQ query. For example, let's say you wanted to see which strings passed the evaluation:
var matches = myStringArray
.Where(element => element.Equals("foo", StringComparison.CurrentCultureIgnoreCase));
You can read more about comparing strings here.
I'm not sure what your method looks like, but I'm assuming.. you're given a random array of strings.. and you want to find a certain element in that array. Using a foreach loop:
public string Check(string[] FinalEncryptText)
{
foreach (string i in FinalEncryptText)
{
//let's say the word you want to match in that array is "whatever"
if (i == "whatever")
{
return "Found the match: " + i;
}
}
}
Using a regular for loop:
public string Check(string[] FinalEncryptText)
{
for (int i = 0; i < FinalEncryptText.Count; i++)
{
//let's say the word you want to match in that array is "whatever"
if (FinalEncryptText[i] == "whatever")
{
//Do Something
return "Found the match: " + FinalEncryptText[i];
}
}
}
Now if you already have a fixed array.. and you're passing in a string to check if that string exists in the array then it would go something like this:
public string Check(string stringToMatch)
{
for (int i = 0; i < FinalEncryptText.Count; i++)
{
//this will match whatever string you pass into the parameter
if (FinalEncryptText[i] == stringToMatch)
{
//Do Something
return "Found the match: " + FinalEncryptText[i];
}
}
}
You could use the String.Equals method in an if statement. More info on String.Method here: String.Equals Method.
if(firstString.Equals(secondString))
{
//whatever you need to do here
}
I am trying to use bubble sort to sort a list of items. I am aware that this is not the most effective method of sorting; however, I require this method to work before moving on to better things. My current code partially sorts a list, but I cannot see what I am doing wrong.
public class ListComponents
{
public int Priority;
public string Name;
public ListComponents Next;
}
public void bubblesort()
{
ListComponents Current = Head;
int temp = 0;
bool swapped = true;
while (swapped)
{
Print(); // Debug Function to print each swap
Current = Head.Next; // RESET CURRENT TO HEAD + 1 ON EACH ITERATION?
swapped = false;
for (int sort = 0; sort < (size - 1); sort++) //Size defined as # of items in list
{
if (Current != null &&
Current.Next != null &&
Current.Priority> Current.Next.Priority)
{
temp = Current.Priority;
Current.Priority= Current.Next.Priority;
Current.Next.Priority= temp;
Current = Head; // POTENTIAL ISSUE?
swapped = true;
}
}
}
}
My debug print function shows the following, showing how the values are almost in order:
List: 4 2 1 3 (Inital List Order)
List: 1 4 2 3 (First Swap)
List: 1 2 4 3 (Second Swap)
The issue seems to be with setting the 'Current' value, although I cannot see where this is not working.
My advice: start over. This is a mess.
Here's how I would tackle problems like this when I was a beginner. Start by writing the code in pseduo-code:
void BubbleSort(ListComponent head)
{
if the list is of zero length then it is already sorted, so return
if the list is of length one then it is already sorted, so return
Otherwise, the list is of length two or more. Therefore we know that
a first item exists and a second-last item exists.
Our strategy is: run down the list starting with the first item
and ending with the second-last item. If at any time the current
item and the one following it are out of order, swap their elements.
If we made no swaps then the list is sorted, return.
If we made one or more swaps then the list might not be sorted, so
run down the list again.
}
OK, now we can start translating that into code.
void BubbleSort(ListComponent head)
{
// if the list is of zero length then it is already sorted, so return
if (head == null) return;
// if the list is of length one then it is already sorted, so return
if (head.Next == null) return;
// Otherwise, the list is of length two or more. Therefore we know that
// a first item exists and a second-last item exists.
// Our strategy is: run down the list starting with the first item
// and ending with the second-last item.
for (ListComponent current = head;
current.Next != null;
current = current.Next)
{
If at any time the current item and the one following it
are out of order, swap their elements.
}
If we made no swaps then the list is sorted, return.
If we made one or more swaps then the list might not be sorted, so
run down the list again.
}
OK, I've translated some of that English into code. Can you translate the rest?
Another example with a simple class with 2 properties. This is NOT for arrays but for a simple class simulating pointers... Made just for fun !
class MyLinkedList
{
MyLinkedList nextNode;
int data;
public void OrderListBubbleAlgoritm(ref MyLinkedList head)
{
bool needRestart = true;
MyLinkedList actualNode = head; //node Im working with
int temp;
while (needRestart)
{
needRestart = false;
actualNode = head;
while (!needRestart && actualNode.nextNode != null)
{
if (actualNode.nextNode.data >= actualNode.data) //is sorted
{
actualNode = actualNode.nextNode;
}
else
{
//swap the data
temp = actualNode.data;
actualNode.data = actualNode.nextNode.data;
actualNode.nextNode.data = temp;
needRestart = true;
}
}
}
}
}
Remember to use bubble sorting just with small quantity of data.
It's performance is: O(n^2)
This question is related to my earlier question, asked here:
How do I get every combination of letters using yield return and recursion?
I have several lists of strings like so, from a possible list of several dozen:
1: { "A", "B", "C" }
2: { "1", "2", "3" }
3: { "D", "E", "F" }
These three were only picked as an example, and the user can pick from several dozen similar lists with varying number of elements. For another example, this is also a perfectly valid selection for a user:
25: { } // empty
4: { "%", "!", "$", "#" }
16: { "I", "a", "b", "Y" }
8: { ")", "z", "!", "8" }
What I want to do is get every combination of strings possible while keeping the 'order' of the lists. In other words, assuming we're looking at the first list, the first combination will be A1D, then A1E, then A1F, then B1D, then B1E, and so on and so forth. Based on the answer provided in my previously-asked question, I've written this working recursive algorithm:
public void Tester()
{
var collection = new List { list1, list2, list3 };
var answer = GetStringCombinations(collection).ToList();
answer.ForEach(Console.WriteLine);
}
private IEnumerable<string> GetStringCombinations(List<List<string>> collection)
{
// if the collection is empty, return null to stop the recursion
if (!collection.Any())
{
yield return null;
}
// recurse down the list, selecting one letter each time
else
{
foreach (var letter in collection.First())
{
// get the collection sans the first item
var nextCollection = collection.Skip(1).ToList();
// construct the strings using yield return and recursion
foreach (var tail in GetStringCombinations(nextCollection))
{
yield return letter + tail;
}
}
}
}
However, this code depends on yield return to work properly. How would you implement this algorithm without the use of the yield return keyword, for example if I were to port the code to ColdFusion or Ruby (assuming that they don't have a similar keyword either)?
I am not tested it, but should work
private List<string> GetStringCombinations(List<List<string>> collection)
{
List<string> ls = new List<string>();
// if the collection is empty, return null to stop the recursion
if (!collection.Any())
{
return null;
}
// recurse down the list, selecting one letter each time
else
{
foreach (var letter in collection.First())
{
// get the collection sans the first item
var nextCollection = collection.Skip(1).ToList();
// construct the strings using yield return and recursion
foreach (var tail in GetStringCombinations(nextCollection))
{
ls.add(letter + tail);
}
}
}
return ls;
}
Pseudocode:
Combinations(lists[1..n], start, prefix)
1. If start = n + 1 then print(prefix)
2. else then
3. for i = 1 to lists[start].length do
4. Combinations(lists, start + 1,
prefix.append(lists[start][i])
Something like that should work. For best results, call the above with start = the lowest array index and prefix = the empty string. With some tweaking, this will work nice.