Collect the digits numbers in the decimal number C# - c#

I want a method to remove the comma from the decimal number and then collect the digits. For example, if the user inputs 1,3 it will remove the comma and collect 1 and 3 together. I mean 1+3 =4. Can I use trim or replace?
public int AddSum(string x1)
{
string x = x1.Trim();
int n = Convert.ToInt32(x);
return n;
}

public int AddSum(string x1)
{
var digitFilter = new Regex(#"[^\d]");
return digitFilter.Replace(x1, "").Select(c => int.Parse(c)).Sum();
}
OR
public int AddSum(string x1)
{
return x1.Where(c => char.IsDigit(c)).Select(c => c - '0').Sum();
}

If you want to iterate over the characters in a string and compute the sum of digits contained therein, it's trivial:
public static int SumOfDigits( string s ) {
int n = 0;
foreach ( char c in s ) {
n += c >= '0' && c <= '9' // if the character is a decimal digit
? c - '0' // - convert to its numeric value
: 0 // - otherwise, default to zero
; // and add that to 'n'
}
return n;
}

It sounds like you want take a comma-separated string of numbers, add the numbers together, then return the result.
The first thing you have to do is use the Split() method on the input string. The Split() method takes an input string splits the string into an array of strings based on a character:
string[] numbers = x1.Split(',');
So now we have an array of strings called numbers that hold each number. The next thing you have to do is create an empty variable to hold the running total:
int total = 0;
The next thing is to create a loop that will iterate through the numbers array and each time, add the number to the running total. Remember that numbers is an array of strings and not numbers. so we must use the Parse() method of int to convert the string to a number:
foreach (string number in numbers)
{
total += int.Parse(number);
}
Finally, just return the result:
return total;
Put it all together and you got this:
private static int AddSum(string x1)
{
string[] numbers = x1.Split(',');
int total = 0;
foreach (string number in numbers)
{
total += int.Parse(number);
}
return total;
}
I hope this helps and clarifies things. Keep in mind that this method doesn't do any kind of error checking, so if your input is bad, you'll get an exception probably.

Related

Getting the sum of all numbers in a character array

I have converted string to char[], but now when I try to get a total of all the numbers in the array, I get a wrong output. The goal is that if the user enters a number as a string e.g - 12, the output should be 3 i.e 1 + 2, another example - 123 should be 1+2+3 = 6.
I am new to coding. My apologies for any inconvienence.
static void Main(string[] args)
{
int sum = 0;
String num = Console.ReadLine();
char[] sep = num.ToCharArray();
for (int i = 0; i < sep.Length; i++)
{
sum += (sep[i]);
}
Console.WriteLine(sum);
Console.ReadLine();
}
You are currently adding ascii values. The ascii value of 1 is 49 and that of 2 Is 50... You need to use int.TryParse to convert from char to int.
int value;
for (int i = 0; i < sep.Length; i++)
{
if (int.TryParse (sep[i].ToString(),out value))
sum += value;
}
If you want to calculate sum of digits, you need to convert each char to int first. Char needs to be converted to string and then parsed into int. Your original code contains implicit conversion, which converts 1 and 2 into 49 and 50 (ASCII), thus the sum ends up being 99.
Try this code instead:
static void Main(string[] args)
{
int sum = 0;
String num = Console.ReadLine();
char[] sep = num.ToCharArray();
for (int i = 0; i < sep.Length; i++)
{
sum += int.Parse(sep[i].ToString());
}
Console.WriteLine(sum);
Console.ReadLine();
}
Just for fun here is a LINQ solution.
var sum = num.Select( c => int.Parse((string)c) ).Sum();
This solution takes advantage of the fact that a string is also an IEnumerable<char> and therefore can be treated as a list of characters.
The Select statement iterates over the characters and converts each one to an integer by supplying a lambda expression (that's the => stuff) that maps each character onto its integer equivalent. The symbol is typically prounced "goes to". You might pronounce the whole expression "C goes to whatever integer can be parsed from it."
Then we call Sum() to convert the resulting list of integers into a numeric sum.

C# - Class that uses ILists to store huge integers without BigInt. Can't figure out how to use CompareTo and Int.TryParse to +, -, and * two Lists

I've been working on an assignment and I'm a beginner to C#. I have to implement a program that's similar to what BigInt can do: perform addition, subtraction, or multiplication with two absurdly large values (without actually using the BigInt library). I was told to use CompareTo and that it would make creating the add, subtract, and multiply methods easy, but I have no clue how to implement CompareTo. I don't even know if my class is implemented correctly or if I am missing something important.
Here is my code:
public class HugeInt
{
char sign;
public IList<int> theInt = new List<int>();
public string ToString(IList<int> theInt)
{
string bigInt = theInt.ToString();
return bigInt;
}
public HugeInt CompareTo(HugeInt num1)
{
int numParse;
string number = ToString(theInt); /// I did this to convert the List into a string
for(int i = 0; i < number.Length; i++)
{
bool temp = Int32.TryParse(number, out numParse); /// Supposed to change each index of the string to a separate integer (not sure how to properly do this)
/// These are *supposed to* perform operations on two HugeInts ///
num1.plus(numParse, num1);
num1.minus(numParse, num1);
num1.times(numParse, num1);
}
return num1;
}
I'm not here to ask for all the answers for this assignment, I've just been working on this for hours now and can't figure out what I'm doing wrong -- I have already done a lot of google searching. Thanks in advance for all advice and help!
To write such a class, it requires you know a little bit about how to do math by hand. For example, when adding two numbers, you start by adding their least significant digits. If the result is greater than 9, you have to carry a 1 to the next digit (explanation). Then you continue to the next digit.
Now, here is my take on it. I want to save the "huge int" as a list of digits starting from the least significant digit. Then I implement the Plus method as described above. I can compare two "huge ints" by looking at the number of digits. The number with the most digits is the largest. In the case the number of digits are the same, I will need to compare each digit one-by-one, starting from the most significant digit.
The below is just something to get you started. It only handles positive integers and has Plus and CompareTo methods. Be aware there are plenty of corner cases that I have not taken care of.
It can be used like this:
var num1 = new HugeInt("11112222333399998888777123123");
var num2 = new HugeInt("00194257297549");
Console.WriteLine(num1.Plus(num2).ToString()); // Writes 11112222333399999083034420672
Console.WriteLine(num1.CompareTo(num2)); // Writes -1 since num1 > num2
Here is the class:
public class HugeInt
{
// The array that contains all the digits of the number. To create a new number, you do not change this array but instead you create a new instance of HugeInt.
// The first digit is the least significant digit.
private readonly int[] digits;
public HugeInt(string number)
{
// Trim off the leading zeros
number = number.TrimStart('0');
if (number == "")
number = "0";
// Convert to digit array with the least significant digit first
digits = number.ToCharArray().Select(c => int.Parse(c.ToString())).Reverse().ToArray();
}
public HugeInt(IList<int> digits)
{
// Trim off the leading zeros
var d = digits.ToList();
while (d.Count > 1 && d.Last() == 0)
d.RemoveAt(d.Count - 1);
// Convert to digit array with the least significant digit first
this.digits = d.ToArray();
}
public HugeInt Plus(HugeInt num)
{
// Add two positive integers by adding each digit together, starting with the least significant digit.
var result = new List<int>();
int carry = 0;
for (var i = 0; i < this.digits.Length || i < num.digits.Length; i++)
{
var digit1 = i < this.digits.Length ? this.digits[i] : 0;
var digit2 = i < num.digits.Length ? num.digits[i] : 0;
var digitResult = digit1 + digit2 + carry;
carry = 0;
if (digitResult >= 10)
{
digitResult -= 10;
carry = 1;
}
result.Add(digitResult);
}
if (carry > 0)
result.Add(carry);
return new HugeInt(result);
}
public int CompareTo(HugeInt num)
{
// First compare by length of number
if (this.digits.Length > num.digits.Length)
return -1;
else if (this.digits.Length < num.digits.Length)
return 1;
else
{
// If lengths are equal, then compare each digit - starting with the most significant digit.
for (var i = this.digits.Length - 1; i >= 0; i--)
{
var cmp = this.digits[i].CompareTo(num.digits[i]);
if (cmp != 0)
return cmp;
}
return 0;
}
}
public override string ToString()
{
return String.Join("", digits.Reverse());
}
}

Split string into multiple smaller strings

I have a multiline textbox that contains 10 digit mobile numbers separated by comma. I need to achieve string in group of at least 100 mobile numbers.
100 mobile numbers will be separated by 99 comma in total. What i am trying to code is to split the strings containing commas less than 100
public static IEnumerable<string> SplitByLength(this string str, int maxLength)
{
for (int index = 0; index < str.Length; index += maxLength) {
yield return str.Substring(index, Math.Min(maxLength, str.Length - index));
}
}
By using above code, I can achieve 100 numbers as 100 numbers will have 10*100(for mobile number)+99(for comma) text length. But the problem here is user may enter wrong mobile number like 9 digits or even 11 digits.
Can anyone guide me on how can I achieve this.
Thank you in advance.
You could use this extension method to put them into max-100 number groups:
public static IEnumerable<string[]> SplitByLength(this string str, string[] splitBy, StringSplitOptions options, int maxLength = int.MaxValue)
{
var allTokens = str.Split(splitBy, options);
for (int index = 0; index < allTokens.Length; index += maxLength)
{
int length = Math.Min(maxLength, allTokens.Length - index);
string[] part = new string[length];
Array.Copy(allTokens, index, part, 0, length);
yield return part;
}
}
Sample:
string text = string.Join(",", Enumerable.Range(0, 1111).Select(i => "123456789"));
var phoneNumbersIn100Groups = text.SplitByLength(new[] { "," }, StringSplitOptions.None, 100);
foreach (string[] part in phoneNumbersIn100Groups)
{
Assert.IsTrue(part.Length <= 100);
Console.WriteLine(String.Join("|", part));
}
You have a few options,
Put some kind of mask on the input data to prevent the user entering invalid data. In your UI you could then flag the error and prompt the user to reenter correct information. If you go down this route then something like this string[] nums = numbers.Split(','); will be fine.
Alternatively, you could use regex.split or regex.match and match on the pattern. Something like this should work assuming your numbers are in a string with a leading comma or space
Regex regex = new Regex("(\s|,)\d{10},)";
string[] nums = regex.Split(numbers);
This be can resolved with a simple Linq code
public static IEnumerable<string> SplitByLength(this string input, int groupSize)
{
// First split the input to the comma.
// this will give us an array of all single numbers
string[] numbers = input.Split(',');
// Now loop over this array in groupSize blocks
for (int index = 0; index < numbers.Length; index+=groupSize)
{
// Skip numbers from the starting position and
// take the following groupSize numbers,
// join them in a string comma separated and return
yield return string.Join(",", numbers.Skip(index).Take(groupSize));
}
}

Get a range from two integers

string num = db.SelectNums(id);
string[] numArr = num.Split('-').ToArray();
string num contain for an example "48030-48039";
string[] numArr will therefor contain (48030, 48039).
Now I have two elements, a high and low. I now need to get ALL the numbers from 48030 to 48039. The issue is that it has to be string since there will be telephone numbers with leading zeroes now and then.
Thats why I cannot use Enumerable.Range().ToArray() for this.
Any suggestions? The expected result should be 48030, 48031, 48032, ... , 48039
This should work with your leading zero requirement:
string num = db.SelectNums(id);
string[] split = num.Split('-');
long start = long.Parse(split[0]);
long end = long.Parse(split[1]);
bool includeLeadingZero = split[0].StartsWith("0");
List<string> results = new List<string>();
for(int i = start; i <= end; i++)
{
string result = includeLeadingZero ? "0" : "";
result += i.ToString();
results.Add(result);
}
string[] arrayResults = results.ToArray();
A few things to note:
It assumes your input will be 2 valid integers split by a single hyphen
I am giving you a string array result, personally I would prefer to work with a List<int> in the end
If the first number contains a single leading zero, then all results will contain a single leading zero
It uses long to cater for longer numbers, beware that the max number that will parse is 9,223,372,036,854,775,807, you could double this value (not length) by using ulong
Are you saying this?
int[] nums = new int[numArr.Length];
for (int i = 0; i < numArr.Length; i++)
{
nums[i] = Convert.ToInt32(numArr[i]);
}
Array.Sort(nums);
for (int n = nums[0]; n <= nums[nums.Length - 1]; n++)
{
Console.WriteLine(n);
}
here link
I am expecting your string always have valid two integers, so using Parse instead TryParse
string[] strList = "48030-48039".Split('-').ToArray();
var lst = strList.Select(int.Parse).ToList();
var min = lst.OrderBy(l => l).FirstOrDefault();
var max = lst.OrderByDescending(l => l).FirstOrDefault();
var diff = max - min;
//adding 1 here otherwise 48039 will not be there
var rng = Enumerable.Range(min,diff+1);
If you expecting invalid string
var num = 0;
var lst = (from s in strList where int.TryParse(s, out num) select num).ToList();
This is one way to do it:
public static string[] RangeTest()
{
Boolean leadingZero = false;
string num = "048030-48039"; //db.SelectNums(id);
if (num.StartsWith("0"))
leadingZero = true;
int min = int.Parse(num.Split('-').Min());
int count = int.Parse(num.Split('-').Max()) - min;
if (leadingZero)
return Enumerable.Range(min, count).Select(x => "0" + x.ToString()).ToArray();
else
return Enumerable.Range(min, count).Select(x => "" + x.ToString()).ToArray(); ;
}
You can use string.Format to ensure numbers are formatted with leading zeros. That will make the method work with arbitrary number of leading zeros.
private static string CreateRange(string num)
{
var tokens = num.Split('-').Select(s => s.Trim()).ToArray();
// use UInt64 to allow huge numbers
var start = UInt64.Parse(tokens[0]);
var end = UInt64.Parse(tokens[1]);
// if your start number is '000123', this will create
// a format string with 6 zeros ('000000')
var format = new string('0', tokens[0].Length);
// use StringBuilder to make GC happy.
// (if only there was a Enumerable.Range<ulong> overload...)
var sb = new StringBuilder();
for (var i = start; i <= end; i++)
{
// format ensures that your numbers are padded properly
sb.Append(i.ToString(format));
sb.Append(", ");
}
// trim trailing comma after the last element
if (sb.Length >= 2) sb.Length -= 2;
return sb.ToString();
}
Usage example:
// prints 0000012, 0000013, 0000014
Console.WriteLine( CreateRange("0000012-0000014") );
Three significant issues were brought up in comments:
The phone numbers have enough digits to exceed Int32.MaxValue so
converting to int isn't viable.
The phone numbers can have leading zeros (presumeably for some
international calling?)
The possible range of numbers can theoretically exceed the maximum size of an array (which may have memory issues, and I think may not be represented as a string)
As such, you may need to use long instead of int, and I would suggest using deferred execution if needed for very large ranges.
public static IEnumerable<string> EnumeratePhoneNumbers(string fromAndTo)
{
var split = fromAndTo.Split('-');
return EnumeratePhoneNumbers(split[0], split[1]);
}
public static IEnumerable<string> EnumeratePhoneNumbers(string fromString, string toString)
{
long from = long.Parse(fromString);
long to = long.Parse(toString);
int totalNumberLength = fromString.Length;
for (long phoneNumber = from; phoneNumber <= to; phoneNumber++)
{
yield return phoneNumber.ToString().PadLeft(totalNumberLength, '0');
}
}
This assumes that the padded zeros are already included in the lower bound fromString text. It will iterate and yield out numbers as you need them. This can be useful if you're churning out a lot of numbers and don't need to fill up memory with them, or if you just need the first 10 or 100. For example:
var first100Numbers =
EnumeratePhoneNumbers("0018155500-7018155510")
.Take(100)
.ToArray();
Normally that range would produce 7 billion results which cannot be stored in an array, and might run into memory issues (I'm not even sure if it can be stored in a string); by using deferred execution, you only create the 100 needed.
If you do have a small range, you can still join up your results into a string as you desired:
string numberRanges = String.Join(", ", EnumeratePhoneNumbers("0018155500-0018155510"));
And naturally you can put this array creation into your own helper method:
public static string GetPhoneNumbersListing(string fromAndTo)
{
return String.Join(", ", EnumeratePhoneNumbers("0018155500-0018155510"));
}
So your usage would be:
string numberRanges = GetPhoneNumbersListing("0018155500-0018155510");
A complete solution inspired by the answer by #Dan-o:
Inputs:
Start: 48030
End: 48039
Digits: 6
Expected String Output:
048030, 048031, 048032, 048033, 048034, 048035, 048036, 048037, 048038, 048039
Program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class Program
{
public static void Main()
{
int first = 48030;
int last = 48039;
int digits = 6;
Console.WriteLine(CreateRange(first, last, digits));
}
public static string CreateRange(int first, int last, int numDigits)
{
string separator = ", ";
var sb = new StringBuilder();
sb.Append(first.ToString().PadLeft(numDigits, '0'));
foreach (int num in Enumerable.Range(first + 1, last - first))
{
sb.Append(separator + num.ToString().PadLeft(numDigits, '0'));
}
return sb.ToString();
}
}
For Each item In Enumerable.Range(min, count).ToArray()
something = item.PadLeft(5, "0")
Next

Formatting double for showing only 4 digits

Is there a way to format a double number that always have n digits sepecified by user?
For example if user want to see always 4 digits, take the following numbers as example:
Original Formatted
------- ---------
3.42421 3.424
265.6250 265.6
812.50 812.5
12.68798 12.68
0.68787 0.687
I made up this but it just allows for number of floating points! it is not what I wanted!
public string ToEngV(double d, int percision = 0)
{
string zeros = string.Empty;
if (percision <= 0)
{
zeros += "0";
}
else if (percision > 0)
{
for (int i = 0; i < percision; i++)
{
zeros += "0";
}
}
return String.Format("{0:0." + zeros + "}", d)
}
Imagine I call the above method for a number like 812.50 and I set the precision to (this is now used for all numbers I am going to format). Obviously the output will be 812.5
But if I give the another number like 1.61826 I will get 1.6 and this ruins the formatting in the page I show these number to users. I need that to be 1.618
Thus I want my method to always show N digit!
I'm not sure if your asking to round or truncate numbers, so I wrote this method:
public static string ToEngV(this double d, int digits, bool round)
{
var lenght = Math.Truncate(d).ToString().Length;
if (lenght > digits)
{
throw new ArgumentException("...");
}
int decimals = digits - lenght;
if (round)
{
return Math.Round(d, decimals).ToString();
}
else
{
int pow = (int)Math.Pow(10, decimals);
return (Math.Truncate(d * pow) / pow).ToString();
}
}
Example:
var numbers = new double[] { 3.42421, 265.6250, 812.50, 12.68798, 0.68787 };
foreach (var number in numbers)
{
Console.WriteLine(number.ToEngV(4, false));
}
Console.WriteLine()
foreach (var number in numbers)
{
Console.WriteLine(number.ToEngV(4, true));
}
Output:
3.424
265.6
812.5
12.68
0.687
3.424
265.6
812.5
12.69
0.688
Note that if your number has more integer digits than digits you will get an ArgumentException.
number.ToString("#0.000").Substring(0, 5);
I'm not sure this is what you're searching for, anyway give it a try:
string FmtDbl(double num, int digits)
{
digits++; // To include decimal separator
string ret = num.ToString();
if (ret.Length > digits) return ret.Substring(0, digits);
else return ret + new String('0', digits - ret.Length);
}
Note that if your number has more than digits integer digits, this doesn't work...
What about something like:
d.ToString().PadRigth(4,'0').SubString(0,4);
public static void RunSnippet()
{
Console.WriteLine(myCustomFormatter(3.42421));
Console.WriteLine(myCustomFormatter(265.6250));
Console.WriteLine(myCustomFormatter(812.50));
Console.WriteLine(myCustomFormatter(12.68798));
Console.WriteLine(myCustomFormatter(0.68787));
Console.ReadLine();
}
public static double myCustomFormatter(double value)
{
string sValue = value.ToString();
string sFormattedValue = sValue.Substring(0,5);
double dFormattedValue= Convert.ToDouble(sFormattedValue);
return dFormattedValue;
}

Categories

Resources