Add up al numbers in a string C# - 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?

Related

Using specific array count

My array max size is 20. If I were to enter data that would be less than 20,how do I get it where my program only counts the used arrays?
for (int i = 0; i < Score.Length; i++)
{
sum = sum + Score[i];
}
average = sum / Score.Length;
If I use this for loop above, it always divides by 20 for the average. I need it to only count the ones I entered, not 20. I would prefer solutions using arrays
If you insist in using arrays, then you must keep track of how many items you added to the array, like:
int[] Score = new int[20];
Random rdn = new Random();
int size=0;
for(int i=0;i<rdn.Next(0,20);i++)
{
Score[i] = rdn.Next();
size++;
}
int sum = 0;
for (int i = 0; i < size; i++)
{
sum = sum + Score[i];
}
double average = sum / size;
A better option is to use the List class that keep track for you of the number of items you add
List<int> Score = new List<int>();
Random rdn = new Random();
for(int i=0;i<rdn.Next(0,20);i++)
{
Score.Add(rdn.Next());
}
int sum = 0;
for (int i = 0; i < Score.Count; i++)
{
sum = sum + Score[i];
}
double average = sum / Score.Count;
And of course, as you didn't say the type of your data you could use other data types, like double, float, long, decimal for both solutions.
That is probably an overkill, but another approach would be to use a SparseVector class of the Math.Numerics package:
Sparse Vector uses two arrays which are usually much shorter than the vector. One array stores all values that are not zero, the other stores their indices.
PM > Install-Package MathNet.Numerics
var vector = SparseVector.Build.SparseOfArray(Score);
var sum = vector.Sum();
Sum() will only go through non-empty elements.
You need to keep track of the record that are != 0, so
int count = 0;
for(int i = 0; i < array.Length; i++)
{
if ( array[i] != 0 )
{
count++;
sum += array[i];
}
}
average = sum / count;
And beware of division by 0 ;)

Incorrect values when converting char digits to int

My end goal is to take a number like 29, pull it apart and then add the two integers that result. So, if the number is 29, for example, the answer would be 2 + 9 = 11.
When I'm debugging, I can see that those values are being held, but it appears that other values are also being incorrect in this case 50, 57. So, my answer is 107. I have no idea where these values are coming from and I don't know where to begin to fix it.
My code is:
class Program
{
static void Main(string[] args)
{
int a = 29;
int answer = addTwoDigits(a);
Console.ReadLine();
}
public static int addTwoDigits(int n)
{
string number = n.ToString();
char[] a = number.ToCharArray();
int total = 0;
for (int i = 0; i < a.Length; i++)
{
total = total + a[i];
}
return total;
}
}
As mentioned the issue with your code is that characters have a ASCII code value when you cast to int which doesn't match with the various numerical digits. Instead of messing with strings and characters just use good old math instead.
public static int AddDigits(int n)
{
int total = 0;
while(n>0)
{
total += n % 10;
n /= 10;
}
return total;
}
Modulo by 10 will result in the least significant digit and because integer division truncates n /= 10 will truncate the least significant digit and eventually become 0 when you run out of digits.
Your code is actually additioning the decimal value of the char.
Take a look at https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html
Decimal value of 2 and 9 are 50 and 57 respectively. You need to convert the char into a int before doing your addition.
int val = (int)Char.GetNumericValue(a[i]);
Try this:
public static int addTwoDigits(int n)
{
string number = n.ToString();
char[] a = number.ToCharArray();
int total = 0;
for (int i = 0; i < a.Length; i++)
{
total = total + (int)Char.GetNumericValue(a[i]);
}
return total;
}
Converted number to char always returns ASCII code.. So you can use GetNumericValue() method for getting value instead of ASCII code
Just for fun, I thought I'd see if I could do it in one line using LINQ and here it is:
public static int AddWithLinq(int n)
{
return n.ToString().Aggregate(0, (total, c) => total + int.Parse(c.ToString()));
}
I don't think it would be particularly "clean" code, but it may be educational at best!
You should you int.TryParse
int num;
if (int.TryParse(a[i].ToString(), out num))
{
total += num;
}
Your problem is that you're adding char values. Remember that the char is an integer value that represents a character in ASCII. When you are adding a[i] to total value, you're adding the int value that represents that char, the compiler automatic cast it.
The problem is in this code line:
total = total + a[i];
The code above is equal to this code line:
total += (int)a[i];
// If a[i] = '2', the character value of the ASCII table is 50.
// Then, (int)a[i] = 50.
To solve your problem, you must change that line by this:
total = (int)Char.GetNumericValue(a[i]);
// If a[i] = '2'.
// Then, (int)Char.GetNumericValue(int)a[i] = 2.
You can see this answer to see how to convert a numeric value
from char to int.
At this page you can see the ASCII table of values.
public static int addTwoDigits(int n)
{
string number = n.ToString()
char[] a = number.ToCharArray();
int total = 0;
for (int i = 0; i < a.Length; i++)
{
total += Convert.ToInt32(number[i].ToString());
}
return total;
}
You don't need to convert the number to a string to find the digits. #juharr already explained how you can calculate the digits and the total in a loop. The following is a recursive version :
int addDigit(int total,int n)
{
return (n<10) ? total + n
: addDigit(total += n % 10,n /= 10);
}
Which can be called with addDigit(0,234233433)and returns 27. If n is less than 10, we are counting the last digit. Otherwise extract the digit and add it to the total then divide by 10 and repeat.
One could get clever and use currying to get rid of the initial total :
int addDigits(int i)=>addDigit(0,i);
addDigits(234233433) also returns 27;
If the number is already a string, one could take advantage of the fact that a string can be treated as a Char array, and chars can be converted to ints implicitly :
var total = "234233433".Sum(c=>c-'0');
This can handle arbitrarily large strings, as long as the total doesn't exceed int.MaxValue, eg:
"99999999999999999999".Sum(x=>x-'0'); // 20 9s returns 180
Unless the number is already in string form though, this isn't efficient nor does it verify that the contents are an actual number.

