如何在C中交错两个整数?
假设我有两个整数 a=1234 b=45678 现在我想把它们交错成第三个int c,看起来像这样 c=415263748,假设其长度不变。到目前为止,我已经能够做到这一点: 无符号隔行扫描无符号x,无符号y{ 无符号功率=10; whiley>=pow 功率*=10; 返回x*pow+y; }如何在C中交错两个整数?,c,math,C,Math,假设我有两个整数 a=1234 b=45678 现在我想把它们交错成第三个int c,看起来像这样 c=415263748,假设其长度不变。到目前为止,我已经能够做到这一点: 无符号隔行扫描无符号x,无符号y{ 无符号功率=10; whiley>=pow 功率*=10; 返回x*pow+y; } 你必须一个接一个地得到数字。当你说x%10时,你得到的是最低有效位。当你说x=x/10时,你去掉了最低有效位。开始做y,然后保持交替: unsigned interlace(unsigned x, u
你必须一个接一个地得到数字。当你说x%10时,你得到的是最低有效位。当你说x=x/10时,你去掉了最低有效位。开始做y,然后保持交替:
unsigned interlace(unsigned x, unsigned y)
{
//If the parameters order could be inverted...
if(x > y)
{
unsigned z = x;
x = y;
y = z;
}
unsigned ans = y % 10;
y = y/10;
unsigned exponent = 10;
while(y)
{
ans += (x%10)*exponent;
x = x/10;
exponent *= 10;
ans += (y%10)*exponent;
y = y/10;
exponent *= 10;
}
return ans;
}
你必须一个接一个地得到数字。当你说x%10时,你得到的是最低有效位。当你说x=x/10时,你去掉了最低有效位。开始做y,然后保持交替:
unsigned interlace(unsigned x, unsigned y)
{
//If the parameters order could be inverted...
if(x > y)
{
unsigned z = x;
x = y;
y = z;
}
unsigned ans = y % 10;
y = y/10;
unsigned exponent = 10;
while(y)
{
ans += (x%10)*exponent;
x = x/10;
exponent *= 10;
ans += (y%10)*exponent;
y = y/10;
exponent *= 10;
}
return ans;
}
通过处理值在字符串上的交错表示,稍微扭转方法可以消除参数问题的顺序。这允许一种简单的方法将两个数字缝合在一起。在这里使用strlen时,您还可以使用snprintf NULL,0,%u,a和snprintf NULL,0,%u,b来确定每个字段中的位数 交错字符串表示的简单方法是:
#define NUMC 32
unsigned interlace (unsigned a, unsigned b)
{
char sa[NUMC], sb[NUMC], result[2*NUMC];
size_t lena, lenb, n = 0;
sprintf (sa, "%u", a);
sprintf (sb, "%u", b);
lena = strlen(sa);
lenb = strlen(sb);
if (lena > lenb) {
for (size_t i = 0, j = 0; sa[i]; i++) {
result[n++] = sa[i];
if (sb[j])
result[n++] = sb[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
for (size_t i = 0, j = 0; sb[i]; i++) {
result[n++] = sb[i];
if (sa[j])
result[n++] = sa[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
注意:以上应添加大于零的转换和长度检查验证。为了简洁起见,故意省略了它们
参数的顺序是不相关的。您可以将其称为隔行扫描a、b或隔行扫描b、a,每次的结果都是正确的
举个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMC 32
unsigned interlace (unsigned a, unsigned b)
{
char sa[NUMC], sb[NUMC], result[2*NUMC];
size_t lena, lenb, n = 0;
sprintf (sa, "%u", a);
sprintf (sb, "%u", b);
lena = strlen(sa);
lenb = strlen(sb);
if (lena > lenb) {
for (size_t i = 0, j = 0; sa[i]; i++) {
result[n++] = sa[i];
if (sb[j])
result[n++] = sb[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
for (size_t i = 0, j = 0; sb[i]; i++) {
result[n++] = sb[i];
if (sa[j])
result[n++] = sa[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
int main (void) {
unsigned a = 1234, b = 45678;
printf ("interlaced: %u\n", interlace (a, b));
}
通过处理值在字符串上的交错表示,稍微扭转方法可以消除参数问题的顺序。这允许一种简单的方法将两个数字缝合在一起。在这里使用strlen时,您还可以使用snprintf NULL,0,%u,a和snprintf NULL,0,%u,b来确定每个字段中的位数 交错字符串表示的简单方法是:
#define NUMC 32
unsigned interlace (unsigned a, unsigned b)
{
char sa[NUMC], sb[NUMC], result[2*NUMC];
size_t lena, lenb, n = 0;
sprintf (sa, "%u", a);
sprintf (sb, "%u", b);
lena = strlen(sa);
lenb = strlen(sb);
if (lena > lenb) {
for (size_t i = 0, j = 0; sa[i]; i++) {
result[n++] = sa[i];
if (sb[j])
result[n++] = sb[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
for (size_t i = 0, j = 0; sb[i]; i++) {
result[n++] = sb[i];
if (sa[j])
result[n++] = sa[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
注意:以上应添加大于零的转换和长度检查验证。为了简洁起见,故意省略了它们
参数的顺序是不相关的。您可以将其称为隔行扫描a、b或隔行扫描b、a,每次的结果都是正确的
举个简单的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMC 32
unsigned interlace (unsigned a, unsigned b)
{
char sa[NUMC], sb[NUMC], result[2*NUMC];
size_t lena, lenb, n = 0;
sprintf (sa, "%u", a);
sprintf (sb, "%u", b);
lena = strlen(sa);
lenb = strlen(sb);
if (lena > lenb) {
for (size_t i = 0, j = 0; sa[i]; i++) {
result[n++] = sa[i];
if (sb[j])
result[n++] = sb[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
for (size_t i = 0, j = 0; sb[i]; i++) {
result[n++] = sb[i];
if (sa[j])
result[n++] = sa[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
int main (void) {
unsigned a = 1234, b = 45678;
printf ("interlaced: %u\n", interlace (a, b));
}
这并不完全是您所要求的,但也许您可以在您的函数中重用一些逻辑 输出: 代码:
这并不完全是您所要求的,但也许您可以在您的函数中重用一些逻辑 输出: 代码:
另一种完全不同的方法,与原始方法更加内联,可以使用div函数和div_t结构来自动处理除法和余数。您可以使用snprintfnull,0,%u,var;函数确定位数,以便在必要时交换参数 一个简单的例子是:
#include <stdio.h>
#include <stdlib.h>
unsigned interlace (unsigned a, unsigned b)
{
unsigned result = 0, mult = 1;
div_t da = { .quot = a }, db = { .quot = b };
if (snprintf (NULL, 0, "%u", b) > snprintf (NULL, 0, "%u", a)) {
div_t tmp = da;
da = db;
db = tmp;
}
do {
da = div (da.quot, 10);
result += da.rem * mult;
mult *= 10;
if (db.quot) {
db = div (db.quot, 10);
result += db.rem * mult;
mult *= 10;
}
} while (da.quot);
return result;
}
int main (void) {
unsigned a = 1234, b = 45678;
printf ("interlaced: %u\n", interlace (a, b));
}
如果您还有其他问题,请告诉我。这是另一种对interlace cat进行蒙皮的方法。另一种完全不同的方法,与原始方法更加内联,可以利用div函数和div_t结构自动处理除法和余数。您可以使用snprintfnull,0,%u,var;函数确定位数,以便在必要时交换参数 一个简单的例子是:
#include <stdio.h>
#include <stdlib.h>
unsigned interlace (unsigned a, unsigned b)
{
unsigned result = 0, mult = 1;
div_t da = { .quot = a }, db = { .quot = b };
if (snprintf (NULL, 0, "%u", b) > snprintf (NULL, 0, "%u", a)) {
div_t tmp = da;
da = db;
db = tmp;
}
do {
da = div (da.quot, 10);
result += da.rem * mult;
mult *= 10;
if (db.quot) {
db = div (db.quot, 10);
result += db.rem * mult;
mult *= 10;
}
} while (da.quot);
return result;
}
int main (void) {
unsigned a = 1234, b = 45678;
printf ("interlaced: %u\n", interlace (a, b));
}
如果您还有其他问题,请告诉我。这是另一种对交错猫进行蒙皮的方法。正整数b的最后一个十进制数字是b%10。要将其与a的最后一个数字交错,可以执行10*a%10+b%10。然后除以10将数字右移一位并重复。正整数b的最后一位小数是b%10。要将其与a的最后一个数字交错,可以执行10*a%10+b%10。然后除以10,将数字右移一位并重复。如果参数顺序颠倒,则失败。@DavidC.Rankin假设这些参数的长度不变。我想是吧。是吗?不,我想用户可能会做一些奇怪的事情,所以我只是检查长度,看看哪个更长。更改参数顺序不会更改长度。注意:我没有否决投票,因为您可以假定用户将按显示的顺序传递值。但是您也可以防止用户做一些愚蠢的事情:好吧,添加if-then-use字符串还是要便宜得多。。。根据她提供的代码,她似乎只想用数学来解决它。t exponent=10;->无符号指数=10;为避免因int溢出而导致的潜在UB-无需引入其他类型。如果参数顺序颠倒,则会失败。@DavidC.Rankin假设这些参数的长度不变。我想是吧。是吗?不,我想用户可能会做一些奇怪的事情,所以我只是检查长度,看看哪个更长。更改参数顺序不会更改长度。注意:我没有否决投票,因为您可以假定用户将按显示的顺序传递值。但您也可以防止用户执行som
ething-dumb:好吧,添加if-then使用字符串还是便宜得多。。。根据她提供的代码,她似乎只想用数学来解决它。t exponent=10;->无符号指数=10;为了避免因int溢出而导致的潜在UB,无需引入其他类型。有其他方法吗?我不想用数学library@lolnoname我已经贴了一张。如果您关心参数的顺序,您应该只添加一个检查来交换它们,如果x大于y,还有其他方法吗?我不想用数学library@lolnoname我已经贴了一张。如果您关心参数的顺序,您应该只添加一个复选框来交换它们,如果x大于yI,就像您使用它的地方一样,但是如果您在问题中输入45678和1234,会发生什么呢?旁白:由于在扫描%d之后按[Enter]键,&num2;stdout to fflushstdout;中没有剩余内容;。也把,;实际上是putchar'\n';输出1字符时无需扫描“\0”:当您要求输入数字a:且用户键入43时会发生什么情况?如何检测和处理该错误?好奇的是,有什么规则你不能正确使用任何输入函数,除非你检查返回值?@DavidC.Rankin我根据你的建议对我的代码做了一些更改,scanf现在用户更安全了,输入数字的长度也不再重要了,输入45678和1234将得到想要的答案,但如果总是先从最长的数字开始,则相反的方案不起作用。使用snprintf NULL、0、%ld、num1进行检查将告诉您需要多少位数字,从而确定长度。然后可以确定首先从哪个数字开始。而temp=getchar!='\n'&温度!=EOF;仅当下一个输入不丢弃前导空格时才需要。除%c、%[…]和%n之外的所有scanf转换说明符都放弃前导空格。总之,改进了很多,++1.事实上,我错误地认为第一个输入是交错结果的基础,顺便说一句,谢谢你的提示,我将在我未来的实现中考虑这一点我喜欢你将要使用它的地方,但是如果你在问题中输入45678和1234,会发生什么?旁白:由于在扫描%d之后按[Enter]键,&num2;stdout to fflushstdout;中没有剩余内容;。也把,;实际上是putchar'\n';输出1字符时无需扫描“\0”:当您要求输入数字a:且用户键入43时会发生什么情况?如何检测和处理该错误?好奇的是,有什么规则你不能正确使用任何输入函数,除非你检查返回值?@DavidC.Rankin我根据你的建议对我的代码做了一些更改,scanf现在用户更安全了,输入数字的长度也不再重要了,输入45678和1234将得到想要的答案,但如果总是先从最长的数字开始,则相反的方案不起作用。使用snprintf NULL、0、%ld、num1进行检查将告诉您需要多少位数字,从而确定长度。然后可以确定首先从哪个数字开始。而temp=getchar!='\n'&温度!=EOF;仅当下一个输入不丢弃前导空格时才需要。除%c、%[…]和%n之外的所有scanf转换说明符都放弃前导空格。总之,改进了很多,++1。事实上,我错误地认为第一个输入是交错结果的基础,顺便说一句,感谢您提供的提示,我将在未来的实现中考虑这一点
#include <stdio.h>
#include <stdlib.h>
unsigned interlace (unsigned a, unsigned b)
{
unsigned result = 0, mult = 1;
div_t da = { .quot = a }, db = { .quot = b };
if (snprintf (NULL, 0, "%u", b) > snprintf (NULL, 0, "%u", a)) {
div_t tmp = da;
da = db;
db = tmp;
}
do {
da = div (da.quot, 10);
result += da.rem * mult;
mult *= 10;
if (db.quot) {
db = div (db.quot, 10);
result += db.rem * mult;
mult *= 10;
}
} while (da.quot);
return result;
}
int main (void) {
unsigned a = 1234, b = 45678;
printf ("interlaced: %u\n", interlace (a, b));
}
$ ./bin/interlace_unsinged
interlaced: 415263748