我遇到了一个用第一位和最后一位数字交替进行修改的问题。
代码如下:
/*
Take a integer as input and return integer made up of first digit, last digit alternatively.
Input: 123456
Output: 162534
Idea:
1) find the first digit and last digit of the number.
2) Build the number.
3) Remove the first digit and last digit from the original number.
4) Remaining number is passed to next recursive call.
Explanation:
--> firstlastAlternate(123456);
--------> getFirstDigit(123456) -----------> First Digit: 1
--------> getLastDigit(123456) ------------> Last Digit: 6
--------> buildNum(1, 6, 0) ---------------> new_number: 16
--------> removeFirstandLastDigit(123456) -> num: 2345
--------> firstlastAlternate(2345);
---------------------> getFirstDigit(2345) -----------> First Digit: 2
---------------------> getLastDigit(123456) ------------> Last Digit: 5
---------------------> buildNum(2, 5, 16) ---------------> new_number: 1625
---------------------> removeFirstandLastDigit(2345) -> num: 34
---------------------> firstlastAlternate(34);
----------------------------------> getFirstDigit(34) -----------> First Digit: 3
----------------------------------> getLastDigit(34) ------------> Last Digit: 4
----------------------------------> buildNum(3, 4, 1625) ---------------> new_number: 162534
----------------------------------> removeFirstandLastDigit(34) -> num: 0
----------------------------------> firstlastAlternate(0);
----------------------------------> Terminate condition(True) : print(new_number): 162534
*/
#include<stdio.h>
/*Find first digit. */
int getFirstDigit(int num) {
int firstDigit = num;
while(firstDigit >= 10)
firstDigit = firstDigit / 10;
return firstDigit;
}
/*Find last digit. */
int getLastDigit(int num) {
int lastDigit = num%10;
return lastDigit;
}
/*Build the number. */
void buildNum(int firstDigit, int lastDigit, int *new_number) {
*new_number = (*new_number) * 10 + firstDigit;
*new_number = (*new_number) * 10 + lastDigit;
}
/*Remove the first and last digit from the original number. */
void removeFirstandLastDigit(int *p) {
int y;
*p = *p/10;
y = *p;
int count = 0;
while(y >= 10) {
y = y/10;
count++;
}
int i;
for(i=0; i<count; i++)
y = y*10;
*p = *p-y;
}
void firstlastAlternate(int num) {
/*new_number is our modified number. */
static int new_number = 0;
/*Termination condition. */
if(num == 0) {
printf("\n Modified number is: %d", new_number);
return 0;
}
/*If num is not 0 and num is >= 10. When num is not single digit. */
else if(num >= 10){
int firstDigit, lastDigit, count;
firstDigit = getFirstDigit(num);
lastDigit = getLastDigit(num);
buildNum(firstDigit, lastDigit, &new_number);
removeFirstandLastDigit(&num);
firstlastAlternate(num);
}
/*If num is not 0 and num is <= 10. When num is single digit. */
else {
int firstDigit = getFirstDigit(num);
/*
When num is only a single digit number, then first digit and the last digit are same. So we use only first digit and modify the number. Otherwise it will create repeat.
*/
new_number = new_number * 10 + firstDigit;
printf("\n Modified number is: %d", new_number);
return 0;
}
}
int main(void) {
int num;
printf("\n Enter any number: ");
scanf("%d", &num);
firstlastAlternate(num);
return 0;
}
它适用于某些输入,但不适用于其中包含0的任何输入。 与1042一样,它的输出为124。这样做是因为它将04视为4。
无论如何,我们是否可以区分04和4?还有解决这个问题的更好方法吗?
答案 0 :(得分:1)
还有解决这个问题的更好方法吗?
使用char
数组,stdlib
和string
函数来解决这个问题。
我相信以下内容更简单:
int main(void) {
int num;
printf("\n Enter any number: ");
scanf("%d", &num);
char inputNo[20];
char convertedNo[20];
itoa(num, inputNo, 10);
int i = 1;
int j = 0;
while(inputNo[j] != '\0')
{
if(j%2 == 0)
{
convertedNo[j] = inputNo[j/2];
}
else
{
convertedNo[j] = inputNo[strlen(inputNo) - i];
i++;
}
j++;
}
convertedNo[j] = '\0';
printf("%s\n", convertedNo);
return 0;
}
答案 1 :(得分:0)
据我了解,您在此算法中遇到的问题是removeFirstLastDigit()
。如果删除此函数并稍加修改算法,使其不需要这样的函数,则可以得到数字为1024的预期结果。例如,可以这样完成:
#include <stdio.h>
unsigned int int_pow(unsigned int num, unsigned int power);
unsigned int num_len(unsigned int num);
unsigned int alternate_digits(unsigned int src_num)
{
unsigned int res_num = 0;
unsigned int len = num_len(src_num);
for (unsigned int i = len; i > len / 2; --i)
{
res_num *= 100;
unsigned int high_dgt = src_num / int_pow(10, i - 1) % 10;
unsigned int low_dgt = src_num / int_pow(10, len - i) % 10;
res_num += (high_dgt * 10 + low_dgt);
}
if (len & 1) res_num /= 10;
return res_num;
}
unsigned int int_pow(unsigned int num, unsigned int power)
{
if (power == 0) return 1;
unsigned int result = num;
while (--power) result *= num;
return result;
}
unsigned int num_len(unsigned int num)
{
if (num == 0) return 0;
unsigned int count = 1;
while (num /= 10) ++count;
return count;
}
int main()
{
unsigned int src_num = 123;
printf("%d and %u\n", src_num, alternate_digits(src_num));
return 0;
}
通过计数输入数字的位数(长度)来代替递归和预处理。此解决方案有点古怪:如果数字的长度为奇数,我们需要将结果除以10,否则您可能会在123中得到1322。而且仅通过设计,它不能处理以零开头的输入:04将解释为4.但是,将正确处理1024,结果将为1402。
但是,正如@ gaurav-sehgal在评论中指出的那样,通过将您的数字转换为字符串(一组char
s),可以更轻松(更快)地解决此问题。转换本身可以通过sprintf(str, "%u", num)
完成,其中str
是您的char
数组,其长度至少为11 char
长(每个32位字符为10个字节)整数可以为空字节+1。之后,您可以使用您的解决方案或我的解决方案创建算法,但是现在很容易通过在数字中的位置选择一个数字并将其放置在所需的位置,并且用户可以在程序中输入带前导零的数字,现在将给出预期的结果。
答案 2 :(得分:0)
通过从数字创建字符数组来完成。这不是一种有效的方法,但确实解决了我的目的。
minSdkVersion
PS:如果用户输入001或类似的名称,则每个解决方案都会失败。