我有一个我希望排序的号码。我知道如何按升序和降序对其进行排序,但问题是要在数字中切换位数值。
答案 0 :(得分:1)
试试这个
#include <stdio.h>
unsigned power(unsigned base, unsigned exp){
unsigned result = 1;
while(exp > 0){
if(exp & 1)
result = result * base;
base = base * base;
exp >>=1;
}
return result;//Overflow is not considered
}
int pow10(int exp){
return power(10, exp);
}
int get_num_at(int n, int pos){
int exp = pow10(pos);
return n / exp % 10;//Changed by advice of chux
}
int swap(int n, int pos1, int pos2){
if(pos1 == pos2)
return n;
int n1 = get_num_at(n, pos1);
int n2 = get_num_at(n, pos2);
return n - n1 * pow10(pos1) - n2 * pow10(pos2) + n1 * pow10(pos2) + n2 * pow10(pos1);
}
int length(int n){
int len = 1;
while(n /= 10)
++len;
return len;
}
int arrange(int v){
int len = length(v), half = len / 2;
return (len & 1) ? swap(v, 0, len-1) : swap(v, half-1, half);//0 origin
}
int main (void) {
int v;
scanf("%d", &v);
printf ("%d\n", arrange(v));
}
答案 1 :(得分:0)
继续发表评论,回答你的问题:
我如何修改以下代码以获得上述代码或者我是否必须开始新代码?
我会从一种新方法开始。为什么?虽然您可以使用一组占位符并设置各种条件来操纵整数值,以根据奇数/偶数完成中间数字或结束数字交换,但简单转换要容易得多您的整数值为字符串,然后操纵字符。
鉴于您正在使用整数,您需要解决的最长整数为INT_MIN
(-2147483648
)或<{1}}(11-chars
nul - 终止字符)。您可以简单地使用+1
字符的静态字符缓冲区并调用12
将整数转换为字符串(同时在同一个调用中获取其长度)。一个简单的奇数/偶数测试,你知道交换中间字符或结束字符。要将结果字符串转换回整数,只需使用sprintf
。
您可以在开头测试负值,处理正形式,然后将结果值乘以strtol
,以便在值为负时返回。 (注意:您还应该在分配肯定表单之前测试-1
,因为INT_MIN
将不适合整数值。您还必须在交换后检查结果整数数字也适合整数。 - 这是留给你的练习)。
将这些部分放在一起,你可以做类似的事情:
-INT_MIN
示例使用/输出
使用您的测试值:
#include <stdio.h>
#include <stdlib.h>
enum {BASE = 10, MAXS = 12}; /* constants */
int minswap (int v)
{
char buf[MAXS] = "";
int neg = v < 0 ? -1 : 1, /* flag negative numbers */
val = v * neg, /* handle as positive val */
len = sprintf (buf, "%d", val); /* conver to str, get len */
if (len % 2 == 0) { /* val is even */
int m = len / 2;
char tmp = buf[m - 1]; /* swap mid digits */
buf[m - 1] = buf[m];
buf[m] = tmp;
}
else {
char tmp = *buf; /* swap end digits */
*buf = buf[len - 1];
buf[len - 1] = tmp;
}
return (int)strtol (buf, NULL, BASE) * neg;
}
int main (void) {
int v1 = 264802,
v2 = 1357246;
printf (" %d => %d\n", v1, minswap(v1));
printf (" %d => %d\n", v2, minswap(v2));
return 0;
}
仔细看看,如果您有任何问题,请告诉我。
没有库功能使用
如果您要求不使用$ ./bin/minswap
264802 => 268402
1357246 => 6357241
函数中的任何C库函数,则可以使用类似于以下内容的循环轻松替换它们:
minswap
(注意:实际上无需转换为enum {BASE = 10, MAXS = 12}; /* constants */
int minswap (int v)
{
char buf[MAXS] = "";
int neg = v < 0 ? -1 : 1, /* flag negative numbers */
val = v * neg, /* handle as positive val */
len = 0;
while (len + 1 < MAXS && val) { /* convert to string get len */
buf[len++] = val % 10 + '0';
val /= 10;
}
/* (you should validate len > 0 here) */
if (len % 2 == 0) { /* val is even */
int m = len / 2;
char tmp = buf[m - 1]; /* swap mid digits */
buf[m - 1] = buf[m];
buf[m] = tmp;
}
else {
char tmp = *buf; /* swap end digits */
*buf = buf[len - 1];
buf[len - 1] = tmp;
}
while (len--) /* convert to int */
val = val * 10 + buf[len] - '0';
return val * neg;
}
的字符值,因为您只是在中间位置或结束位置交换值,但为了完整起见,包括在内。)
仔细看看,如果您有其他问题,请告诉我。
答案 2 :(得分:0)
这是一个没有任何标准库调用,数组或字符串的解决方案,除了打印结果:
#include <stdio.h>
long long shuffle(int v) {
int i, n, x, d0, d1;
long long p;
/* compute the number of digits and the largest power of 10 <= v */
for (x = v, p = 1, n = 1; x > 9; x /= 10, p *= 10, n++)
continue;
if (n & 1) {
/* odd number of digits, swap first and last */
d0 = v % 10;
d1 = v / p;
return d0 * p + v % p - d0 + d1;
} else {
/* even number of digits, swap middle 2 digits */
for (i = 0, p = 1; i < n / 2 - 1; i++, p *= 10)
continue;
d0 = (v / p) % 10;
d1 = (v / p) / 10 % 10;
return v + p * (d0 - d1) * 9;
}
}
int main(void) {
printf("%d => %lld\n", 0, shuffle(0));
printf("%d => %lld\n", 1, shuffle(1));
printf("%d => %lld\n", 42, shuffle(42));
printf("%d => %lld\n", 24, shuffle(24));
printf("%d => %lld\n", 264802, shuffle(264802));
printf("%d => %lld\n", 1357246, shuffle(1357246));
return 0;
}
输出:
0 => 0
1 => 1
42 => 24
24 => 42
264802 => 268402
注意:
int
,因此我使用了long long
类型,但在int
与long long
具有相同范围的系统上,您可能会仍然得到错误的结果。答案 3 :(得分:0)
我完成了作业,我的代码如下。它有点原始,但它的确有助于您的贡献。
int swapvalues(int input, int digit)
{
int swapsort = 0; //initializes swapsort to 0
int lastdigit; //finds he last digit of input
int digits; //the total number of digits - 1
int firstdigit; //finds the first digit of the input
int middledigit; //finds the first middle digit in an even digit number
int secondmiddledigit; //finds the second middle digit in an even digit number
int firsthalf; //the first half of an even digit number
int firsthalf2; //the second half of an even digit number
int spacing; //the spacing between the output and the input
if(digit % 2 != 0)
{
lastdigit = input % 10;
digits = digit - 1;
firstdigit = (int)(input / pow(10, digits));
swapsort = lastdigit;
swapsort *= (int) pow(10, digits);
swapsort += input % ((int)pow(10, digits));
swapsort -= lastdigit;
swapsort += firstdigit;
}
else
{
firsthalf = input / pow(10, (digit / 2));
middledigit = firsthalf % 10;
firsthalf2 = input / pow(10, (digit / 2) - 1);
secondmiddledigit = firsthalf2 % 10;
spacing = (((secondmiddledigit * 10) + (middledigit)) - ((middledigit * 10) + (secondmiddledigit))) * pow(10, ((digit / 2) - 1));
swapsort = input + spacing;
}
return(swapsort);
}