int to char array - c#

static void Main(string[] args)
{
int num = 382;
int output = 0;
char[] nlst = num.ToString().ToCharArray();
for (int i = 0; i < nlst.Length; i++)
{
output += nlst[i];
}
Console.WriteLine(output);
Console.ReadLine();
}
The output result is 157, Actually it should be 13.With Dedbugging I found the 3 elements of char[] nlst like this :
[0]51'3', [1]56'8', [2]50'2'
Why? What's the meaning of 51,56,50?

You're assuming that the char value of '0' is 0. It is not; it is in fact the UTF16 value of '0' which is 48.
So you are adding together the UTF16 values of the characters '3', '8' and '2', i.e. 51, 56 and 50.
Note that if your aim is to add together all the digits of an integer, the best approach is to avoid converting to a string completely, like so:
int num = 382;
// Compute the sum of digits of num
int total = 0;
while (num > 0)
{
total += num%10;
num /= 10;
}
Console.WriteLine(total);
However if you just want to know how to get your version working, just subtract '0' from each character before adding the codes together. That will convert '0' to 0, '1' to 1, etc:
for (int i = 0; i < nlst.Length; i++)
{
output += nlst[i] - '0'; // Subtract '0' here.
}

Those are the Unicode values for '3', '8' and '2' respectively.
To convert an Unicode value (eg. 51) to the integer representation of the character represented by the Unicode value (eg. 3), use the Convert.ToInt32(char) method.

Those numbers are the char codes of the numbers. If you just want to add up the value of each Digit, you can subtract 48 from each char value to turn it into ist number value
for (int i = 0; i < nlst.Length; i++)
{
output += nlst[i] - 48;
}

Your output variable is defined as an integer. If you add (+=) a char to an integer, it's unicode value will be added to the output variable.
static void Main(string[] args)
{
int num = 382;
int output = 0;
char[] nlst = num.ToString().ToCharArray();
for (int i = 0; i < nlst.Length; i++)
{
output += Convert.ToInt32(nlst[i]);
}
Console.WriteLine(output);
Console.ReadLine();
}

You need to convert the char back to its numeric value.
Try this:
output += Convert.ToInt32(Char.GetNumericValue(nlst[i]));