Minimum funcion doesn't work as it should

I've written this code with Visual studio c# WindowsForms but it doesn't work as it should.
On my Form1:
private void btnVisualizzaPrezzoMin_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
int i = 0;
while (i < num)
{
if (eleMutui[i].Durata <= int.Parse(txtDurata2.Text) && eleMutui[i].Durata >= int.Parse(txtDurata1.Text))
{
int Min = Funzioni.ImportoMin(eleMutui, num);
ListViewItem Nuovariga = default(ListViewItem);
Nuovariga = new ListViewItem(new string[] {
eleMutui[Min].Codice.ToString(),
eleMutui[Min].Nome,
eleMutui[Min].Provincia,
eleMutui[Min].DataPartenza.ToString(),
eleMutui[Min].Importo.ToString(),
eleMutui[Min].Durata.ToString()
});
listView1.Items.Add(Nuovariga);
}
i++;
}
And the Minimum funcion is:
public static int ImportoMin(Mutui[] ele, int n)
{
int x = 0;
decimal MinimoImporto = default(int);
while (x < n)
{
if (ele[x].Importo < MinimoImporto)
{
MinimoImporto = ele[x].Importo;
}
x++;
}
return decimal.ToInt32(MinimoImporto);
}
Can you help me? I have to do: given by the user a duration interval (ex. between 60 and 120 months), display all the data of the
loan of a lower amount that has a duration in the indicated range.
Thank you!!
It's hard to understand why you use n in ImportoMin(), when you are basically just looping though the []. (That is if n is supposed to be the length of the [], but I don't see where num is declared.)
To continue with your format, you can do something like this:
public static int ImportoMin(Mutui[] ele)
{
decimal MinimoImporto = int.MaxValue;
for(int x = 0; x < ele.length; x++)
{
if (ele[x].Importo < MinimoImporto)
{
MinimoImporto = ele[x].Importo;
}
}
return decimal.ToInt32(MinimoImporto);
}
The issue with your method is that you initialize the min value to zero. Meaning that if all the values in the array are greater than zero then it's going to return zero instead of the actual min. The second issue is that you seem to want the index of the minimum value but you don't keep track of the index and instead return either 0 or the actual min in the array when it's negative (if that's possible). One option is to use MoreLinq's MinBy instead.
var itemWithMinImporto = eleMutui.MinBy(x => x.Importto);
Or you can do that with Linq
var itemWithMinImporto = eleMutui.OrderBy(x=>x.Importto).FirstOrDefault();
Or you can find the index with a normal for loop
int minIndex = -1;
decimal minValue = decimal.MaxValue;
for(int i = 0; i < eleMutui.Length; i++)
{
if(item[i].Importto < minValue)
{
minValue = item[i].Importto;
minIndex = i;
}
}
return minIndex;
Note that it's not clear if n is the actual length of the array or not. If not the above code can be altered to take that into account by using Take(n) for the MoreLinq and Linq solutions or just doing i < n in the for loop.
In your function ImportoMin, instead of using a while loop, you should probably do a for loop instead.
public static int ImportoMin(Mutui[] ele)
{
// I'd return -1 or something to indicate something is wrong
if(ele.Count == 0) return -1;
decimal MinimoImporto = int.MaxValue;
for(int i = 1; i < ele.Length; i++)
{
if( ele[i].Importo < MinimoImporto)
MinimoImporto = ele[i].Importo;
}
return MinimoImporto;
}
In your funciton, you initialize your min to be zero and unless everything else is negative, it will return zero every time.
Edit: This function will return the minimum value in the array, however you can refer to juharr's answer if you're looking for the index.

