我最近遇到了这个问题--给定一个二进制字符串,检查我们是否可以将字符串分割成0..n个部分,使每个部分都是5的次方。返回拆分的最小数目,如果可以的话。
例如:
input = "101101" - returns 1, as the string can be split once to form "101" and "101",as 101= 5^1.
input = "1111101" - returns 0, as the string itself is 5^3.
input = "100"- returns -1, as it can't be split into power(s) of 5.
我想出了这个递归算法:
我在Java实施了上述algo。我相信它工作正常,但它是一个简单的递归解决方案。是否可以使用动态编程来改善运行时间?
代码如下:
public int partition(String inp){
if(inp==null || inp.length()==0)
return 0;
return partition(inp,inp.length(),0);
}
public int partition(String inp,int len,int index){
if(len==index)
return 0;
if(isPowerOfFive(inp,index))
return 0;
long sub=0;
int count = Integer.MAX_VALUE;
for(int i=index;i<len;++i){
sub = sub*2 +(inp.charAt(i)-'0');
if(isPowerOfFive(sub))
count = Math.min(count,1+partition(inp,len,i+1));
}
return count;
}
帮助程序函数:
public boolean isPowerOfFive(String inp,int index){
long sub = 0;
for(int i=index;i<inp.length();++i){
sub = sub*2 +(inp.charAt(i)-'0');
}
return isPowerOfFive(sub);
}
public boolean isPowerOfFive(long val){
if(val==0)
return true;
if(val==1)
return false;
while(val>1){
if(val%5 != 0)
return false;
val = val/5;
}
return true;
}
不是计算所有可能的子字符串,您可以检查5的幂的二进制表示,以搜索一个公共模式。使用类似于:
bc <<< "obase=2; for(i = 1; i < 40; i++) 5^i"
你得到:
51=1012=110012
54=10011100012
55=1100001101012
56=111101000010012
57=1001101001011012UB>
...
529=101000011000111100011111010111001101010111001000010111110010101010102
如您所见,5的奇数次幂总是以101
结尾,5的偶数次幂总是以模式10+1
结尾(其中+
表示一次或多次出现)。
您可以将输入字符串放入一个trie中,然后对其进行迭代,识别10+1
模式,一旦匹配,就对其进行计算,检查是否为假阳性。
以下是可以做的简单改进:
下面是我使用这些想法的解决方案:
public static List<String> powers = new ArrayList<String>();
public static int bestSplit = Integer.MAX_VALUE;
public static void main(String[] args) throws Exception {
// input string (5^5, 5^1, 5^10)
String inp = "110000110101101100101010000001011111001";
// calc all powers of 5 that fits in given string
for (int pow = 1; ; ++pow) {
String powStr = Long.toBinaryString((long) Math.pow(5, pow));
if (powStr.length() <= inp.length()) { // can be fit in input string
powers.add(powStr);
} else {
break;
}
}
Collections.reverse(powers); // simple heuristics, sort powers in decreasing order
// do simple recursive split
split(inp, 0, -1);
// print result
if (bestSplit == Integer.MAX_VALUE) {
System.out.println(-1);
} else {
System.out.println(bestSplit);
}
}
public static void split(String inp, int start, int depth) {
if (depth >= bestSplit) {
return; // can't do better split
}
if (start == inp.length()) { // perfect split
bestSplit = depth;
return;
}
for (String pow : powers) {
if (inp.startsWith(pow, start)) {
split(inp, start + pow.length(), depth + 1);
}
}
}
我还发现了另一种看起来非常快的方法。
input
字符串的5的所有幂。将这些字符串保存在powers
数组中。powers
数组的每个字符串power
:如果power
是input
的子字符串,则将其start
和end
索引保存到edges
数组(元组数组)中。edges
数组中的边找到从索引0
到索引input.length()
的最短路径。每个边具有相同的权重,因此使用BFS可以非常快地找到最短路径。我正在进行排序,并希望控制alpha值的cmp不区分大小写(即。https://perl6.org/archive/rfc/143.html). 有没有:我可能是这个的副词?
问题内容: 我想编写一个Java方法,如果字符串是回文,则返回true。 这是我到目前为止的内容: 我的问题是,它不考虑像这样的单词:回文。 在不区分大小写并忽略标点符号的情况下,测试这是否是回文式的最佳方法是什么。 问题答案: 使用此正则表达式删除所有标点和空格并将其转换为小写
如何根据列中项数的计数来分区DataFrame。假设我们有一个包含100人的DataFrame(列是和),我们希望为一个国家中的每10个人创建一个分区。 如果我们的数据集包含来自中国的80人,来自法国的15人,来自古巴的5人,那么我们需要8个分区用于中国,2个分区用于法国,1个分区用于古巴。 下面是无法工作的代码: null 有什么方法可以动态设置每个列的分区数吗?这将使创建分区数据集变得更加容易
本文向大家介绍MySQL查询以字符串字段中的数字字符对行进行分组?,包括了MySQL查询以字符串字段中的数字字符对行进行分组?的使用技巧和注意事项,需要的朋友参考一下 为此,您可以在+运算符的帮助下将0与字符串字段连接起来。这里的场景就像我们需要从字符串字段“ 9844Bob ”中获取数字“ 9844 ”。 让我们首先创建一个表- 使用插入命令在表中插入一些记录- 使用select语句显示表中的所
我读过spring batch中的分区,我发现了一个演示分区的示例。该示例从CSV文件中读取人员,进行一些处理,并将数据插入数据库。在本例中,1 partitioning=1 file,因此partitioner实现如下所示: 但如果我有一个10TB的文件呢?spring批处理是否允许以某种方式对其进行分区? 我尝试了以下方法来实现我的目标: 分为两步——第一步将文件分成若干部分,第二步处理第一步
问题内容: 如何在Java 8 Stream上实现“分区”操作?划分是指将流分成给定大小的子流。它在某种程度上与Guava Iterators.partition()方法相同,只是希望分区是延迟评估的Streams,而不是List的Streams。 问题答案: 将任意源流划分为固定大小的批次是不可能的,因为这会加重并行处理。并行处理时,你可能不知道拆分后的第一个子任务中有多少个元素,因此你无法为下