I'm now doing a project about solving a Magic cube problem. I want to create an array to remember the steps like this:
char[] Steps = new char[200];
Each time I do the 'F','B','R','L','U','D' turn method, it will add a 'F','B','R','L','U','D' character in the array.
But when I want to get the length of the steps, it always shows 200.
for example:
char[] steps = new char[5];
and now I've already added 3 steps:
steps[] = {'f','b','f','',''};
How can I get the length '3'?
Or is there any alternative method I can use that I don't need to set the length at the beginning?
you can just use List<char> but if performance is really critical in your sceanario you can just initialize the initial capacity
something like the following
List<char> list = new List<char>(200);
list.Add('c');
list.Add('b');
here count will return just what you have really added
var c = list.Count;
note in list you can apply Linq Count() or just use the Count property which does not need to compute like Linq and return the result immediately
You will get compilation error on this line
steps[] = {'f','b','f','',''};
As you cannot use empty char and you need to write steps instead of steps[].
I will suggest you to use string array instead and using LINQ get count of not empty elements in this way:
string [] steps = {"f","b","f","",""};
Console.WriteLine(steps.Where(x=>!string.IsNullOrEmpty(x)).Count());
To count non-empty items using System.Linq:
steps.Count(x => x != '\0');
Your code doesn't compile since '' isn't allowed as a char, but I'm assuming that you mean empty elements in a char array which are actually represented by '\0' or the Unicode Null. So the above condition simply counts the non null items in your array.
you could use a list of character that would make things a lot simpler like this :
List<char> steps = new List<char>();
and just add a line to the list for each steps :
char move = 'F';
steps.add(move);
finally then you can count the number of move in the list easily
int numberofmove = steps.count();
Related
I have an array :
string[] arr = new string[2]
arr[0] = "a=01"
arr[1] = "b=02"
How can I take those number out and make a new array to store them? What I am expecting is :
int [] newArr = new int[2]
Inside newArr, there are 2 elements, one is '01' and the other one is '02' which both from arr.
Another way besides Substring to get the desired result is to use String.Split on the = character. This is assuming the string will always have the format of letters and numbers, separated by a =, with no other = characters in the input string.
for (var i = 0; i < arr.Length; i++)
{
// Split the array item on the `=` character.
// This results in an array of two items ("a" and "01" for the first item)
var tmp = arr[i].Split('=');
// If there are fewer than 2 items in the array, there was not a =
// character to split on, so continue to the next item.
if (tmp.Length < 2)
{
continue;
}
// Try to parse the second item in the tmp array (which is the number
// in the provided example input) as an Int32.
int num;
if (Int32.TryParse(tmp[1], out num))
{
// If the parse is succesful, assign the int to the corresponding
// index of the new array.
newArr[i] = num;
}
}
This can be shortened in a lambda expression like the other answer like so:
var newArr = arr.Select(x => Int32.Parse(x.Split('=')[1])).ToArray();
Though doing it with Int32.Parse can result in an exception if the provided string is not an integer. This also assumes that there is a = character, with only numbers to the right of it.
Take a substring and then parse as int.
var newArr = arr.Select(x=>Int32.Parse(x.Substring(2))).ToArray();
As other answers have noted, it's quite compact to use linq. PM100 wrote:
var newArr = arr.Select(x=>Int32.Parse(x.Substring(2))).ToArray();
You asked what x was.. that linq statement there is conceptually the equivalent of something like:
List<int> nums = new List<int>();
foreach(string x in arr)
nums.Add(Int32.Parse(x.Substring(2);
var newArr = nums.ToArray();
It's not exactly the same, internally linq probably doesn't use a List, but it embodies the same concept - for each element (called x) in the string array, cut the start off it, parse the result as an int, add it to a collection, convert the collection to an array
Sometimes I think linq is overused; here probably efficiencies could be gained by directly declaring an int array the size of the string one and filling it directly, rather than adding to a List or other collection, that is later turned into an int array. Proponents of either style could easily be found; linq is compact and makes relatively trivial work of more long hand constructs such as loops within loops within loops. Though not necessarily easy to work out for those unfamiliar with how to read it it does bring a certain self documenting aspect to code because it uses English words like Any, Where, Distinct and these more quickly convey a concept than does looking at a loop code that exits early when a test returns true (Any) or builds a dictionary/hashset from all elements and returns it (Distinct)
I am just beginning with programming in c#;
I got a list of int variables that I want to sort, and find the number 1.
int Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9
do I need to do this with an array?
By using the yellow book of C# I found out how to make an array, but I can't figure out how to assign the variables to the array.
int [] Weapon_Count = new int [11] ;
for ( int i=0; i<11; i=i+1)
{
Weapon_Count [i] = ??? ;}
I hope this does make sense..
Please let me explain how to use a C#-array.
This creates an unitialized integer-array with 5 elements:
int[] a1= new int[5];
Assigning values 9,8,7,6 and 5:
(Please note that only indexes from 0 to 4 can be used. Index 5 is not valid.)
a1[0]=9;
a1[1]=8;
a1[2]=7;
a1[3]=6;
a1[4]=5;
The same can also achieved with just one line:
int[] a1= new int[] {9,8,7,6,5};
This might help you.
// Declaring the array
int[] Weapon_Count;
// Initializing the array with a size of 11
Weapon_Count = new int[11];
// Adding values to the array
for (int i = 0; i < Weapon_Count.Length; i++)
{
Weapon_Count[i] = i + 100;
}
// Printing the values in the array
for (int i = 0; i < Weapon_Count.Length; i++)
{
Console.WriteLine(Weapon_Count[i]);
}
// Same thing with a list
// Daclare and initializing the List of integers
List<int> weapon_list = new List<int>();
// Adding some values
weapon_list.Add(1);
weapon_list.Add(2);
weapon_list.Add(3);
weapon_list.Add(4);
weapon_list.Add(5);
// Printing weapin_list's values
for (int i = 0; i < weapon_list.Count; i++)
{
Console.WriteLine(weapon_list[i]);
}
// This is just for the console to wait when you are in debug mode.
Console.ReadKey();
Dont forget to include the using statment if you want to use lists (in short hand - dynamic arrays that can change in size.)
using System.Collections.Generic;
The easiest way to do this, assuming there is a finite list of variables to check, would be to throw them into a temporary array and call either Max() or Min() from the System.Linq namespace.
int maxCount = new int[] { Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9 }.Max(); // or .Min()
EDIT
If you still want to get those variables into an array, I would recommend using a System.Collections.Generic.List which has a dynamic size and helper methods such as .Add() to simplify things. Lists can also be used with Linq functions similar to the first part of my answer. See Dot Net Perls for some really good examples on different C# data types and functions.
EDIT 2
As #kblok says, you'll want to add using System.Linq; at the top of your file to gain access to the functions such as Max and Min. If you want to try using the List type, you'll need to add using System.Collections.Generic; as well. If you're in Visual Studio 2017 (maybe 2015 as well?) you can type out the data type and then hit Ctrl + . to get suggestions for namespaces that might contain that data type.
Before we start, you might edit your array to look like this:
int[] weapons = { Weapon_Count1, Weapon_Count2, Weapon_Count3, Weapon_Count4, Weapon_Count5, Weapon_Count6, Weapon_Count7, Weapon_Count8, Weapon_Count9 };
This means that you've created an array called weapons and it is holding integer values.
After you did this, lets find out which element in your array has value of number one.
To find which value has value "1" we must look at each element in array, and we might do that on few ways but I would like recommend foreach or for loop, in this case I will choose foreach loop.
foreach(var item in weapons)
{
if (item == 1)
//Do something
}
This above means, loop throught all of my elements, and in case some of them is equal to number one please do something..
P.S
(I may advice to create one variable which will hold an element which has value '1' and when you find it in a loop assing that variable to that element, and later you can do whatever you want with that variable.. and if you think there will be more elements with value of number one and you need all of them, instead of variable I mentioned above you will create list or array to hold all of your elements and also you can do later with them whatever you want to.)
Thanks and if you are interested in this kind of solution, leave me a comment so let me help you till the end to solve this if you are still struggling.
Again, I am a discrete mathematician, not a coder, but an trying to use C# for a paper I am working on and need some help.
I have a code to generate a set of random integers, based on user input, and printed them as a string separated by commas, but need to convert them into a vector (or an int array?). I am not exactly sure which is appropriate, but I cannot find much online about how to use either in C#. I need to be able to apply vector functions to them, so each entry still needs to be identifiable and an integer, but the vector needs to be able to vary in size depending on the user input.
If you already have a comma-delimited string, you can use the String.Split() method to split it based on the commas into an array and then you can convert each of these values into it's appropriate integer using the Int32.Parse() or Convert.ToInt32() methods respectively :
// The Split() method will yield an array, then the Select() statement
// will map each string value to it's appropriate integer and finally
// the last ToArray() call will make this into an actual array of integers
var output = input.Split(',').Select(n => Int32.Parse(n)).ToArray();
You can see an example of this in action here. If you needed to explicitly ignore possible empty entries and whitespace, you could use the following adjusted example :
var output = input.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries)
.Select(s => Int32.Parse(s.Trim()))
.ToArray();
An even safer approach still would be to only use values that could be properly parsed as integers via the Int32.TryParse() method as seen below :
// Split your string, removing any empty entries
var output = strings.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries)
.Select(n => {
// A variable to store your value
int v;
// Attempt to parse it, store an indicator if the parse was
// successful (and store the value in your v parameter)
var success = Int32.TryParse(n, out v);
// Return an object containing your value and if it was successful
return new { Number = v, Successful = success };
})
// Now only select those that were successful
.Where(attempt => attempt.Successful)
// Grab only the numbers for the successful attempts
.Select(attempt => attempt.Number)
// Place this into an array
.ToArray();
When using the .ToArray() function is it necessary to implicitly define the size of the array in order to hold of the characters that were in the list you're converting?
String [] array = List.ToArray();
I tried doing this because I needed to use the .GetValue() ability of the array, however, the array is maintaining a size of 1 and not holding the material from the list. Am I trying to use the .ToArray() incorrectly?
colAndDelimiter = new List<string>();
colAndDelimiter.Add(text);
String [] cd = colAndDelimiter.ToArray();
This is all of the code I have that effects the array. When I Console.WriteLine() the list it gives me the entirety of the text. I may be confused about how list works. Is it storing everything as a single item, and that's why the array only shows one place?
You don't need to convert it to an array to get specific characters out.
Just use text[index] to get at the needed character.
If you really need it as an array, use String.ToCharArray() - you want an array of char not an array of string.
Edit:
Is it storing everything as a single item, and that's why the array only shows one place?
Yes, yes it is. You're making a list of strings which contains one string: the entire contents of text - what it seems that you want is to split it up letter by letter, which is what the above methods will achieve.
It should work fine, but try the var operator to be sure.
var array = List.ToArray();
Is there a reason to use Array.GetValue instead of the built in functions of the List<T> itself
EG:
string value = List.ElementAt(1);
var values = List.GetRange(0, 5);
What you are doing is fine.. but lets say that you are not sure of the size of the
string[] cd then you can do something like the following
var colAndDelimiter = new List<string>();
colAndDelimiter.Add(text);
String[] cd = { };
cd = colAndDelimiter.ToArray();
find the position of the data in cd
string value = cd[0];
Update:
If you want to do this based on values being stored in a single line then you can do this without having to declare the cd variable as string[] cd;
var colAndDelimiter = new List<string>();
colAndDelimiter.Add("Hello, World, Week, Tuesday");
var cd = colAndDelimiter[0].Split(',');
As long as your List object is some IEnumerable (or similar) that has items in it, this should indeed convert your List to an Array.
Note that once you have created this array, adding elements to List won't also add it to the Array
I have a sorted StringList and wanted to replace
foreach (string line3 in CardBase.cardList)
if (line3.ToLower().IndexOf((cardName + Config.EditionShortToLong(edition)).ToLower()) >= 0)
{
return true;
}
with a binarySearch, since the cardList ist rather large(~18k) and this search takes up around 80% of the time.
So I found the List.BinarySearch-Methode, but my problem is that the lines in the cardList look like this:
Brindle_Boar_(Magic_2012).c1p247924.prod
But I have no way to generate the c1p... , which is a problem cause the List.BinarySearch only finds exact matches.
How do I modify List.BinarySearch so that it finds a match if only a part of the string matches?
e. g.
searching for Brindle_Boar_(Magic_2012) should return the position of Brindle_Boar_(Magic_2012).c1p247924.prod
List.BinarySearch will return the ones complement of the index of the next item larger than the request if an exact match is not found.
So, you can do it like this (assuming you'll never get an exact match):
var key = (cardName + Config.EditionShortToLong(edition)).ToLower();
var list = CardBase.cardList;
var index = ~list.BinarySearch(key);
return index != list.Count && list[index].StartsWith(key);
BinarySearch() has an overload that takes an IComparer<T> has second parameter, implement a custom comparer and return 0 when you have a match within the string - you can use the same IndexOf() method there.
Edit:
Does a binary search make sense in your scenario? How do you determine that a certain item is "less" or "greater" than another item? Right now you only provide what would constitute a match. Only if you can answer this question, binary search applies in the first place.
You can take a look at the C5 Generic Collection Library (you can install it via NuGet also).
Use the SortedArray(T) type for your collection. It provides a handful of methods that could prove useful. You can even query for ranges of items very efficiently.
var data = new SortedArray<string>();
// query for first string greater than "Brindle_Boar_(Magic_2012)" an check if it starts
// with "Brindle_Boar_(Magic_2012)"
var a = data.RangeFrom("Brindle_Boar_(Magic_2012)").FirstOrDefault();
return a.StartsWith("Brindle_Boar_(Magic_2012)");
// query for first 5 items that start with "Brindle_Boar"
var b = data.RangeFrom("string").Take(5).Where(s => s.StartsWith("Brindle_Boar"));
// query for all items that start with "Brindle_Boar" (provided only ascii chars)
var c = data.RangeFromTo("Brindle_Boar", "Brindle_Boar~").ToList()
// query for all items that start with "Brindle_Boar", iterates until first non-match
var d = data.RangeFrom("Brindle_Boar").TakeWhile(s => s.StartsWith("Brindle_Boar"));
The RageFrom... methods perform a binary search, find the first element greater than or equal to your argument, that returns an iterator from that position