2012-04-06 2 views
7

Я занимаюсь домашним заданием для своего курса на C (первый курс программирования). Часть задания состоит в том, чтобы написать код, чтобы пользователь вводил число длиной до 9 цифр, и программе необходимо определить, является ли это число «увеличивающимся»/«действительно увеличивающимся»/«уменьшающимся»/«действительно снижающимся»/«увеличение и уменьшение»/«действительно уменьшающееся и действительно увеличивающееся»/«не уменьшающееся и не увеличивающееся». (7 вариантов в общей сложности)Извлечение отдельных цифр из длинного числа C

Поскольку это наше первое задание мы не разрешается использовать ничего, кроме того, что преподавалось в классе:

делать-то время, потому что, в то время как петли, иначе, если, если, перерыв, продолжать зсапЕ, Printf, по модулю, и основные операторы

(Мы не можем использовать любую библиотеку, кроме для stdio.h)

это все. Я не могу использовать массивы или getchar или любой другой материал. Единственная функция, которую я могу использовать для получения ввода от пользователя, - scanf.

До сих пор я уже написал алгоритм с блок-схемой и всем, но мне нужно отделить вход пользователя от его отдельных цифр.

Например, если пользователь вводит «1234 ...», я хочу сохранить 1 в a, 2 в b и т. Д., А затем выполнить сравнение между всеми цифрами, чтобы определить, например, все ли они равны (увеличение и уменьшение), или a> b> c ... (убывание) и т. д.

Я знаю, как отделить каждую цифру с помощью оператора% и /, но я не могу понять, как «сохранить» эти значения в переменной, которую я позже смогу использовать для сравнений.

Это то, что я до сих пор:

printf("Enter a positive number : "); 

do { 
    scanf ("%ld", &number); 
    if (number < 0) { 
     printf ("invalid input...enter a positive integer: "); 
     continue; 
    } 
    else break; 
} while (1); 

while (number < 0) { 
    a = number % 10; 
    number = number - a; 
    number = number/10; 
    b = a; 
} 
+2

Подождите, они хотят, чтобы вы разделили число до «до 9» цифр, но они не позволят вам использовать массив? Thats ... это просто жестоко! –

+0

это только первая часть ... другая часть связана с теорией Голдбаха, пользователь вводит любое число до 9 цифр, а компьютер выводит первые простые числа, которые составляют это число. те же ограничения для этого – nofe

+2

Я не понимаю вашу концепцию увеличения против действительно увеличивающейся. И что такое «увеличение и уменьшение» по сравнению с «действительно уменьшающимся и действительно увеличивающимся». Просьба уточнить, как ваш код должен классифицировать ввод. – abelenky

ответ

4

Почему не сканировать их в качестве символов (строки)? Затем вы можете получить к ним доступ через смещение массива, вычитая смещение 48 из кода символа ASCII. Вы можете проверить, что символ - это цифра, используя isdigit ctype.h.


EDIT

Из-за невероятно рассеянные ограничений, что ваш профессор поставить на место:

#include <stdio.h> 

int main() 
{ 
    int number; 
    printf("Enter a positive number: "); 

    do 
    { 
    scanf ("%ld", &number); 
    if (number < 0) 
    { 
     printf ("invalid input...enter a positive integer: "); 
     continue; 
    } 
    else break; 
    } while (1); 

    int a = -1; 
    int b = -1; 
    int c = -1; 
    int d = -1; 
    int e = -1; 
    int f = -1; 
    int g = -1; 
    int h = -1; 
    int i = -1; 

    while (number > 0) 
    { 
    if (a < 0) a = number % 10; 
    else if (b < 0) b = number % 10; 
    else if (c < 0) c = number % 10; 
    else if (d < 0) d = number % 10; 
    else if (e < 0) e = number % 10; 
    else if (f < 0) f = number % 10; 
    else if (g < 0) g = number % 10; 
    else if (h < 0) h = number % 10; 
    else if (i < 0) i = number % 10; 

    number /= 10; 
    } 

    /* Printing for verification. */ 

    printf("%i", a); 
    printf("%i", b); 
    printf("%i", c); 
    printf("%i", d); 
    printf("%i", e); 
    printf("%i", f); 
    printf("%i", g); 
    printf("%i", h); 
    printf("%i", i); 

    return 0; 
} 

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