[EDITED]
Char is unicode 16 (https://msdn.microsoft.com/en-us/library/x9h8tsay.aspx). You can use int.Parse
static void Main(string[] args)
{
int num = 382;
int output = 0;
char[] nlst = num.ToString().ToCharArray();
for (int i = 0; i < nlst.Length; i++)
{
output += int.Parse(nlst[i].ToString());
}
Console.WriteLine(output);
Console.ReadLine();
}

The correct solution is
output += Convert.ToInt32(nlst[i]) - '0';
or briefly
output += nlst[i] - '0';
or, as an alternative
output += Convert.ToInt32(Convert.ToString(nlst[i]));
Please note: As well as C++, C# Convert.ToInt32 converts chars to basic Unicode (i.e. good old Ascii).

Related

count odd and even digits in a number

I try to write program that check the ratio between odd and even
digits in a given number. I've had some problems with this code:
static void Main(string[] args)
{
int countEven = 0 ;
int countOdd = 0 ;
Console.WriteLine("insert a number");
int num = int.Parse(Console.ReadLine());
int length = num.GetLength;
for (int i = 0;i<length ; i++)
{
if((num/10)%2) == 0)
int countEven++;
}
}
any ideas?
The problem is that int does not have a length, only the string representation of it has one.As an alternative to m.rogalski answer, you can treat the input as a string to get all the digits one by one. Once you have a digit, then parsing it to int and checking if it is even or odd is trivial.Would be something like this:
int countEven = 0;
int countOdd = 0;
Console.WriteLine("insert a number");
string inputString = Console.ReadLine();
for (int i = 0; i < inputString.Length; i++)
{
if ((int.Parse(inputString[i].ToString()) % 2) == 0)
countEven++;
else
countOdd++;
}
Linq approach
Console.WriteLine("insert a number");
string num = Console.ReadLine(); // check for valid number here?
int countEven = num.Select(x => x - '0').Count(x => x % 2 == 0);
int countOdd = num.Select(x => x - '0').Count(x => x % 2 != 0);
Let's assume your input is : 123456
Now all you have to do is to get the modulo from the division by ten : int m = num % 10;
After that just check if bool isEven = m % 2 == 0;
On the end you have to just divide your input number by 10 and repeat the whole process till the end of numbers.
int a = 123456, oddCounter = 0, evenCounter = 0;
do
{
int m = a % 10;
switch(m % 2)
{
case 0:
evenCounter++;
break;
default: // case 1:
oddCounter++;
break;
}
//bool isEven = m % 2 == 0;
}while( ( a /= 10 ) != 0 );
Online example
Made a small change to your code and it works perfectly
int countEven = 0;
int countOdd = 0;
Console.WriteLine( "insert a number" );
char[] nums = Console.ReadLine().ToCharArray();
for ( int i = 0; i < nums.Length; i++ )
{
if ( int.Parse( nums[i].ToString() ) % 2 == 0 )
{
countEven++;
}
else
{
countOdd++;
}
}
Console.WriteLine($"{countEven} even numbers \n{countOdd} odd numbers");
Console.ReadKey();
What I do is get each number as a a character in an array char[] and I loop through this array and check if its even or not.
If the Input number is a 32-bit integer (user pick the length of the number)
if asked:
The number of even digits in the input number
Product of odd digits in the input number
The sum of all digits of the input number
private void button1_Click(object sender, EventArgs e) {
int num = ConvertToInt32(textBox1.Text);
int len_num = textBox1.Text.Length;
int[] arn = new int[len_num];
int cEv = 0; pOd = 0; s = 0;
for (int i = len_num-1; i >= 0; i--) { // loop until integer length is got down to 1
arn[i] = broj % 10; //using the mod we put the last digit into a declared array
if (arn[i] % 2 == 0) { // then check, is current digit even or odd
cEv++; // count even digits
} else { // or odd
if (pOd == 0) pOd++; // avoid product with zero
pOd *= arn [i]; // and multiply odd digits
}
num /= 10; // we divide by 10 until it's length is get to 1(len_num-1)
s += arn [i]; // sum of all digits
}
// and at last showing it in labels...
label2.Text = "a) The even digits count is: " + Convert.ToString(cEv);
label3.Text = "b) The product of odd digits is: " + Convert.ToString(pOd);
label4.Text = "c) The sum of all digits in this number is: " + Convert.ToString(s);
}
All we need in the interface is the textbox for entering the number, the button for the tasks, and labels to show obtained results. Of course, we have the same result if we use a classic form for the for loop like for (int i = 0; and <= len_num-1; i++) - because the essence is to count the even or odd digits rather than the sequence of the digits entry into the array
static void Main(string args[]) {
WriteLine("Please enter a number...");
var num = ReadLine();
// Check if input is a number
if (!long.TryParse(num, out _)) {
WriteLine("NaN!");
return;
}
var evenChars = 0;
var oddChars = 0;
// Convert string to char array, rid of any non-numeric characters (e.g.: -)
num.ToCharArray().Where(c => char.IsDigit(c)).ToList().ForEach(c => {
byte.TryParse(c.ToString(), out var b);
if (b % 2 == 0)
evenChars++;
else
oddChars++;
});
// Continue with code
}
EDIT:
You could also do this with a helper (local) function within the method body:
static void Main(string args[]) {
WriteLine("Please enter a number...");
var num = ReadLine();
// Check if input is a number
if (!long.TryParse(num, out _)) {
WriteLine("NaN!");
return;
}
var evenChars = 0;
var oddChars = 0;
// Convert string to char array, rid of any non-numeric characters (e.g.: -)
num.ToCharArray().Where(c => char.IsDigit(c)).ToList().ForEach(c => {
byte.TryParse(c.ToString(), out var b);
if (b % 2 == 0)
evenChars++;
else
oddChars++;
// Alternative method:
IsEven(b) ? evenChars++ : oddChars++;
});
// Continue with code
bool IsEven(byte b) => b % 2 == 0;
}
Why am I using a byte?
Dealing with numbers, it is ideal to use datatypes that don't take up as much RAM.
Granted, not as much an issue nowadays with multiple 100s of gigabytes possible, however, it is something not to be neglected.
An integer takes up 32 bits (4 bytes) of RAM, whereas a byte takes up a single byte (8 bits).
Imagine you're processing 1 mio. single-digit numbers, and assigning them each to integers. You're using 4 MiB of RAM, whereas the byte would only use up 1 MiB for 1 mio. numbers.
And seeming as a single-digit number (as is used in this case) can only go up to 9 (0-9), you're wasting a potential of 28 bits of memory (2^28) - whereas a byte can only go up to 255 (0-255), you're only wasting a measly four bits (2^4) of memory.

