Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: Задача из учебника по C  (Прочитано 1037 раз)

0 Пользователей и 1 Гость просматривают эту тему.

tartan

  • Автор темы
  • Гость
Задача из учебника по C
« : 02 Март 2011, 00:50:54 »


Сижу решаю.

Предполагается, что на момент решения я не знаю, что C вообще может работать со строками, не включаю ничего, кроме stdio.h и знаю только операции, циклы for/while и ещё для разнообразия if.

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

Вообще ужас или сойдёт?

#include <stdio.h>

int countdigits(int number)
/* Считаем количество знаков в десятичном числе.
 * Здесь оно особо не нужно, но я её написал для предыдущей задачи
 * и решил использовать */
{
int i = 0;
int num = number;

while(num != 0)
{
num /= 10;
    i++;
}

return i;
}

int degoften(int degree)
/*Возводим десятку в нужную положительную степень*/
{
int result = 1, i = 0;
/* Удачно, что result инициализирован как 1: любое число
* в нулевой степени равно 1, условие цикла не выполняется
* и возвращается 1 */

while(i < degree)
{
result *= 10;
i++;
}

return result;
}

int digit(int position, int number)
/* Получаем знак на произвольной позиции справа*/
{
int buff, result;

buff =  number / (degoften(position - 1));
result = buff % 10;

return result;
}

int undigit(int number, int rpos)
/* Умножаем число на десять в нужной степени, чтобы "собрать" из цифр число
 * Задаём цифру и порядок по счёту справа */
{
if((number == 0) && (rpos ==1)) number = 0;
else
{
//if((number < 10) && (number > 0))
number *= degoften(rpos - 1);
//else
//number = 10 * degoften(rpos-1);
}
return number;
}

int spoil(int number)
/* Портим цифру по условию задачи - прибавляем семь и берём по модулю 10 */
{
number = (number + 7) % 10;
return number;
}

int repair(int number)
{
/* Чиним */
number = (number + 3) % 10;
return number;
}

int encrypt(int input)
{
/* Шифруем число по условию задачи - начиная СПРАВА, берём по одной цифре, "портим" её
* и помещаем на новую позицию, 1234 > 3412 */
int output = 0;
output = undigit(spoil(digit(1, input)), 3) + undigit(spoil(digit(2, input)), 4) + \
undigit(spoil(digit(3, input)), 1) + undigit(spoil(digit(4, input)), 2);
return output;
}

int decrypt(int input)
{
/*И наоборот */
int output = 0;
output = undigit(repair(digit(1, input)), 3) + undigit(repair(digit(2, input)), 4) + \
undigit(repair(digit(3, input)), 1) + undigit(repair(digit(4, input)), 2);
return output;
}

int main()
{
int input, output;

printf("Input 4-digit number to encrypt: ");
scanf("%d", &input);

if(countdigits(input) != 4)
printf("Can't you count to four, dude?/n");
else
{
output = encrypt(input);
printf("%d\n", output);
output = decrypt(output);
printf("%d\n", output);
}

return 0;
}

Есть баг - если на третьей позиции - тройка, то при шифровании на первой позиции оказывается ноль, поэтому зашифрованное число - трёхзначное. Но восстанавливает оно нормально.
« Последнее редактирование: 02 Март 2011, 00:52:25 от tartan »

Оффлайн mkarasik

  • Участник
  • *
  • Сообщений: 163
    • Просмотр профиля
Re: Задача из учебника по C
« Ответ #1 : 03 Март 2011, 00:44:49 »
Как говориться работает не трогай.
Чтобы выводило ноль нужно в формате принтф написать %04d тогда ноль вначале будет всегда выводиться.
Что касается кода то на вкус и цвет как говорится...

Мне не нравиться (лично мое мнение, а не руководство к действию или попытка обосрать) постоянная сборка и разборка. Я бы, наверное, считывал 4-ре цифры сразу в разные инты и работал бы с массивом из четырех цифр без digit/undigit. Что нибу типа такого
scanf("%1u%1u%1u%1u", &i[0], &i[1], &i[2], &i[3])
Ну и проверил бы что функция вернула на случай ошибки. В данном случае не имеет значения но хорошая практика проверять код возврата чужих АПИ.
И еще я не совсем понял функцию degoften.

tartan

  • Автор темы
  • Гость
Re: Задача из учебника по C
« Ответ #2 : 04 Март 2011, 00:54:05 »
Массивы на момент решения этой задачи - через два урока, и даже функции - только в следующем. Интересно, как без функций-то это чудище решать...

