将字符串转换为等效数字的复杂性是多少,反之亦然?它是否会根据编程语言而改变?
从表面上看,需要遍历整个字符串以将其转换为数字,因此它是 O(n),还是使用了一些类型转换?
当我写一个程序检查一个给定的数字是否是一个回文时,出现了这个疑问。一种方法是将数字除以基数(此处为10),累加数字,并将它们放在一起。示例:309/10 = rem(9),30/10 = rem(0),3/10 = rem(3)。我们得到903。
我采用的另一种方法是将此数字转换为字符串,并且由于字符串具有分割,反转等成员函数的负载,因此代码更短更清晰,但这是最好的方法吗?
答案 0 :(得分:14)
数字字符串是以位置表示法格式化的数字 - 因此需要考虑每个数字的值乘以基数的幂,以便将数字转换为二进制格式。
所以是的,这是一个O(N)操作,因为随着更多数字的添加,运行时间会线性增加。但是,在实践中,N可能受到语言支持的任何数值数据类型的限制(例如int32_t,int64_t)。但是如果使用任意精度数字类型(某些语言,如Python,默认使用)那么数字的数量没有限制(显然除了可用内存)。
答案 1 :(得分:4)
要转换为数字,您必须始终阅读所有数字。所以它至少是O(n)
。
现在做类似(伪代码)的事情
a = 0
foreach digit in string
do
a = 10 * a + digit
end
是O(n)
。所以复杂性是O(n)
答案 2 :(得分:0)
C#和C / C ++在表示(可能)数值的字符串中没有任何特殊信息。因此,他们需要在转换时逐位解析字符串。
但是,位数是有限的,所以我们只有O(1):转换时间有界(通常是最大数字的转换)。对于32位int,转换必须考虑最多10个十进制数字(可能还有一个符号)。
从字符串转换实际上也是O(1),因为在解析它时,只考虑有限数量的字符(在32位int的情况下为10 + 1)。
严格来说,我们不能使用O
- 符号表示int-to-string转换的情况,因为int的最大值是有界的。无论如何,转换所需的时间(在两个方向上)都受到常数的限制。
正如@Charles建议的那样,其他语言(Python)实际上可以使用任意精度的数字。对于解析此类数字,时间为O(number of digits)
,两次转换分别为O(string length)
和O(log(number))
。对于任意精度的数字,人们不能更快地做到这一点,因为对于两次转换,必须考虑每个数字。对于有限精度数字的转换,适用相同的O(1)
推理。但是我自己并没有在Python中分析解析,因此可能会使用效率较低的算法。
O(input length)
。如果已知字符串被裁剪,则转换再次为O(1)
。
答案 3 :(得分:0)
我有理由相信,处理纯数字运算符(在c ++和c#中我认为它将是“%”模数运算符)如果编码正确会更有效,因为在某种程度上你必须检查类似功能(结束与开头匹配)并执行字符串和数字之间的转换只会增加操作的复杂性,如果您可以执行相同的操作而不执行该转换。
那就是说,我不担心数字和字符串之间转换的性能影响,因为与程序的大多数其他方面的性能影响相比,它可能是微不足道的。数字类型限制为64位,这会对您计划解析的数字位数设置相对较低的上限,除非您正在实现/使用自定义编码的大数字类型。
您不必担心复杂性为O(n),其中n是数字的大小。它更像是O(n),其中n是数字的位数(具有我提到的低上限)或(如另一个答复中所述)O(log(n)),如果n是数字的大小。相对不显着的绩效影响。
现在,如果按照你的建议,你对N没有限制(这是不可能的,因为有2 GB的RAM,你只能存储多达20亿个数字的数字),那么我们可能需要更多考虑性能执行数学运算符。考虑这个大数字类型的“%”和“/”运算符的性能。但后来才意识到,为了将数字转换为字符串,无论如何它基本上都是使用相同的运算符。再一次,如果你做对了,就不能直接把它作为一个数字来处理。
答案 4 :(得分:0)
如果您要将数字N转换为字符串。它需要O(log(N))和10。(如果除以10并保留余数) 如果要转换长度为N的字符串,则需要O(N)。 (如果你使用的算法会不断增加数字10 ^(N)*数字(N))
如果你使用不属于你的函数(假设是字符串),你只能期望它们更慢。