交换给定数字的交替数字而不使用数组,例如:
Input: 54687
Output: 45867
在不使用数组的情况下解决此问题的正确算法是什么?我在接受采访时被问到这个问题,但仍然无法找到正确的方法。
答案 0 :(得分:2)
如果你不是一个数字理论家,你可以通过检查这两个数字之间的差异取得一些进展(如果我的人力资源部门坚持要求候选人提出这个问题,我认为这样做了我希望他们做什么)。如果你是一个数字理论家,那么答案就会很快从你的脑海中消失。这是一个正数;
前两位数位于1000s位置(例如a = 1000
)。
前两位数字因-1
而异(b = -1
说;请注意签名约定。)
您需要将9 * a * b
添加到Input
。即-9000
。交换前两位数字。然后我们继续:
接下来的两位数字位于10s位置(a = 10
)。
数字相差+2
(b = 2
)
再次添加9 * a * b
,即+180
。
强有力的候选人会指出Input
可能太大而无法容纳int
,具体取决于您的平台。
请注意,通过重复整数除以10得到最高有效位的位置,直到达到0。
答案 1 :(得分:1)
这个问题只需要记住一个角色。在伪代码中:
forever {
c = read()
print(read())
print(c)
}
请注意,您必须正确处理EOF
:如果位数为奇数,则输出最后一个字符(即如果您在第一个EOF
中获得read()
)。
请注意,甚至可以在不声明任何变量的情况下解决此问题(在C意义上)。为此,将问题视为DFA,对每个字符组合的信息进行编码(即转换为第一个字符的不同状态集)。
只是为了证明这一点(当然,不要用这种方式编写代码),例如DFA" tree"使用switch
switch
(Live at Coliru,Dissassembly 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
注意,在上面的两个伪代码函数中,/
表示带截断的整数除法,%
表示模运算符,与它们在例如它们中使用的方式相同。 c
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);