对于我目前正在实现的算法,我需要处理上一步,我不完全确定它在计算上易于处理。此步骤需要为任意n
生成长度为n
的所有二进制单词(它可能很大,但实际上不应大于50)。如果我记得很清楚,这具有指数复杂性(O(2^n)
),这是不好的。
一个天真的递归实现可能如下:
def gen(n: Int, acc: List[String]) : List[String] = {
if (n == 0) {
acc
} else {
if (acc.length == 0) {
gen(n - 1, List("0", "1"))
} else {
gen(n - 1, (for (i <- acc) yield i ++ "0") ++ (for (j <- acc) yield j ++ "1"))
}
}
}
gen(4, List()) //List(0000, 1000, 0100, 1100, 0010, 1010, 0110, 1110, 0001, 1001, 0101, 1101, 0011, 1011, 0111, 1111)
这适用于小型n
,并在n
增加时快速冻结我的计算机。
这个问题也可以看作是获得所有自然数[0,2^n - 1]
的二进制表示,它可以很容易地并行化,但是这对于n
的大值无论如何都不起作用,因为元素是巨大的。
即使这是可能的,另一个问题是大多数数据结构都有一个限制大小(大多数数据Int.MaxValue
),但这是另一个故事:)
这个问题确实有解决方案吗?
答案 0 :(得分:1)
由于private int updateContact(int Id,
String contactresult, String alternatecontactresult,
Integer prevContactSeq) {
StringBuffer contactQuery =new StringBuffer();
contactQuery.append("Update contacttable ");
contactQuery.append(" Set phone1=?,");
contactQuery.append(" phone2 =?");
contactQuery.append(" Where contactSeq=?");
contactQuery.append(" And id=?");
System.out.println("Contact Update Query "+contactQuery.toString());
try{
JdbcTemplate jdbcTemplate = this.getJdbcTemplate();
return jdbcTemplate.update(contactQuery.toString(), new Object[] {Long.parseLong(contactresult),Long.parseLong(alternatecontactresult),prevContactSeq,Id});
}catch(DataAccessException dae){
dae.printStackTrace();
//error in making the database update. return 0 to identify that the database update failed
return 0;
}
}
显然支持Long.parseLong
- 我对Scala中的编码没有丝毫的线索 - 你可以简单地用它来表示这些词。其余的很简单:
所有长度为scala
的二进制字都在BigInteger
中。只需从0开始作为起始值和增量:
n
或
[0 , 1 << n)
这将产生按字典顺序排列的所有单词
更重要的问题是:如果for (bint <- 0L until 1L << n)
process(bint)
,你已经结束了2 ^ 40个单词。即使你每个字只使用40位= 5个字节,你最终也会得到5TB的数据。我怀疑你是否有能力处理这么多数据。应该有一个比生成该列表更好的方法。
答案 1 :(得分:1)
您可以使用Stream:
类Stream实现了惰性列表,其中元素仅在需要时进行评估。
为您的场景创建一个非常简单的流:
def numbers(n: BigInt): Stream[BigInt] = n #:: numbers(n + 1)
然后,您可以使用take
来获取/生成n
第一个数字:
val stream = numbers(0).take(n)
然后将其转换为二进制String
表示形式:
val stream = numbers(0).take(10).map(_.toString(2))
这也会返回一个Stream。之后,您可以使用stream
执行任何操作,每个实例:
stream.foreach(println)
不确定性能影响,但它是您可以尝试的另一种选择。
答案 2 :(得分:0)
您可以使用范围来执行此操作。如果Integers不足以表示,则使用NumericRange over Long或BigInt:
val numbers = NumericRange[BigInt](0,1000,1)
您可以在需要时使用.toString(2)将数字转换为二进制字符串。您可以将范围转换为列表或任何您想要的。
然而,知道你需要什么是很好的。我想不出一个很好的理由来迭代那么多数字甚至存储它们。如果这是解决另一个问题的一部分,可能有更好的方法来解决它。