0

我参加了考试,从那以后我一直在苦苦挣扎。您有一个整数数组(例如 13、6、21、4),我需要生成如下所示的输出:

13 = 2^3 + 2^2 + 2^0
6 = 2^2 + 2^1
21 = 2^4 + 2^2 + 2^0
4 = 2^2

这就是我到目前为止所得到的。

#include <stdio.h>
#define MAX 100

int main() {
    int niz[MAX], nizb, n, i, ones, k;

    while(1) {
        printf("Array length: ");
        scanf("%d", &n);

        if (n<=0 || n>MAX) break;

        printf("Array elements: ");
        for(i=0;i<n;i++){
            scanf("%d", &niz[i]);
            if (niz[i] <=0) {
                printf("Error! Wrong value. Enter new one: ");
                scanf("%d", &niz[i]);
            }
        }

        for(i=0;i<n;i++) {
            nizb = niz[i];
            ones = 0;

            for(k=0; k < 16; k++) {
                //What should i do here?
            }

        }

    }
}

我被困在这里。我不知道我应该使用多少位,以及 C 如何看到这些整数位。我正在使用 var 'k' 添加到格式为 '2^3 + 2^2 ...' 的字符串中,其中 k 是 'for' 迭代的值。我假设整数的长度是 16,但我真的不确定,因为我们是在一张纸上做的。

我想对大家说声谢谢!!!

4

5 回答 5

2

sizeof您可以使用运算符和来计算要使用的位数CHAR_BIT

int bitsPerInt = sizeof(int) * CHAR_BIT;

CHAR_BIT中定义limits.h

在你有这个限制之后,你可以使用按位运算&符来提取每一位:

for (k = bitsPerInt - 1; k >= 0; k--)
{
    if (nizb & (1U << k))
        // output
    else
        // don't
}

我会把细节留给你。

旁白:看起来您正在尝试将其niz用作数组,但您尚未将其声明为数组。这段代码甚至可以编译吗?此外, 的返回值main应该是int

于 2013-05-21T16:58:00.977 回答
1

这是完全的猜想,因为我的数学不是很好,但我想我会这样去做:

 int potency = 0, base = 1;
 while(base < NumberInQuestion) {
     base *= 2;
     ++potency;
 }

循环结束后,您将知道仍然适合“数字”的最高效力。

 Number -= base/2; //Removes the base you just calculated from the number.
 printf("2^%d", potency);

冲洗并重复,直到 Number 降至 0,最迟应为 2^0。

对于您的用例,代码可能看起来像这样:

for(i=0; i < n; ++i) {
    int Number = niz[i];
    while(Number > 0) {
        int potency = 0, base = 1;
        do {               //Executes at least once, making a number of '1' possible.
            base *= 2;
            ++potency;
        } while(base < Number);
        Number -= base/2; //Reverts the last step you made, making the 'base' smaller than 'Number'.
        printf("2^%d", potency);
    }
}

有一个可能的替代方案,它可以让您更全面地了解事物并节省您的迭代。为此,我们使用两步过程。

for(i=0; i < n; ++i) {
    int Number = niz[i];
    int potency = 0, base = 1;
    do {               //Executes at least once, making a number of '1' possible.
        base *= 2;
        ++potency;
    } while(base < Number);

    base /= 2;                      //Reverses the last iteration.

    //At this point, we know the maximum potency, which still fits into the number.
    //In regards of base 2, we know the Most Significant Bit.
    while(base > 0) {
        Number -= base;             //Removes the MSD (Most significant digit)
        printf("2^%d", potency);    //Prints your '1'.
        while(base > Number) {      //Executes at least once.
            base /= 2;              //Goes back one potency. (Ends at '0' latest.)
            --potency;              //For each potency (except for first), it's a '0'.
        }
    }
}
于 2013-05-21T17:02:44.307 回答
1

不确定这与二进制补码有什么关系(这是表示负数的一种特殊方式)。显然,您要做的是将整数表示为 2 的幂的总和。这是我的做法,不一定比其他答案更好或更差......

void powersum(int n)
{ int powers[sizeof(int) << 3];
  int i;
  char *sep = "";

  printf("%d = ", n);

  powers[0] = 0;

  for (i = 0; n; n >>= 1, ++i)
    powers[i] = n & 1;

  while (--i >= 0)
  { if (powers[i])
    { printf("%s2^%d", sep, i);
      sep = " + ";
    }
  }

  printf("\n");
}

编辑:这是另一个不使用堆栈分配数组的版本,但作为权衡必须更多地绕过循环(每个位一次,而不是只循环直到找到最高 1 位):

void powersum2(int n)
{ int i = (sizeof(int) << 3) - 2;
  int m = 1 << i;
  char *sep = "";

  printf("%d = ", n);

  while (m)
  { if (n & m)
    { printf("%s2^%d", sep, i);
      sep = " + ";
    }
    m >>= 1;
    --i;
  }

  printf("\n");
}
于 2013-05-21T17:22:00.157 回答
0

如果您可以容忍 GCC 依赖,那么对@twalberg 的解决方案的 hack 会变​​得非常好和小;)

void powersum(int n)
{
    char *sep = "";
    printf("%d = ", n);

    while (n) {
        int pos = 31 - __builtin_clz(n);
        printf("%s2^%d", sep, pos);
        sep = " + ";
        n ^= 1 << pos;
    }

    printf("\n");
}
于 2013-05-21T20:19:44.750 回答
0
quotient = niz[i];
 int k=0,c[MAX];

while(quotient!=0){

     binaryNumber[i++]= quotient % 2;  //this will convert your numbers to binary form 

     quotient = quotient / 2;          //and store in reverse in array

}
for(j = 0 ;j<i;j++)                 
 {                            
     if(binaryNumber[j]==1)  */e.g binary of 4 is stored in array as 001 ie 1 atpos2*/
  {  c[k]=j;
    k++;}
 }
  while(k--)
   printf("2^%d +",c[k]);  
于 2013-05-21T17:26:00.767 回答