Levin101q Ответов: 4

Может кто-нибудь объяснить мне, как я получил 5135311?


#include <stdio.h>
void main()
{
    long broj = 1123583145;
    long cif, rez = 0;
	
    while( broj )
    {
        cif = broj % 10;
	rez = ( cif & 1 ) ? rez * 10 + cif : rez;
	broj = broj / 10;			
    };
    printf( "%li", rez );
}


Что я уже пробовал:

Может кто-нибудь объяснить мне, как я получил 5135311??

0x01AA

Прежде всего: все ваши теги c# вы можете удалить. C# не принимает rez = ( cif & 1 ) ? rez * 10 + cif : rez; особенно эта часть ( cif & 1 )
Второе: Похоже, вы не знаете, что означает оператор"%"? В случае, если это правильно, google для "модуля". И еще я не уверен, что вы понимаете, что означает " ( cif & 1)?...". Для этого Гугл для "тернарного оператора"

4 Ответов

Рейтинг:
28

OriginalGriff

Потому что это то, что вы сказали компьютеру сделать.

Потому что broj % 10 дает вам наименее значимую цифру.
Он отбрасывает все четные числа: cif & 1 позаботится об этом.
Затем он перемещает каждую нечетную цифру "вверх" на одну позицию.
Это означает, что наименее значимая нечетная цифра исходного числа становится самой значимой в результате, и так далее.

Разбейте отладчик и прогоните свой код через него шаг за шагом - вы поймете, что я имею в виду.

Цитата:
Я до сих пор не понимаю, почему он удаляет все четные числа. % 10 делит 1123583145 на 10 и сохраняет остаток, который в данном случае равен 5. 5 & 1 означает истину, и это первое число, хорошо. Когда мы повторяем этот процесс, Что происходит с 4?


В принципе, вы смущены тем, что conditional operator.
Когда вы пишете
a = B ? c : d;
вы действительно пишете это в короткой форме:
if (B)
   {
   a = c;
   }
else
   {
   a = d;
   }
Итак, ваш код выглядит следующим образом:
while( broj )
    {
    cif = broj % 10;
    if (cif & 1)
       {
       rez = rez * 10 + cif;
       }
    else
       {
       rez = rez;
       }
    broj = broj / 10;
    };
Таким образом, вы можете отказаться от else часть полностью - она вообще ничего не делает - и упростите свой код до этого:
while( broj )
    {
    cif = broj % 10;
    if (cif & 1)
       {
       rez = rez * 10 + cif;
       }
    broj = broj / 10;
    };
Что гораздо более очевидно в отношении того, что происходит!
С cif & 1 это верно только в том случае, если cif это нечетное число (потому что именно так работает оператор &), вы делаете все только с нечетными цифрами, вы игнорируете четные.


Levin101q

Я до сих пор не понимаю, почему он удаляет все четные числа. % 10 делит 1123583145 на 10 и сохраняет остаток, который в данном случае равен 5. 5 & 1 означает истину, и это первое число, хорошо. Когда мы повторяем этот процесс, Что происходит с 4?

OriginalGriff

Ответ обновлен

Рейтинг:
1

Richard Deeming

Просто: вы работаете через цифры broj справа налево, и добавляя каждую нечетную цифру к rez.

Нечетные цифры числа broj являются 5, 1, 3, 5, 3, 1, и 1.

Поэтому ваш результат таков 5135311.

Если вы все еще не понимаете, используйте отладчик для пошагового просмотра кода строка за строкой и изучения переменных на каждом шаге.

Редактировать:
Компьютеры хранят номера с помощью двоичный[^].

Например:
5 (основание 10) === 0101 (основание 2)
4 (основание 10) === 0100 (основание 2)

Когда применяется к числам, то & оператор выполняет а побитовое-и[^] по номерам. Каждая пара двоичных цифр в двух операндах будет производить двоичную цифру в результате. Результирующая цифра будет равна 1 если оба входа равны 1; в противном случае результирующая цифра будет равна 0.

Так:
5 & 1 (основание 10) === 0101 & 0001 (основание 2) === 0001 (основание 2) === 1 (основание 10)
4 & 1 (основание 10) === 0100 & 0000 (основание 2) === 0000 (основание 2) === 0 (основание 10)

В двоичном коде все нечетные числа имеют самую правую цифру, равную 1, и все четные числа имеют самую правую цифру, установленную в 0.

Так (odd number) & 1 === 1, и (even number & 1) === 0.

C и C++ рассматривают ненулевые числа как TRUE, и ноль как FALSE Следовательно, в вашем троичном выражении вы оцениваете "истинную" часть, если cif это странно, и "ложная" часть, если cif ровный.


