如何在C中交错两个整数?

如何在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

假设我有两个整数

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, 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