+2

Я перечислил ограничения, которые у меня есть для этого задания выше ... спрашивая: «Почему бы просто не сделать это», или это не имеет значения. Вы могли бы также спросить меня, почему я даже изучаю C (почему не Java? C++?). Я, потому что это то, что мой университет требует от меня – nofe

+2

Если вы можете сканировать целые числа, вы можете сканировать символы. Смещение массива в основном дополняет, что соответствует ограничению основных операторов. –

+0

Я могу сканировать персонажей, ты прав. Можете ли вы объяснить, как сделать смещение массива без использования массива (не знаю, что такое массив), как для isdigit. Я не могу использовать эту или любую другую библиотеку, кроме stdio.h, но это нормально, потому что мне не нужно убедитесь, что символы действительно цифры, пользователь вводит только целые числа. – nofe

1

Давайте предположим, что этот номер 23654

23654 % 10000 = 2 and 3654 
3654 % 1000 = 3 and 654 
654 % 100 = 6 and 54 
54 % 10 = 5 and 4 
4 

Таким образом, вы можете получить все цифры. Конечно, вы должны знать, превышает ли число 10000, 1000, 100 или 10, чтобы знать первый делитель.

Играйте с sizeof, чтобы получить размер целого, чтобы избежать огромного, если ...другое заявление

EDIT:

Давайте посмотрим

if (number>0) { 
    // Well, whe have the first and only digit 
} else if (number>10) { 
    int first_digit = number/10; 
    int second_digit = number % 10; 
} else if (number>100) { 
    int first_digit = number/100; 
    int second_digit = (number % 100)/10; 
    int third_digit = (number % 100) % 10; 
} ... 

и так далее, я полагаю

+0

Мне нужно поставить это в цикл, потому что мне нужно обрабатывать до 9 цифр. Кроме того, я хочу «сохранить» эти цифры где-нибудь или назначить их переменным, чтобы я мог использовать их для моих сравнений. – nofe

+0

не может использовать sizeof .... огромные инструкции if-else в порядке – nofe

0

Вот рабочий пример в простом C:

#include <stdio.h> 

unsigned long alePow (unsigned long int x, unsigned long int y); 

int main(int argc, const char* argv[]) 
{ 
    int enter_num, temp_num, sum = 0; 
    int divisor, digit, count = 0; 

    printf("Please enter number\n"); 
    scanf("%d", &enter_num); 

    temp_num = enter_num; 

    // Counting the number of digits in the entered integer 
    while (temp_num != 0) 
    { 
     temp_num = temp_num/10; 
     count++; 
    } 

    temp_num = enter_num; 

    // Extracting the digits 
    printf("Individual digits in the entered number are "); 
    do 
    { 
     divisor = (int)(alePow(10.0, --count)); 
     digit = temp_num/divisor; 
     temp_num = temp_num % divisor; 

     printf(" %d",digit); 
     sum = sum + digit; 
    } 
    while(count != 0); 

    printf("\nSum of the digits is = %d\n",sum); 

    return 0; 
} 


unsigned long alePow(unsigned long int x, unsigned long int y) { 

    if (x==0) { return 0; } 
    if (y==0||x==1) { return 1; } 
    if (y==1) { return x; } 
    return alePow(x*x, y/2) * ((y%2==0) ? 1 : x); 
} 
+0

спасибо, некоторые из них полезны , Я не хочу суммировать цифры, хотя я хочу сравнить их. Также я не могу использовать math.h – nofe

+0

Обновлено без использования math.h, взгляните на функцию alePow;) – aleroot

1

Это глупо просить вас делать циклы без массивов --- но t виновата твоя учительница, а не твоя.

Это, как говорится, я хотел бы сделать что-то вроде этого:

char c; 
while (1) { 
    scanf("%c", &c); 
    if (c == '\n') /* encountered newline (end of input) */ 
     break; 
    if (c < '0' || c > '9') 
     break;  /* do something to handle bad characters? */ 
    c -= '0'; 
    /* 
    * At this point you've got 0 <= c < 9. This is 
    * where you do your homework :) 
    */ 
} 