Levin101q

Я до сих пор не понимаю, почему он удаляет все четные числа. % 10 делит 1123583145 на 10 и сохраняет остаток, который в данном случае равен 5. 5 & 1 означает истину, и это первое число, хорошо. Когда мы повторяем этот процесс, Что происходит с 4?

OriginalGriff

Ответ обновлен

Richard Deeming

Вы хотели обновить мой ответ? :)

OriginalGriff

Нет, я промахнулся ... :doh:

Рейтинг:
1

Patrice T

Цитата:
Может кто-нибудь объяснить мне, как я получил 5135311??

Почему бы вам не попросить свой компьютер показать вам это с помощью отладчика ?

Ваш код ведет себя не так, как вы ожидаете, или вы не понимаете, почему !

Существует почти универсальное решение: запускайте свой код на отладчике шаг за шагом, проверяйте переменные.
Отладчик здесь, чтобы показать вам, что делает ваш код, и ваша задача-сравнить с тем, что он должен делать.
В отладчике нет никакой магии, он не знает, что должен делать ваш код, он не находит ошибок, он просто помогает вам, показывая, что происходит. Когда код не делает того, что ожидается, вы близки к ошибке.
Чтобы увидеть, что делает ваш код: просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик - Википедия, свободная энциклопедия[^]

Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
Базовая отладка с помощью Visual Studio 2010 - YouTube[^]

Отладка кода C# в Visual Studio - YouTube[^]

1.11 — отладка программы (пошаговое выполнение и останова) | выучить C++[^]

Отладчик здесь только для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.


0x01AA

Извини, но тот, у кого был один, был я. Я думаю, что ваше "решение" в данном случае совершенно неуместно.

Patrice T

Привет,
Прежде всего, спасибо за комментарий. По крайней мере, у вас есть смелость высказывать свое мнение, многие даунвотеры остаются анонимными.

Мой опыт показывает, что отладчик всегда полезен для понимания того, почему программа ведет себя не так, как ожидалось. Поэтому я думаю, что чем скорее вы научитесь им пользоваться, тем лучше.
Я думаю, что мое решение подходит, так как уже было 3 других решения.

Рейтинг:
0

raddevus

Хмм...
Я попробовал это сделать как JavaScript, чтобы открыть браузер Dev tools (F12) и запустить его в консоли:

var rez = 0; var broj = 1123583145;
while (broj > 0){ 
    cif = broj %10; 
    rez = (cif & 1) ? Math.trunc(rez * 10 + cif) : rez;  // uses ternary operator
    console.log("rez : " + rez);
    broj = broj /10; 
    console.log("broj : "+ broj)
} 
console.log(rez);


Если вы откроете окно консоли браузера (F12 в большинстве браузеров и вставите и запустите этот код, вы увидите, что он показывает вам, как вы получаете значение.

В основном я добавлял вывод каждый раз через цикл, чтобы вы могли видеть значения broj и rez каждый раз.

Кроме того, вы понимаете, что строка, которую я отметил//, использует тернарный оператор?
rez = (cif & 1) ? Math.trunc(rez * 10 + cif) : rez;


Эта строка выполняет побитовую операцию над значением cif и 1.
Первый раз через cif = 5; (1123583145 % 5) // 1123583145 мод 5
так как cif = 5, то двоичное значение равно 0101
&Amp; является побитовым, и поэтому (cif & 1) будет
0101
0001
----
0001

Значение cif & 1 = 1
Поскольку значение 1 равно true то левая часть тернарного оператора завершена:
Math.trunc(rez * 10 + cif) // функция trunc заключается в том, чтобы гарантировать, что это целочисленное значение
rez * 10 = 0 // так как rez начинается с 0
0 + 5 (значение cif) означает, что rez получает значение 5


Ниже приведены первые N раз через цикл, где вы можете видеть, что происходит.
Вы можете видеть, что он берет каждую цифру начального значения и строит его.
Остальное я оставляю на ваше усмотрение.

rez : 5 
broj : 112358314.5 
rez : 5 
broj : 11235831.45 
rez : 51 
broj : 1123583.145
rez : 513 
broj : 112358.31450000001
rez : 513 
broj : 11235.831450000001 
rez : 5135 
broj : 1123.583145 
rez : 51353 
broj : 112.3583145
rez : 51353 
broj : 11.235831450000001
rez : 513531 
broj : 1.123583145
rez : 5135311 
broj : 0.1123583145 
broj : 0.01123583145 
broj : 0.0011235831450000001