How to convert string into int array in C# - c#

I am making a credit card validator program in which I am asking for a string which is going to be a 16 digit number (credit card #) and I want to convert that into an int array. How do I do that? I need to then multiply every other digit starting from the first digit by 2.
char[] creditNumbers = creditCardNumber.ToCharArray();
creditNumbers[0] = (char)((int)(creditNumbers[0] * 2));
creditNumbers[2] = (char)((int)(creditNumbers[2] * 2));
creditNumbers[4] = (char)((int)(creditNumbers[4] * 2));
creditNumbers[6] = (char)((int)(creditNumbers[6] * 2));
creditNumbers[8] = (char)((int)(creditNumbers[8] * 2));
This is what I made so far but my casting is not done properly. How do I fix the problem?

To just get the int array, I would do this:
creditCardNumber.Select(c => int.Parse(c.ToString())).ToArray()
To check the number using the Luhn algorithm, you could do this:
bool IsValid(string creditCardNumber)
{
var sum = creditCardNumber.Reverse()
.Select(TransformDigit)
.Sum();
return sum % 10 == 0;
}
int TransformDigit(char digitChar, int position)
{
int digit = int.Parse(digitChar.ToString());
if (position % 2 == 1)
digit *= 2;
return digit % 10 + digit / 10;
}

var intArray = creditCardNumber.ToCharArray().Select(o => int.Parse(o.ToString())).ToArray();
var result = new List<int>();
for(int i=0; i<intArray.Length; i++){
if((i % 2) == 0)
result.Add(intArray[i] * 2);
else
result.Add(intArray[i]);
}
Console.Write(string.Concat(result.Select(o => o.ToString())));

Related

Calculating the correct length of string per line with Page X/Y

I got asked a question and now I am kicking myself for not being able to come up with the exact/correct result.
Imagine we have a function that splits a string into multiple lines but each line has to have x number of characters before we "split" to the new line:
private string[] GetPagedMessages(string input, int maxCharsPerLine) { ... }
For each line, we need to incorporate, at the end of the line "x/y" which is basically 1/4, 2/4 etc...
Now, the paging mechanism must also be part of the length restriction per line.
I have been overworked and overthinking and tripping up on things and this seems pretty straight forward but for the life of me, I cannot figure it out! What am I not "getting"?
What am I interested in? The calculation and some part of the logic but mainly the calculation of how many lines are required to split the input based on the max chars per line which also needs to include the x/y.
Remember: we can have more than a single digit for the x/y (i.e: not just 1/4 but also 10/17 or 99/200)
Samples:
input = "This is a long message"
maxCharsPerLine = 10
output:
This i 1/4 // << Max 10 chars
s a lo 2/4 // << Max 10 chars
ng mes 3/4 // << Max 10 chars
sage 4/4 // << Max 10 chars
Overall the logic is simple but its just the calculation that is throwing me off.
The idea: First, find how many digits is the number of lines:
(n = input.Length, maxCharsPerLine = 10)
if n <= 9*(10-4) ==> 1 digit
if n <= 9*(10-5) + 90*(10-6) ==> 2 digits
if n <= 9*(10-6) + 90*(10-7) + 900*(10-8) ==> 3 digits
if n <= 9*(10-7) + 90*(10-8) + 900*(10-9) + 9000*(10-10) ==> No solution
Then, subtract the spare number of lines. The solution:
private static int GetNumberOfLines(string input, int maxCharsPerLine)
{
int n = input.Length;
int x = maxCharsPerLine;
for (int i = 4; i < x; i++)
{
int j, sum = 0, d = 9, numberOfLines = 0;
for (j = i; j <= i + i - 4; j++)
{
if (x - j <= 0)
return -1; // No solution
sum += d * (x - j);
numberOfLines += d;
d *= 10;
}
if (n <= sum)
return numberOfLines - (sum - n) / (x - j + 1);
}
return -2; // Invalid
}
Usage:
private static string[] GetPagedMessages(string input, int maxCharsPerLine)
{
int numberOfLines = GetNumberOfLines(input, maxCharsPerLine);
if (numberOfLines < 0)
return null;
string[] result = new string[numberOfLines];
int spaceLeftForLine = maxCharsPerLine - numberOfLines.ToString().Length - 2; // Remove the chars of " x/y" except the incremental 'x'
int inputPosition = 0;
for (int line = 1; line < numberOfLines; line++)
{
int charsInLine = spaceLeftForLine - line.ToString().Length;
result[line - 1] = input.Substring(inputPosition, charsInLine) + $" {line}/{numberOfLines}";
inputPosition += charsInLine;
}
result[numberOfLines-1] = input.Substring(inputPosition) + $" {numberOfLines}/{numberOfLines}";
return result;
}
A naive approach is to start counting the line lengths minus the "pager"'s size, until the line count changes in size ("1/9" is shorter than "1/10", which is shorter than "11/20", and so on):
private static int[] GetLineLengths(string input, int maxCharsPerLine)
{
/* The "pager" (x/y) is at least 4 characters (including the preceding space) and at most ... 8?
* 7/9 (4)
* 1/10 (5)
* 42/69 (6)
* 3/123 (6)
* 42/420 (7)
* 999/999 (8)
*/
int charsRemaining = input.Length;
var lineLengths = new List<int>();
// Start with " 1/2", (1 + 1 + 2) = 4 length
var highestLineNumberLength = 1;
var lineNumber = 0;
do
{
lineNumber++;
var currentLineNumberLength = lineNumber.ToString().Length; // 1 = 1, 99 = 2, ...
if (currentLineNumberLength > highestLineNumberLength)
{
// Pager size changed, reset
highestLineNumberLength = currentLineNumberLength;
lineLengths.Clear();
lineNumber = 0;
charsRemaining = input.Length;
continue;
}
var pagerSize = currentLineNumberLength + highestLineNumberLength + 2;
var lineLength = maxCharsPerLine - pagerSize;
if (lineLength <= 0)
{
throw new ArgumentException($"Can't split input of size {input.Length} into chunks of size {maxCharsPerLine}");
}
lineLengths.Add(lineLength);
charsRemaining -= lineLength;
}
while (charsRemaining > 0);
return lineLengths.ToArray();
}
Usage:
private static string[] GetPagedMessages(string input, int maxCharsPerLine)
{
if (input.Length <= maxCharsPerLine)
{
// Assumption: no pager required for a message that takes one line
return new[] { input };
}
var lineLengths = GetLineLengths(input, maxCharsPerLine);
var result = new string[lineLengths.Length];
// Cut the input and append the pager
var previousIndex = 0;
for (var i = 0; i < lineLengths.Length; i++)
{
var lineLength = Math.Min(lineLengths[i], input.Length - previousIndex); // To cater for final line being shorter
result[i] = input.Substring(previousIndex, lineLength) + " " + (i + 1) + "/" + lineLengths.Length;
previousIndex += lineLength;
}
return result;
}
Prints, for example:
This 1/20
is a 2/20
long 3/20
strin 4/20
g tha 5/20
t wil 6/20
l spa 7/20
n mor 8/20
e tha 9/20
n te 10/20
n li 11/20
nes 12/20
beca 13/20
use 14/20
of i 15/20
ts e 16/20
norm 17/20
ous 18/20
leng 19/20
th 20/20

Convert an integer to a binary string with leading zeros

I need to convert int to bin and with extra bits.
string aaa = Convert.ToString(3, 2);
it returns 11, but I need 0011, or 00000011.
How is it done?
11 is binary representation of 3. The binary representation of this value is 2 bits.
3 = 20 * 1 + 21 * 1
You can use String.PadLeft(Int, Char) method to add these zeros.
// convert number 3 to binary string.
// And pad '0' to the left until string will be not less then 4 characters
Convert.ToString(3, 2).PadLeft(4, '0') // 0011
Convert.ToString(3, 2).PadLeft(8, '0') // 00000011
I've created a method to dynamically write leading zeroes
public static string ToBinary(int myValue)
{
string binVal = Convert.ToString(myValue, 2);
int bits = 0;
int bitblock = 4;
for (int i = 0; i < binVal.Length; i = i + bitblock)
{ bits += bitblock; }
return binVal.PadLeft(bits, '0');
}
At first we convert my value to binary.
Initializing the bits to set the length for binary output.
One Bitblock has 4 Digits. In for-loop we check the length of our converted binary value und adds the "bits" for the length for binary output.
Examples:
Input: 1 -> 0001;
Input: 127 -> 01111111
etc....
You can use these methods:
public static class BinaryExt
{
public static string ToBinary(this int number, int bitsLength = 32)
{
return NumberToBinary(number, bitsLength);
}
public static string NumberToBinary(int number, int bitsLength = 32)
{
string result = Convert.ToString(number, 2).PadLeft(bitsLength, '0');
return result;
}
public static int FromBinaryToInt(this string binary)
{
return BinaryToInt(binary);
}
public static int BinaryToInt(string binary)
{
return Convert.ToInt32(binary, 2);
}
}
Sample:
int number = 3;
string byte3 = number.ToBinary(8); // output: 00000011
string bits32 = BinaryExt.NumberToBinary(3); // output: 00000000000000000000000000000011
public static String HexToBinString(this String value)
{
String binaryString = Convert.ToString(Convert.ToInt32(value, 16), 2);
Int32 zeroCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(binaryString.Length) / 8)) * 8;
return binaryString.PadLeft(zeroCount, '0');
}
Just what Soner answered use:
Convert.ToString(3, 2).PadLeft(4, '0')
Just want to add just for you to know. The int parameter is the total number of characters that your string and the char parameter is the character that will be added to fill the lacking space in your string. In your example, you want the output 0011 which which is 4 characters and needs 0's thus you use 4 as int param and '0' in char.
string aaa = Convert.ToString(3, 2).PadLeft(10, '0');
This may not be the most elegant solution but it is the fastest from my testing:
string IntToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(int) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((uint)value << (n + diff))) >> (sizeof(int) * 8 - 1)));
}
return new string(output);
}
string LongToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(long) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((ulong)value << (n + diff))) >> (sizeof(long) * 8 - 1)));
}
return new string(output);
}
This version completely avoids if statements and therfore branching which creates very fast and most importantly linear code. This beats the Convert.ToString() function from microsoft by up to 50%
Here is some benchmark code
long testConv(Func<int, int, string> fun, int value, int digits, long avg) {
long result = 0;
for (long n = 0; n < avg; n++) {
var sw = Stopwatch.StartNew();
fun(value, digits);
result += sw.ElapsedTicks;
}
Console.WriteLine((string)fun(value, digits));
return result / (avg / 100);//for bigger output values
}
string IntToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(int) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((uint)value << (n + diff))) >> (sizeof(int) * 8 - 1)));
}
return new string(output);
}
string Microsoft(int value, int totalDigits) {
return Convert.ToString(value, toBase: 2).PadLeft(totalDigits, '0');
}
int v = 123, it = 10000000;
Console.WriteLine(testConv(Microsoft, v, 10, it));
Console.WriteLine(testConv(IntToBinary, v, 10, it));
Here are my results
0001111011
122
0001111011
75
Microsofts Method takes 1.22 ticks while mine only takes 0.75 ticks
With this you can get binary representation of string with corresponding leading zeros.
string binaryString = Convert.ToString(3, 2);;
int myOffset = 4;
string modified = binaryString.PadLeft(binaryString.Length % myOffset == 0 ? binaryString.Length : binaryString.Length + (myOffset - binaryString.Length % myOffset), '0'));
In your case modified string will be 0011, if you want you can change offset to 8, for instance, and you will get 00000011 and so on.

