Tricky C Программа для поиска четных и нечетных
Это сложная проблема, с которой я столкнулся, когда сдавал стажировку в Microsoft. Вопрос следующий:
Пользователь вводит десятичное число. На выходе должно быть указано, является ли число четным или нечетным объектом ограничения, что можно использовать только один printf
, а не двоичный оператор, логический оператор, арифметический оператор, if-else
и switch-case
.
Итак, любые идеи?
Ответы
Ответ 1
Ответ Сета Карнеги может терпеть неудачу для определенных входных данных. В частности, в моей системе он терпит неудачу при вводе 2147483647
, указывая на то, что он даже (по крайней мере, в моей системе), потому что преобразование этого значения в float
теряет точность.
Здесь улучшенное решение, основанное на его:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char **argv) {
const char *const even_or_odd[] = { "even", "odd" };
for (int i = 1; i < argc; i ++) {
const int n = atoi(argv[i]);
printf("%d is %s\n",
n,
even_or_odd[(int)fmod((unsigned char)n, 2.0)]);
}
return 0;
}
Синтаксис for (int i = ...
является "новым" на C99; если ваш компилятор не поддерживает его, объявите int i
; выше цикла.
Проверяемые значения берутся из аргументов командной строки. Было бы достаточно просто изменить программу, чтобы они были взяты из stdin
или в другом месте.
Функция atoi()
не проверяет ошибки, поэтому не ожидайте значимых результатов, если вы дадите ей то, что не является десятичным целым.
Преобразование значения n
в unsigned char
перед передачей его в fmod()
дает результат с той же четностью (нечетность или четность) как n
, но это не будет терять точность при преобразовании в double
(это преобразование происходит неявно, потому что fmod()
принимает аргументы double
). Стандартизованная семантика преобразования в неподписанный тип такова, что это будет корректно работать даже в системах, которые используют представление, отличное от двух'-дополнений.
Вполне возможно, что преобразование из unsigned char
в double
может потерять точность. Для этого потребовалось бы unsigned char
иметь невероятно большую верхнюю границу. double
должен иметь не менее 10 десятичных цифр точности или около 33 или 34 бит; потеря точности будет требовать, чтобы unsigned char
составлял как минимум 34 бита (вероятно, у меня есть одна-единственная ошибка или две там). Такая система может соответствовать, но я сомневаюсь, что такие системы существуют в реальном мире.
Ответ 2
Глупые вопросы требуют глупых ответов.
printf("Yes, the number is even or odd\n");
Ответ 3
Это будет работать:
printf("Number is odd? %d\n", (int)fmod((float)i, (float)2));
Или лучше, если вы можете использовать условный оператор:
printf("Number is %s\n", (int)fmod((float)i, (float)2) ? "odd" : "even");
Ответ 4
Пусть x - определяемая переменная. Следующий код будет печатать 0, если x четный, 1 - если нечетно:
union
{
unsigned char tmp:1;
} u;
u.tmp = x;
printf("%d", u.tmp);
Ответ 5
Я рассматриваю принятый ответ, используя fmod, чтобы нарушать правило "без арифметических операторов". Здесь решение, использующее только structs и casts, чтобы узнать, что наименее значащий бит (означает нечетное или четное):
float f = ...;
struct intStruct {
int i;
};
struct intStruct is;
is.i = (int)f;
struct bitField {
unsigned int odd : 1;
unsigned int padding: 15; // to round out to 16 bits
};
struct bitField *bf_ptr;
bf_ptr = (struct bitField *)&is;
struct bitField bf = *bf_ptr;
printf("Odd? %d", bf.odd);
Ответ 6
Нет тернарного оператора:
int n;
char *answers[] = { "even", "odd" };
scanf("%i", &n);
printf("%s\n", answers[(int) fmod(n, 2.0)]);
Ответ 7
Здесь решение, которое вообще не позволяет использовать fmod. Он работает с использованием символьного представления числа, проверяя, находится ли последняя цифра в {0, 2, 4, 6, 8}.
Большая проблема - найти последнюю цифру.
Ограничения проблемы обременительны.
- нет двоичных операторов: нет назначений (
=
) или индексации массива ([]
) или даже ссылки на структуру (.
)
- нет логических операторов: никакого отрицания (
!
) или ярлыков (&&
) или равенства (==
)
- нет арифметических операторов: нет приращений (
++
)
- no
if
или switch
- только один
printf
Об остальных операторах есть *
, &
, ~
, ?:
и sizeof
.
Большая часть кода пытается найти последнюю цифру в строке. Единственный двоичный оператор, используемый в драйвере main()
, получает argv[1]
. (Квадратные скобки для c[2]
являются синтаксисом объявления, а не оператором)
Я работал над назначением с помощью вызова функции и memcpy
.
Я работал вокруг if
с помощью while
и перебора теста.
Я работаю вокруг !=
, предположив NULL == 0
.
С положительной стороны эта функция работает с действительно большими номерами!
#include <string.h>
#include <stdio.h>
void* null_pointer;
char c[2];
// If s is not null, copy *s to *save, and change *s to '~'
// Return s
char* copy_zap_char_not_null(char* save, char* s) {
char* p;
memcpy(&p, &s, sizeof(char*));
while (p) {
memcpy(save, p, sizeof(char));
memcpy(p, "~", sizeof(char));
memcpy(&p, &null_pointer, sizeof(void*));
}
return s;
}
int print_even_odd(char* s)
{
while (copy_zap_char_not_null(c, strpbrk(s, "0123456789"))) {}
printf("%s\n", ( strpbrk(c, "02468") ? "even" : "odd" ) );
}
int main(int argc, char** argv)
{
print_even_odd(argv[1]);
}
Ответ 8
#include <stdio.h>
#include <string.h>
int main(){
int i, count;
char c, *p, strnum[32];
printf("enter input number:");
scanf("%d%*c", &i);
sprintf(strnum, "%d", i);//or itoa, deprecated.
p=&strnum[strlen(strnum)];
count=sscanf(&p[-1], "%[02468]c", &c);
printf("%d is %s\n", i, count ? "even" : "odd");
return 0;
}
//p=strrev(strnum);//strrev is deprecated. But It works Microsoft C Compiler.
//count=sscanf(p, "%[02468]c", &c);
//printf("%d is %s\n", i, sscanf(strrev(itoa(i,(char*)malloc(32),10)), "%[02468]c", (char*)(malloc(1)) ? "even" : "odd");
Ответ 9
int main()
{ int number;
scanf("%d",&number);
number&1 && printf("Odd") || printf("even");
}
или
int main()
{
int number ;
char arr[][2]={"Even","Odd"};
printf("%s\n",arr[number%2]);
}
Ответ 10
n&1? puts("NO"):puts("YES");
Ответ 11
Я думаю, вы можете сделать это, используя побитовый оператор AND...
scanf("%d",&n);
if( n & 1 == 1) // if last bit in numbers is 1, 'n' is odd , 0 for even
Позже вы можете использовать if else и переключиться на отображение числа, если оно четное или нечетное.
Ответ 12
Лучшее, что я мог придумать...
#include <stdio.h>
int main() {
int number;
char oddness[4+1];
printf("Type an integer: ");
scanf("%d", &number);
printf("I need some help here, user. Is it even or odd? ");
scanf("%s", oddness);
printf("%d is %s.\n", number, oddness);
return 0;
}
Ответ 13
Если пользователь обращается к десятичным числам как числам с плавающей запятой, а не к номерам в базе 10, это может быть возможным ответом.
printf("Floating point numbers are neither even nor odd.");
Четное число представляет собой целое число, которое равномерно делится на 2, т.е. делится на 2 без остатка; нечетное число - это целое число, которое не равномерно делится на 2.