degoften - потому что math.h и pow в следующем уроке опять же. (

Но это все равно такой кайф... сочиняю консольные крестики-нолики, вот где красноглазие в полный рост.

Оффлайн Sеr

  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Re: Задача из учебника по C
« Ответ #3 : 07 Март 2011, 13:01:29 »
#include <stdio.h>
int div(int x, int y, int z)
{
int i;
for(i=0;(x-y)>=0;i++){x-=y;}
if(z==1)return x;
else return i;
}
int main()
{
int input, output, i, j, in_per, m[4];
while(printf("Введите четырехзначное число: ")) /*Ввод числа*/
{
scanf("%d", &input);
in_per=input;
for(i=0;input>0;i++)input/=10;
if(i==4){input=in_per; printf("%4d\n", input); break;}
else printf("Неверный ввод! Число должно быть четырехзначным.\n"); /*Проверка кол-ва символов*/
}
for(i=1000,j=3;i>0,j>=0;j--,i/=10)
{
m[j]=div(input,i,0);
input=div(input,i,1);
} /*Определяем каждую цифру числа*/
for(i=0;i<4;i++)
{
if(m[i]>2)
{
m[i]+=7;
m[i]=div(m[i],10,1);
}
else m[i]+=7;
} /*Складываем каждый элемент и 7*/
for(i=0;i<4;i++)printf("%d",m[i]);putchar('\n'); /*Выводим "сложенное" число на экран*/
for(i=0;i<2;i++)
{
in_per=m[i];
j=div(i+2,4,1);
m[i]=m[j];
m[j]=in_per;
} /*Меняем местами 1 и 3, 2 и 4*/
for(i=0;i<4;i++)printf("%d",m[i]);putchar('\n'); /*Выводим шифрованное число на экран*/

return 0;
}
Вот у меня получился такой код для шифровки, он имеет несколько багов.
#include <stdio.h>
int div(int x, int y, int z)
{
int i;
for(i=0;(x-y)>=0;i++){x-=y;}
if(z==1)return x;
else return i;
}
int main()
{
int input, output, i, j, in_per, m[4];
while(printf("Введите четырехзначное число: ")) /*Ввод числа*/
{
scanf("%d", &input);
in_per=input;
for(i=0;input>0;i++)input/=10;
if(i==4){input=in_per; printf("%4d\n", input); break;}
else printf("Неверный ввод! Число должно быть четырехзначным.\n"); /*Проверка кол-ва символов*/
}
for(i=1000,j=3;i>0,j>=0;j--,i/=10)
{
m[j]=div(input,i,0);
input=div(input,i,1);
} /*Определяем каждую цифру числа*/
for(i=0;i<4;i++)
{
if(m[i]<7)
{
m[i]-=7;m[i]+=10;
}
else m[i]-=7;
}/*Чиним число*/
for(i=0;i<4;i++)printf("%d",m[i]);putchar('\n');/*Выводим "починенные" цифры на экран*/
for(i=0;i<2;i++)
{
in_per=m[i];
j=div(i+2,4,1);
m[i]=m[j];
m[j]=in_per;
}/*Меняем местами 1 и 3, 2 и 4*/
for(i=0;i<4;i++)printf("%d",m[i]);putchar('\n'); /*Выводим дешифрованное число на экран*/
return 0;
}
Код для расшифровки, точно такие же, как и в первом, баги.
Простите за неграмотность в языке си, хотел проверить, что у меня получится.
Оба кода работают, но не содержат проверки на символы, тоесть буквы он воспринимает и потом просто зацикливается.
Также у меня что то не сошлось с массивом.
Я использовал только одну функцию, которая делит с остатком и может возвращать либо остаток, либо результат деления. Есть еще массив, но я просто не понимаю, как без него обойтись.
еще раз простите за неграмотность.

Оффлайн Nuсlear

  • Новичок
  • *
  • Сообщений: 24
    • Просмотр профиля
Re: Задача из учебника по C
« Ответ #4 : 07 Март 2011, 21:34:13 »
забываете про отрицательные числа

Оффлайн ABEgorov

  • Участник
  • *
  • Сообщений: 130
    • Просмотр профиля
Re: Задача из учебника по C
« Ответ #5 : 07 Март 2011, 22:49:04 »
С вообще не знаю, изучаю C++.

Я бы написал так. Тупо, зато без массивов, функций и прочего:
#include <stdio.h>

int main()
{
    char ch1, ch2, ch3, ch4, ch5;
   
    // Input:
    printf("Enter number: ");
    ch1 = getchar();
    ch2 = getchar();
    ch3 = getchar();
    ch4 = getchar();
    ch5 = getchar();
    if (ch1<'0' || ch1>'9' || ch2<'0' || ch2>'9' ||
        ch3<'0' || ch3>'9' || ch4<'0' || ch4>'9' || ch5 != '\n')
    {
        fprintf(stderr, "Fatal: Invalid input.");
        return -1;
    }

    // Encrypt:
    ch1 += 7; if (ch1>'9') ch1 -= 10;
    ch2 += 7; if (ch2>'9') ch2 -= 10;
    ch3 += 7; if (ch3>'9') ch3 -= 10;
    ch4 += 7; if (ch4>'9') ch4 -= 10;
    char tmp;
    tmp = ch1; ch1 = ch3; ch3 = tmp;
    tmp = ch2; ch2 = ch4; ch4 = tmp;

    // Output
    printf("\nEncrypted number: ");
    putchar(ch1);
    putchar(ch2);
    putchar(ch3);
    putchar(ch4);
    getchar();
    return 0;
}
Расшифровка аналогична...

Оффлайн Sеr

  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Re: Задача из учебника по C
« Ответ #6 : 08 Март 2011, 00:10:15 »
ABEgorov, я бы так не смог)
ведь привыкли же люди усложнять себе жизнь разной фигней...(это я про себя)

Оффлайн Nuсlear

  • Новичок
  • *
  • Сообщений: 24
    • Просмотр профиля
Re: Задача из учебника по C
« Ответ #7 : 08 Март 2011, 14:54:29 »
не буду надоедать, но всё таки вы забываете про отрицательные числа [-9999;-1000]
просто сам только начал изучать и как решать не знаю, так что интересно

Оффлайн Sеr

  • Любитель
  • *
  • Сообщений: 60
  • Познаю мир, пока не в вузе...
    • Просмотр профиля
Re: Задача из учебника по C
« Ответ #8 : 08 Март 2011, 21:31:12 »
Nuсlear, а разве вообще в этой задаче возможны отрицательные числа?
тем более, здесь говориться про шифровку фактически отдельных цифр, так что на знак можно не обращать внимание.

 

Страница сгенерирована за 0.093 секунд. Запросов: 24.