Split number into groups of 3 digits

I want to make a method that takes a variable of type int or long and returns an array of ints or longs, with each array item being a group of 3 digits. For example:
int[] i = splitNumber(100000);
// Outputs { 100, 000 }
int[] j = splitNumber(12345);
// Outputs { 12, 345 }
int[] k = splitNumber(12345678);
// Outputs { 12, 345, 678 }
// Et cetera
I know how to get the last n digits of a number using the modulo operator, but I have no idea how to get the first n digits, which is the only way to make this method that I can think of. Help please!
Without converting to string:
int[] splitNumber(int value)
{
Stack<int> q = new Stack<int>();
do
{
q.Push(value%1000);
value /= 1000;
} while (value>0);
return q.ToArray();
}
This is simple integer arithmetic; first take the modulo to get the right-most decimals, then divide to throw away the decimals you already added. I used the Stack to avoid reversing a list.
Edit: Using log to get the length was suggested in the comments. It could make for slightly shorter code, but in my opinion it is not better code, because the intent is less clear when reading it. Also, it might be less performant due to the extra Math function calls. Anyways; here it is:
int[] splitNumber(int value)
{
int length = (int) (1 + Math.Log(value, 1000));
var result = from n in Enumerable.Range(1,length)
select ((int)(value / Math.Pow(1000,length-n))) % 1000;
return result.ToArray();
}
By converting into a string and then into int array
int number = 1000000;
string parts = number.ToString("N0", new NumberFormatInfo()
{
NumberGroupSizes = new[] { 3 },
NumberGroupSeparator = "."
});
By using Maths,
public static int[] splitNumberIntoGroupOfDigits(int number)
{
var numberOfDigits = Math.Floor(Math.Log10(number) + 1); // compute number of digits
var intArray = new int[Convert.ToInt32(numberOfDigits / 3)]; // we know the size of array
var lastIndex = intArray.Length -1; // start filling array from the end
while (number != 0)
{
var lastSet = number % 1000;
number = number / 1000;
if (lastSet == 0)
{
intArray[lastIndex] = 0; // set of zeros
--lastIndex;
}
else if (number == 0)
{
intArray[lastIndex] = lastSet; // this could be your last set
--lastIndex;
}
else
{
intArray[lastIndex] = lastSet;
--lastIndex;
}
}
return intArray;
}
Try converting it to string first and do the parsing then convert it back to number again
Convert to string
Get length
If length modulus 3 == 0
String substring it into ints every 3
else if
Find remainder such as one or two left over
Substring remainder off of front of string
Then substring by 3 for the rest
You can first find out how large the number is, then use division to get the first digits, and modulo to keep the rest:
int number = 12345678;
int len = 1;
int div = 1;
while (number >= div * 1000) {
len++;
div *= 1000;
}
int[] result = new int[len];
for (int i = 0; i < result.Length; i++) {
result[i] = number / div;
number %= div;
div /= 1000;
}
You can use this with the System.Linq namespace from .NET 3.5 and above:
int[] splitNumber(long value)
{
LinkedList<int> results = new LinkedList<int>();
do
{
int current = (int) (value % 1000);
results.AddFirst(current);
value /= 1000;
} while (value > 0);
return results.ToArray();// Extension method
}
I use LinkedList<int> to avoid having to Reverse a list before returning. You could also use Stack<int> for the same purpose, which would only require .NET 2.0:
int[] splitNumber(long value)
{
Stack<int> results = new Stack<int>();
do
{
int current = (int) (value % 1000);
results.Push(current);
value /= 1000;
} while (value > 0);
return results.ToArray();
}

