Добавление цифр в четных и нечетных местах (C #) - PullRequest
5 голосов
/ 24 августа 2009

Мне нужно добавить цифры в четных и нечетных местах в целое число. Сказать, Пусть number = 1234567. Сумма четных цифр = 2+4+6 = 12 Сумма нечетных разрядов = 1+3+5+7 = 16

Подождите, не спешите с ответом!

Я ищу коды с минимальными строками, желательно однострочные. Аналогично тому, что 'chaowman' разместил в теме Сумма цифр в C # .

Есть ли у кого-нибудь классные коды. Спасибо.

Ответы [ 13 ]

9 голосов
/ 24 августа 2009
    bool odd = false;

    int oddSum = 1234567.ToString().Sum(c => (odd = !odd) ? c - '0' : 0 );

    odd = false;

    int evenSum = 1234567.ToString().Sum(c => (odd = !odd) ? 0 : c - '0' );
2 голосов
/ 24 августа 2009
"1234567".Where((ch, i) => i % 2 == 0).Sum(ch => ch - '0')
2 голосов
/ 24 августа 2009

Если вам понравилось решение chaowmans для другого вопроса, это было бы логическим продолжением четных / нечетных чисел:

int even = 17463.ToString().Where((c, i) => i%2==1).Sum(c => c - '0');
int odd  = 17463.ToString().Where((c, i) => i%2==0).Sum(c => c - '0');

Хотя цикл может быть проще и эффективнее:

for (odd = even = 0; n != 0; n /= 10) {
  tmp = odd;
  odd = even*10 + n%10;
  even = tmp;
}

И это тоже не очень долго и не сложнее. Обе версии определяют «странность» слева от числа.

2 голосов
/ 24 августа 2009

Это не однострочник, но работает следующее:

int oddSum = 0, evenSum = 0;
bool odd = true;
while (n != 0) {
    if (odd)  
        oddSum += n % 10;
    else
        evenSum += n % 10;
    n /= 10;
    odd = !odd;
}

РЕДАКТИРОВАТЬ:

Если вы хотите в одну строку:

int oddSum = 0, evenSum = 0; bool odd = true; while (n != 0) { if (odd) oddSum += n % 10; else evenSum += n % 10; n /= 10; odd = !odd; }
1 голос
/ 24 августа 2009

Вот мой однолинейный лайнер, использующий LINQ, который (a) вычисляет нечетные и четные суммы в одной строке, (b) не преобразовывает исходное число промежуточный string и (c) не имеют побочных эффектов:

var totals = Enumerable.Range(0, 10)
    .Select(x => (number / (int)Math.Pow(10, x)) % 10)
    .Where(x => x > 0)
    .Reverse()
    .Select((x, i) => new { Even = x * (i % 2), Odd = x * ((i + 1) % 2) })
    .Aggregate((a, x) => new { Even = a.Even + x.Even, Odd = a.Odd + x.Odd });

Console.WriteLine(number);         // 1234567
Console.WriteLine(totals.Even);    // 12
Console.WriteLine(totals.Odd);     // 16

(Приведенный выше код подсчитывает нечетные / четные позиции слева направо. Для подсчета справа налево вместо этого просто удалите вызов Reverse. Вычисления из L-to-R дадут результаты, отличные от R-to-L, когда number имеет четное число цифр.)

1 голос
/ 24 августа 2009

версия Рубена с измененной логикой группировки:

bool isOdd = false; 
var sums = 1234567
    .ToString()
    .Select(x => Char.GetNumericValue(x))
    .GroupBy(x => isOdd = !isOdd)
    .Select(x => new { IsOdd = x.Key, Sum = x.Sum() });

foreach (var x in sums)
    Console.WriteLine("Sum of {0} is {1}", x.IsOdd ? "odd" : "even", x.Sum);
1 голос
/ 24 августа 2009

Если вы ищете неизбежную глупую версию трюков LINQ, вот одна из них:

var result = 1234567
    .ToString()
    .Select((c, index) => new { IndexIsOdd = index % 2 == 1, ValueOfDigit = Char.GetNumericValue(c) })
    .GroupBy(d => d.IndexIsOdd)
    .Select(g => new { OddColumns = g.Key, sum = g.Sum(item => item.ValueOfDigit) });
foreach( var r in result )
    Console.WriteLine(r);

Я уверен, что кто-то скучно может преобразовать его в однострочник (и удалить преобразование его в строку как способ генерации цифр).

РЕДАКТИРОВАТЬ: Использование кортежей, чтобы сделать его короче (но более запутанным)

var result = 1234567
    .ToString()
    .Select((c, index) => Tuple.Create( index % 2 == 1, Char.GetNumericValue(c))
    .GroupBy(d=>d.Item1)
    .Select(g => new { OddColumns = g.Key, Sum = g.Sum(item => item.Item2) });
foreach( var r in result )
    Console.WriteLine(r);
0 голосов
/ 24 августа 2009

Это работает без LINQ.

var r = new int[]{0,0}; for (int i=0; i<7; i++) r[i%2]+="1234567"[i]-48;
System.Console.WriteLine("{0} {1}",r[0],r[1]);
0 голосов
/ 24 августа 2009

Это работает, если вы начинаете справа. По крайней мере, это работает в C ++. Я не знаю C #, как я уже сказал. Я надеюсь, что они убрали эту чепуху в C #.

Это не однострочник, а одно утверждение, если вы игнорируете декларацию (которую я считаю справедливой):

int oddSum, evenSum;
for(bool odd = ((oddSum = evenSum = 0) == 0);
    n != 0;
    odd = (!odd || (n /= 10) == n + (oddSum += (odd ? n % 10 : 0) - evenSum + (evenSum += (!odd ? n % 10 : 0)))))
;

В качестве дополнительной награды приведем однострочный скрипт на Python, который превратит все ваши решения на C # в однострочные.

one_liner.py
open(__import__('sys').argv[2]','w').write(open(__import__('sys').argv[1],'r').read().replace('\n',''))

Использование:

python one_liner.py infile outfile
0 голосов
/ 24 августа 2009
int n = 1234567;
int[] c = new int[2];
int p = 0;
n.ToString().Select(ch => (int)ch - '0').ToList().ForEach(d => { c[p] += d; p ^= 1; });
Console.WriteLine("even sum = {0}, odd sum = {1}", c[0], c[1]);

Короче:

int n = 1234567, p = 0;
int[] c = new int[2];
while (n > 0) { c[p] += n % 10; n /= 10;  p ^= 1; };
Console.WriteLine("even sum = {0}, odd sum = {1}", c[p ^ 1], c[p]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...