交换给定数字的交替数字而不使用数组

时间:2018-06-05 13:29:44

标签: c algorithm

交换给定数字的交替数字而不使用数组,例如:

 Input: 54687
Output: 45867

在不使用数组的情况下解决此问题的正确算法是什么?我在接受采访时被问到这个问题,但仍然无法找到正确的方法。

4 个答案:

答案 0 :(得分:2)

如果你不是一个数字理论家,你可以通过检查这两个数字之间的差异取得一些进展(如果我的人力资源部门坚持要求候选人提出这个问题,我认为这样做了我希望他们做什么)。如果你是一个数字理论家,那么答案就会很快从你的脑海中消失。这是一个正数;

  1. 前两位数位于1000s位置(例如a = 1000)。

  2. 前两位数字因-1而异(b = -1说;请注意签名约定。)

  3. 您需要将9 * a * b添加到Input。即-9000。交换前两位数字。然后我们继续:

  4. 接下来的两位数字位于10s位置(a = 10)。

  5. 数字相差+2b = 2

  6. 再次添加9 * a * b,即+180

  7. 强有力的候选人会指出Input可能太大而无法容纳int,具体取决于您的平台。

    请注意,通过重复整数除以10得到最高有效位的位置,直到达到0。

答案 1 :(得分:1)

这个问题只需要记住一个角色。在伪代码中:

forever {
    c = read()
    print(read())
    print(c)
}

请注意,您必须正确处理EOF:如果位数为奇数,则输出最后一个字符(即如果您在第一个EOF中获得read())。

请注意,甚至可以在不声明任何变量的情况下解决此问题(在C意义上)。为此,将问题视为DFA,对每个字符组合的信息进行编码(即转换为第一个字符的不同状态集)。

只是为了证明这一点(当然,不要用这种方式编写代码),例如DFA&#34; tree&#34;使用switch switchLive at ColiruDissassembly at Compiler Explorer)内的#include <stdio.h> int main(void) { for (;;) { switch (getchar()) { case '0': switch (getchar()) { case '0': putchar('0'); break; ... case '9': putchar('9'); break; default: putchar('0'); return 0; } putchar('0'); break; ... case '9': switch (getchar()) { case '0': putchar('0'); break; ... case '9': putchar('9'); break; default: putchar('9'); return 0; } putchar('9'); break; default: return 0; } } } 来C:

 <dependency>
   <groupId>org.apache.spark</groupId>
   <artifactId>spark-sql_2.11</artifactId>
   <version>2.3.0</version>
 </dependency>

答案 2 :(得分:1)

您可以将每对十进制数字视为基数为100的数字,并一次将其转换为基数为100的数字。唯一的&#34;技巧&#34;如果输入具有奇数个十进制数字,则保持最低有效十进制数字。

例如:

 Input │ Output │ Operation
═══════╪════════╪══════════════════════════════════════════════
 54687 │        │ Initial state
 5468  │      7 │ Keep least significant decimal digit,
       │        │ because odd number of decimal digits.
 54    │    867 │ Swap next two digits (68), and add to output.
       │  45867 │ Swap next two digits (45), and add to output.

在伪代码中,您可以将其实现为两个函数。第一个计算value中的小数位数,即ceil(log10(value))。你也可以这样做&#34;蛮力&#34;使用整数数据类型的方法:

Function DecimalDigits(value):
    Let  digits = 1

    While (value >= 10):
        Let  digits = digits + 1
        Let  value = value / 10    # Truncate, or round down
    End While

    Return digits
End Function

或略微&#34;优化&#34; version,通过计算十进制数字组来使用较少数量的除法和模数:

Function DecimalDigits(value):
    Let  digits = 1
    Let  value = value / 10
    While (value > 9999999):
        Let  digits = digits + 8
        Let  value = value / 100000000
    End While
    If (value > 999):
        Let  digits = digits + 4
        Let  value = value / 10000
    End If
    If (value > 9):
        Let  digits = digits + 2
        Let  value = value / 100
    End If
    If (value > 0):
        Let  digits = digits + 1
    End If

    Return digits
End Function

但对于真正的伪代码,表达意图应该足够了:

Function DecimalDigits(value):
    # Number of decimal digits in value
    Return ceil(log10(value))
End Function

实际的第二个函数进行成对变换:

Function SwapAlternateDigits(value):

    # Remember if negative. We operate on nonnegative 'value'.
    If (value < 0) Then:
        Let  value = -value
        Let  sign = -1
    Else:
        Let  sign = +1
    End If

    # If there is an odd number of digits,
    # keep the rightmost (least significant)
    # digit as-is.
    If (IsOdd(DecimalDigits(value))) Then:
        Let  result = value % 10
        Let  value = value / 10
        Let  base = 10
    Else:
        Let  result = 0
        Let  base = 1
    End If

    # Loop over the remaining pairs of decimal digits.
    While (value > 0):
        Let  lower = value % 10
        Let  value = value / 10
        Let  upper = value % 10
        Let  value = value / 10

        Let  result = result + base * (upper + 10 * lower)

        Let  base = base * 100
    End While

    Return sign * result
End Function

注意,在上面的两个伪代码函数中,/表示带截断的整数除法,%表示模运算符,与它们在例如它们中使用的方式相同。

base变量是10的幂,用于跟踪要添加到result的下一个数字对的位置。 lower是较低的十进制数字,upper是从value提取的高位十进制数字。显然,upper + 10*lower是交换时十进制数字对的值。

答案 3 :(得分:0)

怎么样:

int in = 354687;                // Input number   
int out = 0;                    // Output number
int decimal = 10;               // The current decimal we are working with
int subtractor = 0;             // Subtractor to make sure we ingore previous variables
int residue = 0;                // The current decimal's value

for (int i=1; i<8; i++){        // Limit to 8 chars

    // Move the current char
    residue = (in-subtractor)%decimal;
    if (i%2)                    // If even, need to move digit left
        out += residue * 10; 
    else                        // Else move digit right
        out += residue / 10;

    // Get ready for next time around
    subtractor += residue;
    decimal *= 10;
}

printf("\n\nOut: %d\n", in);
printf("Out: %d\n", out);