[英]Swapping some digits of a number in c programming
我有一个要排序的数字。 我知道如何按升序和降序对它进行排序,但是问题是要在数字中切换位置值。
尝试这个
#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));
}
继续我的评论,回答您的问题:
我将如何修改下面的代码以获取以上内容?还是必须开始新的代码?
我将从一种新方法开始。 为什么? 尽管您可以使用一组占位符并设置各种条件来操纵整数值以完成根据奇数/偶数的中位数或末位数交换,但将整数值简单转换为字符串和然后操纵角色。
假定您正在使用整数,则必须寻址的最长整数是INT_MIN
( -2147483648
)或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
仔细看一下,如果您有任何问题,请告诉我。
没有库函数的用法
如果您需要在minswap
函数中不使用任何C库函数,则可以使用类似于以下内容的循环轻松地将它们替换:
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;
}
( 注意:实际上,您不必使用-/+ '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
具有相同范围的系统上,您仍然可能得到错误的结果。 我已经完成任务,我的代码如下。 这有点原始,但是它很有效,谢谢大家的贡献。
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);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.