Get the seventh digit from an integer

I have a integer of 10 digits. I need to get the 7th digit of that integer.
I have found a mathematical solution to get the first digit of an integer.
var myDigit = 2345346792;
var firstDigit = Math.Abs(myDigit);
while (firstDigit >= 10)
{
firstDigit /= 10;
}
How can I get the seventh digit from myDigit? I am trying to avoid casting to string and doing a substring. I would like to see the mathemathical version of getting the seventh digit.
Anyone?
var seventh_digit = ( myDigit/1000000 ) % 10;
int getSeventhDigit(int number)
{
while(number >= 10000000)
number /= 10;
return number % 10;
}
This will take the last digit of numbers with 7 or less digits.
For numbers with 8 or more digits, it will divide by 10 until the number is 7 digits long, then take the last digit.
Mathematical solution without while loops:
int myDigit = 2345346792;
var seventh = (myDigit / 1000000) % 10;
//result should be 5, your seventh digit from the right
More generally, you can create a (zero-based) array from the digits:
uint myDigit = 2345346792;
int[] digits = new int[10];
for (int i = 9; i >= 0; i--)
{
digits[i] = (int)(myDigit % 10);
myDigit /= 10;
}
That should be useful for whatever manipulation you wish to do.
var nthDigit = (int)((number / Math.Pow(10, nth - 1)) % 10);
Where nth is n-th digit of the number.
Assuming that the "zeroth digit" is the least significant digit, this should do you:
public static int nthDigit( int value , int n )
{
if ( n < 0 ) throw new ArgumentException();
if ( value < 0 ) throw new ArgumentException() ;
while ( n-- > 0 )
{
value /= 10 ;
}
int digit = value % 10 ;
return digit ;
}
Something like this (C code, but should be readily portable):
if (n < 1000000)
return 0; // no 7th digit
while (n > 9999999)
n /= 10; // now in the range [1,000,000..9,999,999]
return n % 10;
This may seem outdated, but I wanted to get specific digits from a string of numbers and most of these solutions (and others I found) were lacking. So...I decided a workaround and converted the number to a string and then pulled the characters of the string, converting them back to an int. I know this isn't very efficient, but for small projects I don't concern myself with efficiency.
For my task, I was specifically working with phone numbers, so here is my code:
long number = 5559876543;
string s = "" + number;
int areaCode = int.Parse(s.Substring(0, 3));
int prefix = int.Parse(s.Substring(3, 3));
int suffix = int.Parse(s.Substring(6, 4));
I hope this helps anyone looking for a similar solution.
public static int GetNthDigit(this int value, int digits)
{
double mult = Math.Pow(10.0, digits);
if (value >= mult)
{
while(value >= mult)
value /= 10;
return value % 10;
}
else
{
throw new ArgumentOutOfRangeException("Digits greater than value");
}
}