What's the fastest way to remove characters from an alpha-numeric string?

Say we have the following strings that we pass as parameters to the function below:
string sString = "S104";
string sString2 = "AS105";
string sString3 = "ASRVT106";
I want to be able to extract the numbers from the string to place them in an int variable. Is there a quicker and/or more efficient way of removing the letters from the strings than the following code?: (*These strings will be populated dynamically at runtime - they are not assigned values at construction.)
Code:
public GetID(string sCustomTag = null)
{
m_sCustomTag = sCustomTag;
try {
m_lID = Convert.ToInt32(m_sCustomTag); }
catch{
try{
int iSubIndex = 0;
char[] subString = sCustomTag.ToCharArray();
//ITERATE THROUGH THE CHAR ARRAY
for (int i = 0; i < subString.Count(); i++)
{
for (int j = 0; j < 10; j++)
{
if (subString[i] == j)
{
iSubIndex = i;
goto createID;
}
}
}
createID: m_lID = Convert.ToInt32(m_sCustomTag.Substring(iSubIndex));
}
//IF NONE OF THAT WORKS...
catch(Exception e)
{
m_lID = 00000;
throw e;
}
}
}
}
I've done things like this before, but I'm not sure if there's a more efficient way to do it. If it was just going to be a single letter at the beginning, I could just set the subStringIndex to 1 every time, but the users can essentially put in whatever they want. Generally, they will be formatted to a LETTER-then-NUMBER format, but if they don't, or they want to put in multiple letters like sString2 or sString3, then I need to be able to compensate for that. Furthermore, if the user puts in some whacked-out, non-traditional format like string sString 4 = S51A24;, is there a way to just remove any and all letters from the string?
I've looked about, and can't find anything on MSDN or Google. Any help or links to it are greatly appreciated!
You can use a regular expression. It's not necessarily faster, but it's more concise.
string sString = "S104";
string sString2 = "AS105";
string sString3 = "ASRVT106";
var re = new Regex(#"\d+");
Console.WriteLine(re.Match(sString).Value); // 104
Console.WriteLine(re.Match(sString2).Value); // 105
Console.WriteLine(re.Match(sString3).Value); // 106
You can use a Regex, but it's probably faster to just do:
public int ExtractInteger(string str)
{
var sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
if(Char.IsDigit(str[i])) sb.Append(str[i]);
return int.Parse(sb.ToString());
}
You can simplify further with some LINQ at the expense of a small performance penalty:
public int ExtractInteger(string str)
{
return int.Parse(new String(str.Where(c=>Char.IsDigit(c)).ToArray()));
}
Now, if you only want to parse the first sequence of consecutive digits, do this instead:
public int ExtractInteger(string str)
{
return int.Parse(new String(str.SkipWhile(c=>!Char.IsDigit(c)).TakeWhile(c=>Char.IsDigit(c)).ToArray()));
}
Fastest is to parse the string without removing anything:
var s = "S51A24";
int m_lID = 0;
for (int i = 0; i < s.Length; i++)
{
int d = s[i] - '0';
if ((uint)d < 10)
m_lID = m_lID * 10 + d;
}
Debug.Print(m_lID + ""); // 5124
string removeLetters(string s)
{
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
if (IsEnglishLetter(c))
{
s = s.Remove(i, 1);
}
}
return s;
}
bool IsEnglishLetter(char c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
While you asked "what's the fastest way to remove characters..." what you really appear to be asking is "how do I create an integer by extracting only the digits from the string"?
Going with this assumption, your first call to Convert.ToInt32 will be slow for the case where you have other than digits because of the exception throwing.
Let's try another approach. Let's think about each of the cases.
The string always starts with a series of digits (e.g. 123ABC => 123)
The string always ends with a series of digits (e.g. ABC123 => 123)
A string has a series of contiguous digits in the middle (e.g. AB123C ==> 123)
The digits are possibly noncontiguous (e.g. A77C12 => 7712)
Case 4 is the "safest" assumption (after all, it is a superset of Case 1, 2 and 3. So, we need an algorithm for that. As a bonus I'll provide algorithms specialized to the other cases.
The Main Algorithm, All Cases
Using in-place unsafe iteration of the characters of the string, which uses fixed, we can extract digits and convert them to a single number without the data copy in ToCharArray(). We can also avoid the allocations of, say, a StringBuilder implementation and a possibly slow regex solution.
NOTE: This is valid C# code though it's using pointers. It does look like C++, but I assure you it's C#.
public static unsafe int GetNumberForwardFullScan(string s)
{
int value = 0;
fixed (char* pString = s)
{
var pChar = pString;
for (int i = 0; i != s.Length; i++, pChar++)
{
// this just means if the char is not between 0-9, we exit the loop (i.e. stop calculating the integer)
if (*pChar < '0' || *pChar > '9')
continue;
// running recalculation of the integer
value = value * 10 + *pChar - '0';
}
}
return value;
}
Running this against any of the inputs: "AS106RVT", "ASRVT106", "106ASRVT", or "1AS0RVT6" results in pulling out 1, 0, 6 and calculating on each digit as
0*10 + 1 == 1
1*10 + 0 == 10
10*10 + 6 == 106
Case 1 Only Algorithm (Digits at Start of String)
This algorithm is identical to the one above, but instead of continue we can break as soon as we reach a non-digit. This would be much faster if we can assume all the inputs start with digits and the strings are long.
Case 2 Only Algorithm (Digits at End of String)
This is almost the same as Case 1 Only except you have to
iterate from the end of the string to the beginning (aka backwards) stopping on the first non-digit
change the calculation to sum up powers of ten.
Both of those are a bit tricky, so here's what that looks like
public static unsafe int GetNumberBackward(string s)
{
int value = 0;
fixed (char* pString = s)
{
char* pChar = pString + s.Length - 1;
for (int i = 0; i != -1; i++, pChar--)
{
if (*pChar < '0' || *pChar > '9')
break;
value = (*pChar - '0') * (int)Math.Pow(10, i) + value;
}
}
return value;
}
So each of the iteration of the calculation looks like
6*100 + 0 == 6
0*101 + 6 == 6
1*102 + 6 == 106
While I used Math.Pow in these examples, you can find integer only versions that might be faster.
Cases 1-3 Only (i.e. All Digits Contiguous Somewhere in the String
This algorithm says to
Scan all non-digits
Then scan only digits
First non-digit after that, stop
It would look like
public static unsafe int GetContiguousDigits(string s)
{
int value = 0;
fixed (char* pString = s)
{
var pChar = pString;
// skip non-digits
int i = 0;
for (; i != s.Length; i++, pChar++)
if (*pChar >= '0' && *pChar <= '9')
break;
for (; i != s.Length; i++, pChar++)
{
if (*pChar < '0' || *pChar > '9')
break;
value = value * 10 + *pChar - '0';
}
}
return value;
}

Convert "int" into "char" inside char array

I am trying to do string manipulation. Here's my C# code :
static void Main(string[] args)
{
string input;
string output;
int length;
Console.WriteLine("input = ");
input = Console.ReadLine();
length = input.Length;
if ((input != "") || (length != 0))
{
Random randem = new Random();
int i = -1; //because I do not want the first number to be replaced by the random number
char[] characters = input.ToCharArray();
while (i < length)
{
int num = randem.Next(0, 9);
char num1 = Convert.ToChar(num);
i = i + 2; //so that every next character will be replaced by random number.. :D
characters[i] = num1; //*error* here
}
output = new string(characters);
Console.WriteLine(output);
}
For example:
User input : "i_love_to_eat_fish"
Desired output : "i2l4v1_9o5e8t7f8s2"
notice that the only unchanged character in
the char[] characters is : "i l v _ o e t f s". (desired output from the program)
I've already tried using this code, but still,
keep getting error at characters[i] = num1;
Am I on the right track?
I'm guessing the error you get is IndexOutOfRangeException this is because of the i = i + 2;. The while makes sure that i is less than length, but then adding 2 could result in it being more. Just add a check that it isn't beyond the length.
i = i + 2;
if(i < length)
characters[i] = num1;
Or just change to a for loop.
Random randem = new Random();
char[] characters = input.ToCharArray();
for(int i = 1; i < length; i += 2)
{
int num = randem.Next(1, 10); // max value is exclusive
char num1 = num.ToString()[0];
characters[i] = num1;
}
output = new string(characters);
Console.WriteLine(output);
Also as Shar1er80 points out you're currently converting the digit to the char that has the same ASCII value, and not the the actual characters that represent the digit. The digits 0-9 are represented by the the values 48-57. You can change the call to Random.Next to be:
int num = randem.Next(48, 58); // The upper bound is exclusive, not inclusive
char num1 = (char)num;
Or as Shar1er80 does it
int num = randem.Next(0,10) // Assumming you want digits 0-9
char num1 = num.ToString[0];
Also note that the max value for Random.Next is exclusive, so if you want to include the possibility of using a 9 you have to use an upper bound that is 1 greater than the greatest value you want.
Whenever you reach i = 17 you add 2 to i . That makes i = 19 with length of input equal to 18 that causes out of range exception.
The error you are getting is IndexOutOfTheRangeException, which explains everthing in itself.
It means that index you are feeding to array in the loop is going beyond its length-1 (as arrays have 0-based indexing)
So when you do i+2, you need to check if i+2 is not exceeding i.length-1 at any point of time; which does in your loop.
In general just check if you are supplying indexes between 0 and Array.Length-1
its because you start at index -1, and characters doesn't contain an index of -1.
EDIT: Sorry no the corrct answer is it must be while(i < length - 2)
Change this line
char num1 = Convert.ToChar(num);
To
char num1 = num.ToString()[0];
Then... Put
characters[i] = num1;
In an if block
if (i < length)
characters[i] = num1;

Add up al numbers in a string C#

I want to add up all numbers in a string, I am sure this can be done easy with a for loop.
I have:
int numbers = 1234512345;
for (int i = 0 ; i numbers.Length ; i++)
{
int total;
total = int [i];
}
But it won't work for a reason, I am puzzled a lot.
For one, the "string" you're trying to iterate over is an int. You probably meant something along the lines of
string numbers = "1234512345"
After that, there are several ways to do this, my favorite personally is iterating over each character of the string, using a TryParse on it (this eliminates any issues if the string happens to be alphanumeric) and totaling the result. See below:
static void Main(string[] args) {
string numbers = "1234512345";
int total = 0;
int num; // out result
for (int i = 0; i < numbers.Length; i++) {
int.TryParse(numbers[i].ToString(), out num);
total += num; // will equal 30
}
Console.WriteLine(total);
total = 0;
string alphanumeric = "1#23451!23cf47c";
for (int i = 0; i < alphanumeric.Length; i++) {
int.TryParse(alphanumeric[i].ToString(), out num);
total += num; // will equal 32, non-numeric characters are ignored
}
Console.WriteLine(total);
Console.ReadLine();
}
Like others have posted though, there are several ways to go about this, it's about personal preference most of all.
this should do what you want
int total = 0;
foreach(char numchar in numbers)
{
total += (int)char.GetNumericValue(numchar);
}
EDIT:
1 line solution:
int total = numbers.Sum(x=> (int)char.GetNumericValue(x));
PS: Why the downvotes?

Code showing wrong output

I have developed a program in c# which is doing "Insertion Sort", the code takes in a max value for the elements and the values of the elements and then one by one shows the steps of sorted values.
Code:
static void insertionSort(int[] ar)
{
for (int i = 1; i < ar.Length; i++)
{
int temp = ar[i];
int j = i - 1;
while (j >= 0 && ar[j] > temp)
{
ar[j + 1] = ar[j];
foreach (int val in ar)
Console.Write(val + " ");
Console.WriteLine();
j--;
}
}
}
static void Main(String[] args)
{
int ar_size;
ar_size = Convert.ToInt32(Console.ReadLine());
int[] ar = new int[ar_size];
for (int i = 0; i < ar_size; i++)
{
ar[i] = Convert.ToInt32(Console.Read());
}
insertionSort(ar);
Console.ReadKey();
}
The Sample Input That I Give:
5
2 4 6 8 3
The Output That Comes:
Can anyone explain me why is this happening!
Any help would be greatly appreciated! :)
Apart from the problems with your sort itself, the reason for the strange numbers in your result is that you use Console.Read very wrong. It returns the ASCII value of the character entered by the user. Furthermore, it will return the ASCII values for all entered characters, not only for the numbers.
So, the first call to Console.Read() will return 50 (ASCII value of '2').
The second call will return 32 (ASCII value of a space).
The third call will return 52 (ASCII value of '4').
etc.
To fix this, initialize ar like this:
var numbers = Console.ReadLine().Split(' ');
for (int i = 0; i < ar_size; i++)
ar[i] = Convert.ToInt32(numbers[i]);
Please note that this code lacks error handling. It will throw an exception in the followin circumstances:
The user entered anything besides spaces and numbers
The user entered less numbers than he specified in the first line

Categories

Resources