insert string into List<int> [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Parse string to int array
I have string which comes from a numeric textbox like this: 2670053157. how should I split each character of string and insert them into List<int> elements?

var list = numberString.Select(c => Int32.Parse(c.ToString())).ToList();
Or, if you'd rather add to an existing list:
list.AddRange(numberString.Select(c => Int32.Parse(c.ToString()));

var list = new List<int>();
list.AddRange(
from character in numericString
select int.Parse(character));

List<int> numericlist = "2670053157".Select(c => c - '0').ToList();

If you're afraid of exceptions being thrown due to improper inputs, you could always go the safe route:
// string input = TextBox1.Text;
List<int> intList = new List<int>();
foreach (char c in input)
{
int i;
if (Int32.TryParse(c.ToString(), out i))
{
intList.Add(i);
}
}

Start out with a helper method:
public static IEnumerable<short> getDigits(long input)
{
while (input > 0)
{
yield return (short)(input % 10);
input /= 10;
}
}
Then if you want the values in a list, just call ToList:
List<short> list = getDigits(2670053157).ToList();
If you want the higher order bits first you'll need to Reverse the sequence:
List<short> list = getDigits(2670053157).Reverse().ToList();

Related

How to skip over characters already looped through in a string

I have a function findChar() that loops through a string to find occurrences of characters in a string Ex: "Cincinnati" (2 Cs, 2 i's, etc) but once it finds another 'C' or 'i' it will return the values again
public static int findChar(string name, char c)
{
int count = 0;
for (int i = 0; i < name.Length; i++)
{
if (name[i] == c || name[i] == Char.ToUpper(c) || name[i] == Char.ToLower(c))
{
count++;
}
}
return count;
}
static void Main(string[] args)
{
string name = "Cincinnati";
char c = ' ' ;
int count = 0;
for (int i = 0; i < name.Length; i++)
{
c = name[i];
count = findChar(name, c);
Console.WriteLine(count);
}
}
My Output looks like this:
2
3
3
2
3
3
3
1
1
3
And I need it to be like:
2
3
3
1
1
Option 1: keep track of the letters you already processed, and ignore it if you already did
Option 2: use System.Linq's GroupBy to get the count
public static void Main()
{
var name = "Cincinatti";
var letters = name.ToLower().GroupBy(letter => letter);
foreach (var group in letters) {
Console.WriteLine(group.Count());
}
}
There are many ways to solve a problem like this. First let's discuss a problem it looks like you've already run into, capitalization. Lower case and upper case versions of the same letter are classified as different characters. The easiest way to combat this is to either convert the string to lowercase or uppercase so each duplicate letter can also be classified as a duplicate character. You can do this either by using the String.ToLower() method or the String.ToUpper() method depending on which one you want to use.
The way to solve this that is the closest to what you have is to just create a list, add letters to it as you process them, then use the list to check what letters you've processed already. It would look something like this:
static void Main(string[] args)
{
string name = "Cincinnati";
char c = ' ' ;
int count = 0;
var countedLetters = new List<string>();
for (int i = 0; i < name.Length; i++)
{
c = name[i];
char cLower = char.ToLower(c);
if(countedLetters.Contains(cLower))
{
continue;
}
countedLetters.Add(cLower);
count = findChar(name, c);
Console.WriteLine(count);
}
}
Although, you can usually use System.Linq's Enumerable extension methods to do things like this pretty easily.
Not deviating too much from what you have, another solution using System.Linq would be to just get the distinct characters and loop through that instead of the entire string. When doing this, we need to convert the entire string to either upper or lower case in order for linq to return the expected result. This would like something like this:
static void Main(string[] args)
{
string name = "Cincinnati";
string nameLower = name.ToLower();
int count = 0;
foreach(char c in nameLower.Distinct())
{
count = findChar(name, c);
Console.WriteLine(count);
}
}
Then finally, you can simplify this a ton by leaning heavily into the linq route. GroupBy is very useful for this because it's entire purpose is to group duplicates together. There are many ways to implement this and two have already be provided, so I will just provide a third.
public static void Main()
{
string name = "Cincinatti";
int[] counts = name.ToLower()
.GroupBy(letter => letter)
.Select(group => group.Count())
.ToArray();
Console.WriteLine(string.Join("\n", counts));
}
you can do group by list, sort optional (i left it commented out) and then select count
var word="Cincinnati";
var groups = word.ToLower().GroupBy(n => {return n;})
.Select(n => new
{
CharachterName = n.Key,
CharachterCount = n.Count()
});
// .OrderBy(n => n.CharachterName);
Console.WriteLine(JsonConvert.SerializeObject(groups.Select(i=>i.CharachterCount)));

Convert string[] to Int[] without losing leading zeros

Input:
string param = "1100,1110,0110,0001";
Output:
int[] matrix = new[]
{
1,1,0,0,
1,1,1,0,
0,1,1,0,
0,0,0,1
};
What I did?
First of all I splited string to string[].
string[] resultantArray = param.Split(',');
Created one method, where I passed my string[].
var intArray = toIntArray(resultantArray);
static private int[] toIntArray(string[] strArray)
{
int[] intArray = new int[strArray.Length];
for (int i = 0; i < strArray.Length; i++)
{
intArray[i] = int.Parse(strArray[i]);
}
return intArray;
}
Issue?
I tried many solutions of SO, but none of them helped me.
Ended up with array without leading zeroes.
determine all digits: .Where(char.IsDigit)
convert the selected char-digits into integer: .Select(x => x-'0') (this is not as pretty as int.Parse or Convert.ToInt32 but it's super fast)
Code:
string param = "1100,1110,0110,0001";
int[] result = param.Where(char.IsDigit).Select(x => x-'0').ToArray();
As CodesInChaos commented, this could lead to an error if there are other type of Digits within your input like e.g. Thai digit characters: '๐' '๑' '๒' '๓' '๔' '๕' '๖' '๗' '๘' '๙' where char.IsDigit == true - if you need to handle such special cases you can allow only 0 and 1 in your result .Where("01".Contains)
You could also remove the commas and convert the result character-wise as follows using Linq.
string param = "1100,1110,0110,0001";
int[] result = param.Replace(",", "").Select(c => (int)Char.GetNumericValue(c)).ToArray();
yet another way to do this
static private IEnumerable<int> toIntArray(string[] strArray)
{
foreach (string str in strArray)
{
foreach (char c in str)
{
yield return (int)char.GetNumericValue(c);
}
}
}
What about this?
string input = "1100,1110,0110,0001";
var result = input
.Split(',')
.Select(e => e.ToCharArray()
.Select(f => int.Parse(f.ToString())).ToArray())
.ToArray();
string[] s=param.split(',');
Char[] c;
foreach(string i in s){
c+=i.ToCharArray()
}
int[] myintarray;
int j=0;
foreach(char i in c){
myintarray[j]=(int)i;
j++
}

Splitting string into an array on 16th char [duplicate]

This question already has answers here:
Splitting a string into chunks of a certain size
(39 answers)
Split string after certain character count
(4 answers)
Closed 8 years ago.
I have a text file with various 16 char strings both appended to one another and on separate lines. I've done this
FileInfo f = new FileInfo("d:\\test.txt");
string FilePath = ("d:\\test.txt");
string FileText = new System.IO.StreamReader(FilePath).ReadToEnd().Replace("\r\n", "");
CharCount = FileText.Length;
To remove all of the new lines and create one massively appended string. I need now to split this massive string into an array. I need to split it up on the consecutive 16th char until the end. Can anyone guide me in the right direction? I've taken a look at various methods in String such as Split and in StreamReader but am confused as to what the best way to go about it would be. I'm sure it's simple but I can't figure it out.
Thank you.
Adapting the answer from here:
You could try something like so:
string longstr = "thisisaverylongstringveryveryveryveryverythisisaverylongstringveryveryveryveryvery";
IEnumerable<string> splitString = Regex.Split(longstr, "(.{16})").Where(s => s != String.Empty);
foreach (string str in splitString)
{
System.Console.WriteLine(str);
}
Yields:
thisisaverylongs
tringveryveryver
yveryverythisisa
verylongstringve
ryveryveryveryve
ry
One possible solution could look like this (extracted as extension method and made dynamic, in case different token size is needed and no hard-coded dependencies):
public static class ProjectExtensions
{
public static String[] Chunkify(this String input, int chunkSize = 16)
{
// result
var output = new List<String>();
// temp helper
var chunk = String.Empty;
long counter = 0;
// tokenize to 16 chars
input.ToCharArray().ToList().ForEach(ch =>
{
counter++;
chunk += ch;
if ((counter % chunkSize) == 0)
{
output.Add(chunk);
chunk = String.Empty;
}
});
// add the rest
output.Add(chunk);
return output.ToArray();
}
}
The standard usage (16 chars) looks like this:
// 3 inputs x 16 characters and 1 x 10 characters
var input = #"1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890";
foreach (var chunk in input.Chunkify())
{
Console.WriteLine(chunk);
}
The output is:
1234567890ABCDEF
1234567890ABCDEF
1234567890ABCDEF
1234567890
Usage with different token size:
foreach (var chunk in input.Chunkify(13))
{
Console.WriteLine(chunk);
}
and the corresponding output:
1234567890ABC
DEF1234567890
ABCDEF1234567
890ABCDEF1234
567890
It is not a fancy solution (and could propably be optimised for speed), but it works and it is easy to understand and implement.
Create a list to hold your tokens. Then get subsequent substrings of length 16 and add them to the list.
List<string> tokens = new List<string>();
for(int i=0; i+16<=FileText.Length; i+=16) {
tokens.Add(FileText.Substring(i,16));
}
As mentioned in the comments, this ignores the last token if it has less than 16 characters. If you want it anyway you can write:
List<string> tokens = new List<string>();
for(int i=0; i<FileText.Length; i+=16) {
int len = Math.Min(16, FileText.Length-i));
tokens.Add(FileText.Substring(i,len);
}
Please try this method. I haven't tried it , but used it once.
int CharCount = FileText.Length;
int arrayhold = (CharCount/16)+2;
int count=0;
string[] array = new string[arrayhold];
for(int i=0; i<FileText.Length; i+=16)
{
int currentleft = FileText.Length-(16*count);
if(currentleft>16)
{
array[count]=FileText.Substring(i,16);
}
if(currentleft<16)
{
array[count]=FileText.Substring(i,currentleft);
}
count++;
}
This is the new code and provide a TRUE leftovers handling. Tested in ideone
Hope it works
Try this one:
var testArray = "sdfsdfjshdfalkjsdfhalsdkfjhalsdkfjhasldkjfhasldkfjhasdflkjhasdlfkjhasdlfkjhasdlfkjhasldfkjhalsjfdkhklahjsf";
var i = 0;
var query = from s in testArray
let num = i++
group s by num / 16 into g
select new {Value = new string(g.ToArray())};
var result = query.Select(x => x.Value).ToList();
result is List containing all the 16 char strings.

find and parse values from string

I have a string that I am trying to parse the values from. It is in this format "43,56,12,ddl=345".
I am trying to store the ddl value (345) in a separate variable, then the other numbers in a list.
List<int> nums = new List<int>();
int? ddlValue;
How do I go about this?
You could try parsing the string for ints, and then have special checks for any other values you want to store.
var sNums = "43,56,12,ddl=345";
List<int> nums = new List<int>();
int? ddlValue;
foreach (var t in sNums.Split(',')) {
int u;
if (int.TryParse(t, out u)) {
nums.Add(u);
} else {
ddlValue = t.Split("=")[1];
}
}
You can do:
var sNums = "43,56,12,ddl=345".Split(',');
var ddl = int.Parse(sNums.First(s => s.Contains("ddl")).Replace("ddl=", ""));
var numbers = sNums.Where(s => !s.Contains("ddl")).Select(int.Parse);
*note - this will be slightly less efficient that doing it in a single loop - but more readable IMO.
You can do something like this:
List<int> nums=new List<int>();
int intVariable = 0;
string s = "43,56,12,ddl=345";
string[] split=s.Split(',');
Regex regex = new Regex(#"^\d+$");
foreach(var element in split)
if(regex.IsMatch(element))
nums.Add(Convert.ToInt32(element));
else
{
intVariable = element.Split("=")[1];
}
I mean the simplest way is a split and replace.
string values = "43,56,12,ddl=345";
string[] values1 = values.Split(',');
foreach (var x in values1)
{
list.Add(x);
}
string myvalue = values.Split(',')[3];
myvalue = myvalue.Replace("ddl=","");
this assumes your going to be getting the same format every time. Maybe more information?
EDIT-
If you will not always have 3 numbers then the ddl= then string myvalue = values.Split(',')[3]; will not work. Theres a few easy ways around it like
string myvalue = values.Split(',')[values1.Count() - 1]

Converting a string number into sequence of digits - .Net 2.0

Given a string
string result = "01234"
I want to get the separate integers 0,1,2,3,4 from the string.
How to do that?
1
The following code is giving me the ascii values
List<int> ints = new List<int>();
foreach (char c in result.ToCharArray())
{
ints.Add(Convert.ToInt32(c));
}
EDIT: I hadn't spotted the ".NET 2.0" requirement. If you're going to do a lot of this sort of thing, it would probably be worth using LINQBridge, and see the later bit - particularly if you can use C# 3.0 while still targeting 2.0. Otherwise:
List<int> integers = new List<int>(text.Length);
foreach (char c in text)
{
integers.Add(c - '0');
}
Not as neat, but it will work. Alternatively:
List<char> chars = new List<char>(text);
List<int> integers = chars.ConvertAll(delegate(char c) { return c - '0'; });
Or if you'd be happy with an array:
char[] chars = text.ToCharArray();
int[] integers = Arrays.ConvertAll<char, int>(chars,
delegate(char c) { return c - '0'; });
Original answer
Some others have suggested using ToCharArray. You don't need to do that - string already implements IEnumerable<char>, so you can already treat it as a sequence of characters. You then just need to turn each character digit into the integer representation; the easiest way of doing that is to subtract the Unicode value for character '0':
IEnumerable<int> digits = text.Select(x => x - '0');
If you want this in a List<int> instead, just do:
List<int> digits = text.Select(x => x - '0').ToList();
Loop the characters and convert each to a number. You can put them in an array:
int[] digits = result.Select(c => c - '0').ToArray();
Or you can loop through them directly:
foreach (int digit in result.Select(c => c - '0')) {
...
}
Edit:
As you clarified that you are using framework 2.0, you can apply the same calculation in your loop:
List<int> ints = new List<int>(result.Length);
foreach (char c in result) {
ints.Add(c - '0');
}
Note: Specify the capacity when you create the list, that elliminates the need for the list to resize itself. You don't need to use ToCharArray to loop the characters in the string.
You could use LINQ:
var ints = result.Select(c => Int32.Parse(c.ToString()));
Edit:
Not using LINQ, your loop seems good enough. Just use Int32.Parse instead of Convert.ToInt32:
List<int> ints = new List<int>();
foreach (char c in result.ToCharArray())
{
ints.Add(Int32.Parse(c.ToString()));
}
string result = "01234";
List<int> list = new List<int>();
foreach (var item in result)
{
list.Add(item - '0');
}
Index into the string to extract each character. Convert each character into a number. Code left as an exercise for the reader.
another solution...
string numbers = "012345";
List<int> list = new List<int>();
foreach (char c in numbers)
{
list.Add(int.Parse(c.ToString()));
}
no real need to do a char array from the string since a string can be enumerated over just like an array.
also, the ToString() makes it a string so the int.Parse will give you the number instead of the ASCII value you get when converting a char.
List<int> ints = new List<int>();
foreach (char c in result.ToCharArray())
{
ints.Add(Convert.ToInt32(c));
}
static int[] ParseInts(string s) {
int[] ret = new int[s.Length];
for (int i = 0; i < s.Length; i++) {
if (!int.TryParse(s[i].ToString(), out ret[i]))
throw new InvalidCastException(String.Format("Cannot parse '{0}' as int (char {1} of {2}).", s[i], i, s.Length));
}
return ret;
}

Categories

Resources