Solving Mathematical logics, placing digits in third number from digits of first and second number

I have two numbers.
First Number is 2875 &
Second Number is 852145
Now I need a program which create third number.
Third Number will be 2885725145
The logic is
First digit of third number is first digit of first number.
Second digit of third number is first digit of second number.
Third digit of third number is second digit of first number.
Fourth digit of third number is second digit of second number;
so on.
If any number has remaining digits then that should be appended at last.
I do not want to convert int to string.
int CreateThirdNumber(int firstNumber, int secondNumber)
{
}
So can anyone suggest me any solution to this problem?
I do not want to convert int to string.
Why?
Without converting to string
Use Modulus and Division operator.
With converting to string
Convert them to string. Use .Substring() to extract and append value in a string. Convert appended string to integer.
Here's a bit that will give you a lead:
Say you have the number 2875. First, you need to determine it's length, and then, extract the first digit
This can be easily calculated:
int iNumber = 2875;
int i = 10;
int iLength = 0;
while (iNumber % i <= iNumber){
iLength++;
i *= 10;
}
// iNumber is of length iLength, now get the first digit,
// using the fact that the division operator floors the result
int iDigit = iNumber / pow(10, iLength-1);
// Thats it!
First a little advice: if you use int in C#, then the value in your example (2885725145) is bigger than int.MaxValue; (so in this case you should use long instead of int).
Anyway here is the code for your example, without strings.
int i1 = 2875;
int i2 = 852145;
int i3 = 0;
int i1len = (int)Math.Log10(i1) + 1;
int i2len = (int)Math.Log10(i2) + 1;
i3 = Math.Max(i1, i2) % (int)Math.Pow(10, Math.Max(i1len, i2len) - Math.Min(i1len, i2len));
int difference = (i1len - i2len);
if (difference > 0)
i1 /= (int)Math.Pow(10, difference);
else
i2 /= (int)Math.Pow(10, -difference);
for (int i = 0; i < Math.Min(i1len, i2len); i++)
{
i3 += (i2 % 10) * (int)Math.Pow(10, Math.Max(i1len, i2len) - Math.Min(i1len, i2len) + i * 2);
i3 += (i1 % 10) * (int)Math.Pow(10, Math.Max(i1len, i2len) - Math.Min(i1len, i2len) + i * 2 + 1);
i1 /= 10;
i2 /= 10;
}
I don't understand why you don't want to use strings (is it homework?). Anyway this is another possible solution:
long CreateThirdNumber(long firstNumber, long secondNumber)
{
long firstN = firstNumber;
long secondN = secondNumber;
long len1 = (long)Math.Truncate(Math.Log10(firstNumber));
long len2 = (long)Math.Truncate(Math.Log10(secondNumber));
long maxLen = Math.Max(len1, len2);
long result = 0;
long curPow = len1 + len2 + 1;
for (int i = 0; i <= maxLen; i++)
{
if (len1 >= i)
{
long tenPwf = (long)Math.Pow(10, len1 - i);
long firstD = firstN / tenPwf;
firstN = firstN % tenPwf;
result = result + firstD * (long)Math.Pow(10, curPow--);
}
if (len2 >= i)
{
long tenPws = (long)Math.Pow(10, len2 - i);
long secondD = secondN / tenPws;
result = result + secondD * (long)Math.Pow(10, curPow--);
secondN = secondN % tenPws;
}
}
return result;
}
This solves it:
#include <stdio.h>
int main(void)
{
int first = 2875,second = 852145;
unsigned int third =0;
int deci,evenodd ,tmp ,f_dec,s_dec;
f_dec = s_dec =1;
while(first/f_dec != 0 || second/s_dec != 0) {
if(first/f_dec != 0) {
f_dec *=10;
}
if( second/s_dec != 0) {
s_dec *= 10;
}
}
s_dec /=10; f_dec/=10;
deci = s_dec*f_dec*10;
evenodd =0;tmp =0;
while(f_dec != 0 || s_dec !=0 ) {
if(evenodd%2 == 0 && f_dec !=0 ) {
tmp = (first/f_dec);
first -=(tmp*f_dec);
tmp*=deci;
third+=tmp;
f_dec/=10;
deci/=10;
}
if(evenodd%2 != 0 && s_dec != 0) {
tmp= (second/s_dec);
second -=(tmp*s_dec);
//printf("tmp:%d\n",tmp);
tmp*=deci;
third += tmp;
s_dec/=10;
deci/=10;
}
evenodd++;
}
printf("third:%u\ncorrct2885725145\n",third);
return 0;
}
output:
third:2885725145
corrct2885725145
#include <stdio.h>
long long int CreateThirdNumber(int firstNumber, int secondNumber){
char first[11],second[11],third[21];
char *p1=first, *p2=second, *p3=third;
long long int ret;
sprintf(first, "%d", firstNumber);
sprintf(second, "%d", secondNumber);
while(1){
if(*p1)
*p3++=*p1++;
if(*p2)
*p3++=*p2++;
if(*p1 == '\0' && *p2 == '\0')
break;
}
*p3='\0';
sscanf(third, "%lld", &ret);
return ret;
}
int main(){
int first = 2875;
int second = 852145;
long long int third;
third = CreateThirdNumber(first, second);
printf("%lld\n", third);
return 0;
}

Categories

Resources