给定一个单位数字,正整数,转换为整数,乘以2,返回一个新数组的数组,每个数字在数组中

时间:2016-11-18 15:23:18

标签: c arrays

例如:

[1,2,3] -> [2,4,6]
[9,1] -> [1,8,2]
[6,7,5] -> [1,3,5,0]

我昨天在第一次技术面试中得到了这个问题(在C中做过,因为那是我最好的语言,所以C答案会有所帮助)并完全消失:( 这就是我的想法:

从数组末尾开始并向左移动 在每{{}}},乘以2并查看是否有2位数(如果arr[i])并且如果有最左边的数字,请将其移至arr[i]/10 != 0,只要arr[i-1]

我无法弄清楚如何在C中实际执行此操作。我有类似的事情:

a[i-1] != NULL

但是我的代码中存在很多错误。有没有更好的方法,还是我走在正确的轨道上?

3 个答案:

答案 0 :(得分:1)

我能在短时间内思考,比如面试

#include <stdio.h>
#include <stdlib.h>

void invert (int *head, int *tail)
{
    int temp;

    if (head < tail)
    {
        temp = *head;
        *head = *tail;
        *tail = temp;

        invert(++head, --tail);
    }
}

int* multTwo(int* arr, size_t len)
{
    int value = 0;
    int n_digits =0 ;

    // CONVERT THE ARRAY TO NUMBER
    while(len--)
    {
        value += *arr;

        value *=10;

        arr++;
    }

    value /= 10;

    // DOUBLE THE NUMBER
    value *= 2;

    // CONVERT IT TO BUFFER
    int *digits = malloc(sizeof(*digits));

    while ((value>0) && (digits != NULL))
    {
        digits[n_digits++] = value%10;

        value /= 10;

        digits = realloc(  digits, sizeof(*digits) * (n_digits+1) );
    }

    if (digits != NULL)
    {
        invert(digits, &digits[n_digits-1]);

        printf("[ ");

        for (int i=0; i<n_digits; i++)
            printf("%d, ", digits[i]);

        printf("]\n");
    }

    return digits;
}

int main(void)
{
    int array[] = {6,7,5};

    multTwo(array, sizeof(array)/sizeof(array[0]));

   return 0;
}

答案 1 :(得分:1)

一些伪代码。主要思想是将C知识的深度展示为面试的一部分,而非代码高尔夫。

什么签名?

 // arr is not changed, use `const`
 // array indexing best done with `size_t`              
 int* multTwo(const int* arr, size_t len) {

需要大小并显示错误处理。也许在arr == NULL

时会检测len > 0
 need = len;
 // if lead element is 5 or more, add 1.
 // Error if element is not in 0-9 range

分配内存。分配给可变去引用类型的大小比编码变量类型更不容易出错,更容易查看和维护。在C面试中显示维护问题是一件很好的事情。考虑以后的代码是否更改为unsigned char* multTwo(const unsigned char* arr, size_t len) {,无需更改newarr = malloc(sizeof *newarr * need)

 newarr = malloc(sizeof *newarr * need)

检查分配。分配0可以返回NULL。然而,这个例程仍然应该分配1个字节,有点浪费,以确保NULL返回是错误。与面试官讨论的问题很好。表明您希望清楚地了解客户的需求,不仅仅是功能,而是角落案例。

 if (newarr == NULL && need > 0) fail()

循环并填充新数组,就像使用有意义的变量名称编码的OP并使用无符号数组索引一样。

 size_t arr_i=len;
 size_t newarr_i=need;
 int carry = 0;
 while (arr_i > 0) 
   sum = arr[--arr_i]*2 + carry;
   newarr[--newarr_i] = sum%10;
   carry = sum/10;
 }
 if (carry) {
   newarr[--newarr_i] = carry;
 }

返回newarr

答案 2 :(得分:1)

我首先要查看arr中的第一个数字是否为5或更多,以检查newarr数组是否需要比原始数组大1。

这样的初始化:

int* newarr;
int  newlen;
if (*arr >= 5)
     newlen = len + 1; 
else
     newlen = len;

newarr = (int*)malloc(sizeof(int) * newlen);   
memset(newarr, 0, newlen); //initialize all newarr values to 0

现在显然我们现在必须进行乘法运算。为了得到1的数字,我们使用模运算符%,为了获得10位数,我们使用除法运算符/。当然,如果乘法值为10或更大,我们只需要进行除法。所以我们填充newarr的循环看起来像这样:

int i, temp;
for (i = 1; i <= len; i++) {
    temp = *(arr + i - 1) * 2;
    if (temp < 10) {
        *(newarr + i - 1) += temp;
    }
    else {
        *(newarr + i - 1) += temp / 10; //inset 10's digit
        *(newarr + i) += temp % 10; //inset 1's digit 
    }

}

所以我们的全部功能最终成为

#include <stdlib.h>
#include <string.h>

int* multTwo(int* arr, int len)
{

    int* newarr;
    int  newlen;
    if (*arr >= 5)
        newlen = len + 1; 
    else
        newlen = len;

    newarr = (int*)malloc(sizeof(int) * newlen);   
    memset(newarr, 0, newlen); //initialize all newarr values to 0

    int i, temp;
    for (i = 1; i <= len; i++) {
        temp = *(arr + i - 1) * 2;
        if (temp < 10) {
            *(newarr + i - 1) += temp;
        }
        else {
            *(newarr + i - 1) += temp / 10; //insert 10's digit
            *(newarr + i) += temp % 10; //inset 1's digit 
        }

    }
    return newarr; //don't forget to free once you're done with newarr!        
}