Хитрость здесь в том, что при вводе номера в программу, вы посылаете буфер все сразу, а не по одному символу за раз. Это означает, что первый scanf будет блокироваться до тех пор, пока вся строка (т. Е. «123823» или что-то еще) не появится одновременно, наряду с символом новой строки ('\ n'). Затем этот цикл анализирует эту строку на досуге.

Редактировать Для тестирования увеличения/уменьшения числа цифр вы можете подумать, что вам нужно сохранить всю строку, но это неверно. Просто определить некоторые дополнительные переменные, чтобы помнить важную информацию, такую ​​как:

int largest_digit_ive_seen, smallest_digit_ive_seen, strict_increasing_thus_far; 

и т.д. и т.п.

+0

спасибо, я действительно уже знал, как проверить правильность ввода, но вы убеждаете меня снова рассмотреть использование char. что означает синтаксический анализ? – nofe

+1

«Анализ» означает анализ (примерно). Тип данных 'char' похож на' int', но меньше: он может обрабатывать числа в диапазоне от -128 до 127 (но это нормально для одной цифры, которая может быть только 0-9 в любом случае). Причина, по которой я использую 'char', заключается в том, что я хочу использовать'% c', который читает ровно одну цифру. Но 'scanf' требует, чтобы вы использовали' char' для использования '% c'. Кроме этого, он может также быть 'int' вместо' char' --- он просто сохраняет число. –

0

Я хотел бы предложить петля-разворачивая (игнорировать этот термин, если вы не знаете этого).

int a=-1, b=-1, c=-1, d=-1, e=1, f=-1, g=-1, h=-1, i=-1; // for holding 9 digits 
int count = 0; //for number of digits in the given number 


if(number>0) { 
i=number%10; 
number/=10; 
count++; 
} 

if(number>0) { 
h=number%10; 
number/=10; 
count++; 
} 

if(number>0) { 
g=number%10; 
number/=10; 
count++; 
} 
.... 
.... 
/* All the way down to the storing variable a */ 

Теперь вы знаете количество цифр (количество переменных), и они сохраняются в какой из переменных. Теперь у вас есть все цифры, и вы можете проверить их «уменьшение», «увеличение» и т. Д. С большим количеством if!

Я не могу придумать лучшего решения, учитывая все ваши условия.

+0

ОК, я думал, что смогу вырезать углы с большой петлей, которая делает все, но в соответствии с тем, что вы говорите, мне придется сделать это так. У меня это уже было, я просто надеялся на ярлык. спасибо – nofe

+0

Потому что ваши условия делают очень трудным написать лучшее решение для этого :) –

+0

@nofe вы можете использовать цикл, и вы почти наверняка должны использовать цикл здесь! 'int a, b, c, d ...' совпадает с 'int digits [9]', поэтому, если у вас есть массив, вы можете легко пропустить все цифры. – Kiril

1

Так как вам нужно только для сравнения последовательных цифр, нет элегантный способ сделать это без массивов:

int decreasing = 2; 
int increasing = 2; 

while(number > 9) 
{ 
    int a = number % 10; 
    int b = (number/10) % 10; 

    if(a == b) 
    { 
    decreasing = min(1, decreasing); 
    increasing = min(1, increasing); 
    } 
    else if(a > b) 
    decreasing = 0; 
    else if(a < b) 
    increasing = 0; 

    number /= 10; 
} 

Здесь мы гуляем через число (путем деления на 10), пока только одна цифра остается. Мы храним информацию о номере до этого момента в decreasing и increasing - a 2 означает действительно увеличивающееся/уменьшающееся, a 1 означает увеличение/уменьшение, а значение 0 означает, что оно не увеличивается/уменьшается.

На каждом шагу a - это одна цифра и b - это десятки. Затем мы меняем increasing и decreasing на основе сравнения между a и b.

В конце, это должно быть легко превратить значения increasing и decreasing в окончательный ответ, который вы хотите.

Примечание: Функция min возвращает меньшее из двух аргументов.Вы должны иметь возможность написать свои собственные или заменить эти строки на if заявления или условные обозначения.

Смежные вопросы