简体   繁体   中英

Write a function that returns the longest sequence of consecutive zeroes in a binary string

 //Write a function that returns the longest sequence of consecutive zeroes in a binary string. var arr = []; function zeroflow(str) { for (var i = 0; i < str.length; i++) { if (str[i] == 0) { var g = i + 1 do { g++; } while (str[g] == 0); arr.push(g - i); } } return arr; } document.write(zeroflow("00010000")); console.log(arr);

My goal here is to produce an array that stores all the sequence of consecutive zeros then pick the largest number in the array to find the longest sequence, but now this function is not even producing the right array.( The console log shows "3,2,6,4,3,2,2" I am looking for basic and simple methods, really appreciate your advice.

You can split on 1's, sort , pop and return the length:

 function zeroflow(str) { return str.split('1').sort().pop().length; } console.log(zeroflow("00010000")); console.log(zeroflow("1000100001")); console.log(zeroflow("000")); console.log(zeroflow("1")); console.log(zeroflow(""));

To keep it easy, following your code I've created this one. It simply loops though the str looking for zeroes. If he finds a zero, increments the counter by one. If finds something that is not a zero, pushes the current counter to the array and resets it to zero.

 function zeroflow(str) { var arr = []; var count = 0; for (var i = 0; i < str.length; i++) { if (str[i] == 0) { count++; } else if (count > 0) { arr.push(count); count = 0; } } if (count > 0) { arr.push(count); } return arr; } var arr = zeroflow("00010000"); console.log(arr);

Then you can sort the array and get the largest number:

 function zeroflow(str) { var arr = []; var count = 0; for (var i = 0; i < str.length; i++) { if (str[i] == 0) { count++; } else if (count > 0) { arr.push(count); count = 0; } } if (count > 0) { arr.push(count); } return arr; } var arr = zeroflow("00010000"); arr.sort(); console.log("Largest one is", arr[arr.length-1]);

BUT this is not optimal. You can get the largest one in the same loop:

 function zeroflow(str) { var count = 0; var largest = 0; for (var i = 0; i < str.length; i++) { if (str[i] == 0) { count++; } else if (count > largest) { largest = count; count = 0; } } if (count > largest) { largest = count; } return largest; } console.log("Largest one is", zeroflow("00010000"));

You can create a regex of your target character, /0+/g , to find runs of it. Once we've found each run using the regex, we can map each group to its length and take the max.

I recommend making your target character a parameter to promote reuse--there's no good reason to hard code this to only work on binary strings--and calling the function longestConsecutive , which is a bit more descriptive.

 const longestConsecutive = (s, c="0") => Math.max(...[...s.matchAll(new RegExp(c + "+", "g"))].map(e => e[0].length)) ; console.log(longestConsecutive("00010101000011"));

As for your original code, the issue you noticed is caused by failing to step i forward to meet g after g is used to detect a run, so we get extra garbage on the arr for each substring within a run. This won't impact correctness if you take the max of arr since the extra garbage values are always less than the max, so it's not an outright bug, per se, just inefficient and unintentional.

var g = i + 1; is a bug, though, because it skips the first element in a run. Just use var g = i; , since g++ inside the loop increments to the first element past the initial 0 character in a run. The other possible fix is to use a while instead of do..while .

Beyond that, arr should be scoped to the function, which is necessary to make the function idempotent , that is, returns the same result for a given parameter and isn't reliant on external (global) state.

Variable names can be improved to be less generic and more descriptive: zeroflow doesn't explain what the function does especially well, although it does sound cool. g doesn't tell me much, either, and arr could be clearer as runs .

Using type coercion with str[i] == 0 seems a little suspicious to me. Since you know you're working with strings, str[i] === "0" seems more accurate and expresses the intent more clearly.

 function zeroflow(str) { var runs = []; for (var i = 0; i < str.length; i++) { if (str[i] === "0") { var run = i; do { run++; } while (str[run] === "0"); runs.push(run - i); i = run; } } return Math.max(...runs); } document.write(zeroflow("00010000"));

A very simple algorithmic approach without array and any other special functions can be to store the count of zeroes in a variable and then reset it incase you encounter 1 and repeat this approach in the loop.

Have written a simple approach tried to cover all the scenarios.

 function zeroflow(str) { var prevCount = 0 var count = 0; var value = 0; for (var i = 0; i < str.length; i++) { if (str[i] == 0) { ++count; value = count } else { if (prevCount < count) { prevCount = count } count = 0 } } return value > prevCount ? value : prevCount } console.log(zeroflow("00010000")); console.log(zeroflow("00000")); console.log(zeroflow("11111")); console.log(zeroflow("00000010000")); console.log(zeroflow("000000010000")); console.log(zeroflow("00010100000")); console.log(zeroflow("00000100100")); console.log(zeroflow("0000010000000000100")); console.log(zeroflow("001000100000010000100"));

Hope it helps. Revert for any doubts.

You can use nested while loops. The outer tracks the place in the array ( i ), while the inner increments a counter . Whenever the counter is greater than longest , it's value is assigned to longest , the value of current is also added to i to track the place in the array. You return longest when the outer loop is done.

 function zeroflow(str) { var longest = 0; // the longest sequence var current; // current sequence var i = 0; // counter while(i < str.length) { current = 0; // init current while (str[current + i] == 0) current++; // increment current while character is 0 longest = current > longest ? current : longest; // take the greater of current and longest i += (current || 1); // increment i by current (if not 0) or by 1 } return longest; } var result = zeroflow("00010000"); console.log(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM