Подтвердить что ты не робот

Tricky C Программа для поиска четных и нечетных

Это сложная проблема, с которой я столкнулся, когда сдавал стажировку в Microsoft. Вопрос следующий:

Пользователь вводит десятичное число. На выходе должно быть указано, является ли число четным или нечетным объектом ограничения, что можно использовать только один printf, а не двоичный оператор, логический оператор, арифметический оператор, if-else и switch-case.

Итак, любые идеи?

4b9b3361

Ответ 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.