c# - Binary search algorithm random generated array items not working

I have implemented binary search algorithm in a console window application in C#. I am generating random values to the array and sorting them using Random() and Array.Sort() functions respectively.
The Problem - No matter what Key(item to be searched in the array) I give, the program is returning Key not found when the array items are generated using Random function
This does not happen if I enter the array elements manually using Console.ReadLine().
TLDR: Binary Search algorithm works fine when array items are entered manually, but does not work when array items are generated using Random function.
Can anyone point out what is the mistake I am doing?
My code - Random Generated array items.
namespace BSA
{
class Program
{
static void Main(string[] args)
{
var arr = new int[10];
Random rnd = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = rnd.Next(1, 1000);
}
Array.Sort(arr);
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", i);
}
while (true)
{
Console.WriteLine("Enter the number to be searched in the array.");
var searchItem = Convert.ToInt32(Console.ReadLine());
var foundPos = Search(arr, searchItem);
if (foundPos > 0)
{
Console.WriteLine("Key {0} found at position {1}", searchItem, foundPos);
}
else
{
Console.WriteLine("Key {0} not found", searchItem);
}
}
}
public static int Search(int[] arr, int item)
{
var min = 0;
var N = arr.Length;
var max = N - 1;
int basicOperations = 0;
basicOperations++;
do
{
var mid = (min + max)/2;
if (arr[mid] == item)
return mid;
if (item < arr[mid])
max = mid - 1;
else
min = mid + 1;
basicOperations++;
} while (min <= max);
return basicOperations;
}
}
}
Please let me know if I am doing any silly mistake or I am committing a blunder in the above code. Any help would be really helpful.
Your search code works fine as far as I can see. However when you list the contents of the random array, you should write arr[i] rather than i to see what's in the array so you can pick a search value in it. Alternatively, pass arr[x] as the search item. It should return x.
Your code works correctly. You're just not looking for the right keys. The function that prints the values generated into the array prints the loop counter instead:
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", i);
}
You need to change it to:
for (int i = 0; i < arr.Length; i++)
{
Console.Write("{0}\n", arr[i]);
}
This will show you the values actually generated.
Comment too short for this so added answer to show how to set basicOperations and still return search position. You declare basicOperations as an out parameter which means the method can change it so the caller can see it when method returns.
public static void Main(string[] args)
{
... ... ...
int basicOperations;
int searchPos = IntArrayBinarySearch(arr, arr[5], out basicOperations);
Console.WriteLine("Found at {0} basic ops={1}", searchPos, basicOperations);
}
public static int IntArrayBinarySearch(int[] data, int item, out int basicOperations)
{
var min = 0;
var N = data.Length;
var max = N - 1;
basicOperations = 0;
basicOperations++;
and at bottom, you don't need to return out parameters, just return -1 to indicate failure as you did before
return -1;

Get number inside of a string and do a loop

I want to get a number of a string, and separate the string and the number, and then, do a loop and call a method the number of times the string says.
The string has to have this structure: "ABJ3" (Only one number accepted and 3 characters before it)
This is my code, but it repeat hundred of times, I don't know why
int veces = 0;
for (int i = 0; i < m.Length; i++)
{
if (Char.IsDigit(m[i]))
veces = Convert.ToInt32(m[i]);
}
if (m.Length == 4)
{
for (int i = 0; i <= veces; i++)
{
m = m.Substring(0, 3);
operaciones(m, u, t);
Thread.Sleep(100);
}
}
operaciones(m,u,t);
if (u.Length >= 14)
{
u = u.Substring(0, 15);
}
Some help please?
You have to convert your m[i] ToString() right now you are sending the char value to Convert.ToInt32 and that is a much higher value (9 = 57 for example)
char t = '9';
int te = Convert.ToInt32(t.ToString());
Console.WriteLine(te);
This gives us a result of 9 but
char t = '9';
int te = Convert.ToInt32(t);
Console.WriteLine(te);
Gives us a result of 57
So you need to change
veces = Convert.ToInt32(m[i]);
to
veces = Convert.ToInt32(m[i].ToString());
Hope it helped.
Best regards //KH.
You cannot convert the digits like this. You're overwriting them and taking only the last one. Moreover, you're taking its ASCII code, not digit value. You have to extract all digits first then convert them:
int position = 0;
int veces = 0;
string temp = ""
for (int i = 0; i < m.Length; i++) {
if (Char.IsDigit(m[i]))
position = i;
else
break;
}
veces = Convert.ToInt32(m.SubString(0, i + 1));
Alternatively, you can use regex instead.

Categories

Resources