我想为数字输入Caesar cipher。 (在所有数字前加3)
输入:52输出:85
输入:954输出:287
输入:-10457输出:-43780
如果有人帮助我,我会很高兴。
我尝试过这种方法,但是当我输入的数字少于5个数字时,它会以3开头。
当我输入52时,它输出33385。我还想问用户该程序应该接受一个新数字还是直接退出。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int number, operation;
printf("Enter the number: ");
scanf("%d", &number);
printf("%d", ((number / 10000) + 3) % 10);
printf("%d", (((number % 10000) / 1000) + 3) % 10);
printf("%d", (((number % 1000) / 100) + 3) % 10);
printf("%d", (((number % 100) / 10) + 3) % 10);
printf("%d\n", ((number % 10) + 3) % 10);
printf("press 1 to continue or 2 for exit.");
scanf("%d", &operation);
switch (operation) {
case 1:
printf("Enter the number: ");
scanf("%d", &number);
printf("%d", ((number / 10000) + 3) % 10);
printf("%d", (((number % 10000) / 1000) + 3) % 10);
printf("%d", (((number % 1000) / 100) + 3) % 10);
printf("%d", (((number % 100) / 10) + 3) % 10);
printf("%d\n", ((number % 10) + 3) % 10);
break;
case 2:
break;
}
return 0;
}
答案 0 :(得分:5)
当您输入52时,您的数字变量取值为00052,它将随您的代码转换为33385。如果您不希望前导3,则可以不打印它们,也可以先检索数字并计算仅当该数字不为0时,其相关的凯撒数字。
考虑任何int
数字(无论数字为)的另一种可能性是:
#include "stdio.h"
#include <stdlib.h>
int main()
{
int number, abs_number;
int caesar_number = 0;
int digit_pos = 1;
printf("Enter the number: ");
scanf("%d", &number);
abs_number = abs(number);
while (abs_number != 0)
{
caesar_number += (((abs_number % 10) + 3) % 10) * digit_pos;
abs_number /= 10;
digit_pos *= 10;
}
if (number < 0)
{
caesar_number = -caesar_number;
}
printf("Result is: %d\n", caesar_number);
return 0;
}
答案 1 :(得分:2)
此解决方案适用于所有测试用例(正数和负数),大于100000的数字以及零的数字:
#include "stdio.h"
#include "stdlib.h"
const int SHIFT = 3;
int main() {
int number, abs_number, is_negative, operation, result, decimal_place;
do {
result = 0;
decimal_place = 1;
printf("Enter the number: ");
scanf("%d", &number);
// remove the sign before entering the cipher logic...
abs_number = abs(number);
// ...but do remember it so we can add it back later
is_negative = number < 0;
// from least to most significant decimal place
do {
// cipher the digit and accumulate it in the result
result += (((abs_number % 10) + SHIFT) % 10) * decimal_place;
// remove the consumed digit from the input variable
abs_number /= 10;
// move to the next decimal place
decimal_place *= 10;
} while (abs_number > 0);
printf("Result is: %s%d\n", is_negative ? "-" : "", result);
printf("Press 1 to continue or 2 for exit.");
scanf("%d", &operation);
} while (operation == 1); // repeat if user requested another cipher
return 0;
}
原始代码中有一些需要注意的地方:
switch
大小写不会帮助您重复操作。为此,您需要一个while
循环; switch
循环替换了while
语句,您的第一次迭代也不必要地在循环外展开。第二种是您处理输入数字的每个小数位的方式。如果您使用相同的代码段来处理任何小数位数,那会更好吗?复制代码被认为是不好的做法。它使代码更大,更难维护,并且容易使重复的代码仅在一个位置而不是另一个位置被更改。您始终希望避免重复代码。答案 2 :(得分:1)
除非不记录用户输入的长度,否则“凯撒数字密码”不可逆。使用"777"
,"7"
,"000"
,"0"
之类的输入,输出必须是4个不同的答案才能转换回去。
要维护内部数字表示形式,请考虑使用"%n"
来跟踪用户输入的长度。
static void print_digits(int a, int length, int offset) {
if (length > 1) {
print_digits(a/10, length-1);
}
putchar((a+offset)%10 + '0');
}
...
#define OFFSET 3
int number;
int n1, n2;
int offset = OFFSET % 10;
if (offset < 10) offset += 10; // Handle negative OFFSET
printf("Enter the number: ");
if (scanf(" %n%d%n", &n1, &number, &n2) == 1) {
int length = n2 - n1;
if (number < 0) {
putchar('-');
number = -number;
length--;
}
print_digits(number, length, offset);
}
以上代码在选择输入幅度大于INT_MAX/10
左右时遇到问题。要处理大整数,请考虑移至字符串处理。