我想在String varilable中导出位流模式。假设我们的比特流类似于bitStream =“111000001010000100001111”。我正在寻找一个Java代码来保存这个位流在一个特定的数组(假设bitArray)中,所有连续的“0”或“1”都保存在一个数组元素中。在这个例子中,输出将是这样的东西:
bitArray[0]="111"
bitArray[1]="00000"
bitArray[2]="1"
bitArray[3]="0"
bitArray[4]="1"
bitArray[5]="0000"
bitArray[6]="1"
bitArray[7]="0000"
bitArray[8]="1111"
我想使用bitArray来计算每个连续流中存储的位数。例如,在这种情况下,最终输出将是“3,5,1,1,1,4,1,4,4”。我弄清楚可能“拆分”方法会为我解决这个问题。但是我不知道分裂模式会对我做什么,如果我使用bitStream.split("1+")
它将分裂为连续的“1”模式,如果我使用bitStream.split("0+")
它将基于连续的“0”进行它是如何基于两者的?
Mathew提出了这个解决方案并且有效:
var wholeString = "111000001010000100001111";
wholeString = wholeString.replace('10', '1,0');
wholeString = wholeString.replace('01', '0,1');
stringSplit = wholeString.split(',');
我的问题是“此解决方案是最有效的吗?”
答案 0 :(得分:3)
尝试分别用“0,1”和“1,0”替换任何出现的“01”和“10”。然后,一旦注入了逗号,就使用逗号分隔字符串作为分隔符。
String wholeString = "111000001010000100001111"
wholeString = wholeString.replace("10", "1,0");
wholeString = wholeString.replace("01", "0,1");
String stringSplit[] = wholeString.split(",");
答案 1 :(得分:2)
您可以使用简单的正则表达式执行此操作。它匹配1和0,并将按照它们在流中出现的顺序返回每个。您如何存储或操作结果取决于您。这是一些示例代码。
String testString = "111000001010000100001111";
Pattern pattern = Pattern.compile("1+|0+");
Matcher matcher = pattern.matcher(testString);
while (matcher.find())
{
System.out.print(matcher.group().length());
System.out.print(" ");
}
这将产生以下输出:
3 5 1 1 1 4 1 4 4
存储结果的一个选项是将它们放在ArrayList<Integer>
由于OP希望效率最高,我做了一些测试,看看每个答案在一次大流上迭代10000次需要多长时间,并得出以下结果。在每次测试中,时间不同,但最快到最慢的顺序保持不变。我知道刻度性能测试有没有考虑系统负载的问题,但我只是想快速测试。
My answer completed in 1145 ms
Alessio's answer completed in 1202 ms
Matthew Lee Keith's answer completed in 2002 ms
Evgeniy Dorofeev's answer completed in 2556 ms
希望这有帮助
答案 2 :(得分:1)
我不会给你一个代码,但我会引导你找到一个可能的解决方案:
构造一个ArrayList<Integer>
,迭代位数组,只要你有1,递增一个计数器,只要你有0,就把计数器添加到ArrayList
。完成此程序后,您将拥有一个包含数字等的ArrayList
:[1,2,2,3,4] - 代表1和0的系列。
这将代表1&0和0的序列。然后构造一个大小为ArrayList
的数组,并相应地填充它。
时间复杂度为O(n),因为您只需要对数组进行一次迭代。
答案 3 :(得分:1)
此代码适用于任何字符串和模式,而不仅仅是1和0。通过char迭代char,如果当前char等于前一个char,则将最后一个char附加到List的最后一个元素,否则在列表中创建一个新元素。
public List<String> getArray(String input){
List<String> output = new ArrayList<String>();
if(input==null || input.length==0) return output;
int count = 0;
char [] inputA = input.toCharArray();
output.add(inputA[0]+"");
for(int i = 1; i <inputA.length;i++){
if(inputA[i]==inputA[i-1]){
String current = output.get(count)+inputA[i];
output.remove(count);
output.add(current);
}
else{
output.add(inputA[i]+"");
count++;
}
}
return output;
}
答案 4 :(得分:1)
试试这个
String[] a = s.replaceAll("(.)(?!\\1)", "$1,").split(",");
答案 5 :(得分:1)
我试图实施@Maroun Maroun解决方案。
public static void main(String args[]){
long start = System.currentTimeMillis();
String bitStream ="0111000001010000100001111";
int length = bitStream.length();
char base = bitStream.charAt(0);
ArrayList<Integer> counts = new ArrayList<Integer>();
int count = -1;
char currChar = ' ';
for (int i=0;i<length;i++){
currChar = bitStream.charAt(i);
if (currChar == base){
count++;
}else {
base = currChar;
counts.add(count+1);
count = 0;
}
}
counts.add(count+1);
System.out.println("Time taken :" + (System.currentTimeMillis()-start ) +"ms");
System.out.println(counts.toString());
}
我认为这是更有效的方式,因为他说它是O(n),你只迭代一次。因为获取计数的目标只是不将它存储为数组。我想推荐这个。即使我们使用正则表达式(内部也必须以任何方式迭代)
结果输出是
Time taken :0ms
[1, 3, 5, 1, 1, 1, 4, 1, 4, 4]
答案 6 :(得分:0)
试试这个:
String[] parts = input.split("(?<=1)(?=0)|(?<=0)(?=1)");