2015-06-19 11 views
5

Giả sử tôi muốn biết chuỗi có chứa 5 số liên tục liên tiếp hay không.Làm thế nào để tìm số lượng cụ thể của các số liên tiếp liên tục có chứa trong một chuỗi bằng cách sử dụng javascript?

var a = "ac39270982"; // False 
var a = "000223344998"; // False 
var a = "512345jj7"; // True - it contains 12345 
var a = "aa456780"; // True - it contains 45678 

Có sẵn RegEx để thực hiện việc này không? Nó cũng sẽ có thể làm việc trong tình huống sau đây?

var a = "5111213141587"; // True 

Điều này phải đúng vì nó chứa 11,12,13,14,15.

Tôi không chắc chắn nếu có thể kiểm tra các ví dụ được cung cấp (số đơn, số có hai chữ số) cũng như số lớn hơn (ba chữ số, v.v.).

+0

Kiểm tra (không có regex) của bội số không quá khó: ROUND (string.length/5) cung cấp cho bạn số chữ số tối đa có thể. Tại sao lại sử dụng regex? –

+2

Làm thế nào để bạn biết nếu nó là '11,12,13,14,15' và không phải' 11,1,2, ... '? – chris85

+0

Bạn không thể làm điều này với các biểu thức thông thường. –

Trả lời

3

Tôi đã dành thời gian để thực hiện phương pháp tiếp cận Javascript 100% cho câu hỏi của bạn. Tôi đã làm cho nó chỉ đơn giản là phân tích cú pháp mỗi ký tự trong chuỗi và làm so sánh chỉ số nguyên. Điều này làm việc không chỉ cho năm số nguyên liên tiếp, nhưng nó hoạt động để kiểm tra phần mười là tốt (10, 20, vv). Bạn cũng có thể tăng/giảm số lượng so sánh nếu muốn.

Cảnh báo hợp lý: mặc dù phương pháp này có khả năng mở rộng nếu được mã hóa để tìm tất cả các loại kích thước số, bạn vẫn bị ràng buộc bởi sức mạnh tính toán và số so sánh. Đó là lý do tại sao tôi chỉ cung cấp mã cho các chữ số và phần mười, tôi để nó mở cho bạn/cộng đồng để quyết định cách mở rộng từ đây.

jsFiddle

Nếu bạn tình cờ cần biết thêm chi tiết về làm thế nào nó hoạt động sau đó cho tôi biết, tôi có thể tiếp tục làm rõ hoạt động bên trong của nó.

var str = "1111122asdgas222*&^%121314151617bdjfjahdi234bdce56789"; 
var consecutive = 5; // Number of comparisons 

// Single digits 
alert("It is " + consecutiveDigits(str, consecutive) + " that " + str + " contains " + consecutive + " consecutive digits."); 
// Tenths digits 
alert("It is " + consecutiveDigits(str, consecutive) + " that " + str + " contains " + consecutive + " consecutive tenths."); 

function consecutiveDigits(str, consecutive){ 
    var curr, 
     prev, 
     count = 0; 
    for(var i = 0; i < str.length; ++i) { 
     curr = parseInt(str.split('')[i]); 
     if(isNumeric(curr)) { 
      if(count === 0){ 
       ++count; 
      } 
      else if(prev + 1 === curr){ 
       ++count; 
       if(count === consecutive){ 
        return true; 
       } 
      } 
      prev = curr; 
     } 
    } 
    return false; 
} 

function consecutiveTenths(str, consecutive, iterations){ 
    var curr, 
     prev, 
     curr_tenth = 0, 
     prev_tenth = 0, 
     count = 0, 
     count_tenth = 0; 

    for(var i = 0; i < str.length; ++i) { 
     curr = parseInt(str.split('')[i]); 
     if(isNumeric(curr)) { 
      ++count; 
      if(count === iterations){ 
       curr_digit = (prev * 10) + curr; 
       alert(count_digit + " " + curr_digit + " " + prev_tenth); 
       if(count_digit === 0){ 
        ++count_digit; 
       } 
       else if(curr_tenth === (prev_tenth + 1)){ 
        ++count_digit; 
        if(count_digit === consecutive){ 
         return true; 
        } 
       } 
       prev_digit = curr_digit; 
       count = 0; 
      } 
      else { 
       prev = curr; 
      } 
     } 
     else { 
      count = 0; 
     } 
    } 
} 


function isNumeric(n) { 
    return !isNaN(parseFloat(n)) && isFinite(n); 
} 
+1

Điều này thật hoàn hảo! Awasome work @AGE –

1

Bạn có thể xây dựng regexp để xác thực nếu nó đúng hay không, nhưng bạn có thể gặp khó khăn khi truy lục toàn bộ chuỗi liên tiếp. Điều đó nói rằng RegExp sẽ là một chút cồng kềnh, nhưng bạn có thể tạo ra một chức năng để tạo ra các regexp cần thiết, tùy thuộc vào các thông số muốn. Xem đoạn:

function build_regexp(n) { 
 
    var string = ""; 
 
    for (var i = 0; i <= 14 - n; i++) { 
 
    var start_num = i 
 
    for (var j = 0; j < n; j++) { 
 
     string += (start_num++).toString() 
 

 
    } 
 
    string += "|"; 
 
    } 
 
    string = string.replace(/\|$/, ''); 
 
    return string 
 
} 
 

 

 
document.getElementById('check').onclick = function() { 
 
    var regex = new RegExp(build_regexp(document.getElementById('cons').value), "g"); 
 
    document.getElementById('regex').textContent = regex; 
 
    document.getElementById('result').innerHTML = (regex.exec(document.getElementById('to_check').value) || "false") 
 
}
<div id="regex"></div> 
 
<div>Enter wanted consecutive numbers: <input id="cons"></input></div> 
 
<div>Enter string to check: <input id="to_check"></input></div> 
 
<button id="check">check</button> 
 
<div id="result"></div>

2

EDIT: Thêm một đoạn mã & lỗi cố định trong numRegex

Để trả lời những trường hợp chung (tức là dãy liền kề của các chữ số tùy ý độ dài), bạn có thể làm điều gì đó như sau:

http://jsfiddle.net/ksgLzL9u/8/

/* Find a sequence of n > 1 contiguously increasing integers in input 
 
* 
 
* If sequence is found, return an object: 
 
* { 
 
*  start: <starting index of the sequence in input>, 
 
*  length: <length of the found sequence string>, 
 
*  first: <first number in the sequence> 
 
* } 
 
* 
 
* Otherwise, return null 
 
*/ 
 
function findSequence(input, n) { 
 
    var numRegex = /^(?:0|[1-9][0-9]*)$/; 
 

 
    // Try every starting position 
 
    for (var i = 0; i < input.length; ++i) { 
 
    // At the current starting position, try every length for the 1st number 
 
    for (var firstLen = 1; i + firstLen < input.length - 1; ++firstLen) { 
 
     var afterFirst = i + firstLen; 
 
     var first = input.slice(i, afterFirst); 
 
     
 
     // If the first string isn't an integer, move on 
 
     if (!numRegex.test(first)) { 
 
     continue; 
 
     } 
 

 
     // Convert the first string to an integer 
 
     var firstInt = parseInt(first, 10); 
 

 
     // Build what the rest of the string should look like following the 
 
     // first, in order to get a valid sequence 
 
     var rest = ""; 
 
     for (var j = 1; j < n; ++j) { 
 
     rest = rest.concat(firstInt + j); 
 
     } 
 

 
     // Compare to what actually follows the starting string; if it 
 
     // matches, then we have our sequence; otherwise, continue on 
 
     if (input.slice(afterFirst, afterFirst + rest.length) === rest) { 
 
      return { 
 
      start: i, 
 
      length: first.length + rest.length, 
 
      first: first 
 
      }; 
 
     } 
 
    } 
 
    } 
 
    return null; 
 
} 
 

 
$(function() { 
 
    function processChange() { 
 
    var input = $('#input').val(); 
 
    var n = parseInt($('#n').val()); 
 
     
 
    if (n > 1 && input.length) { 
 
     var result = findSequence(input, n); 
 
     if (result) { 
 
     $('#result').text(JSON.stringify(result, null, 2)); 
 
     var afterFirst = result.start + result.first.length; 
 
     var afterSeq = result.start + result.length; 
 
     $('#highlighted').empty() 
 
      .append($('<span/>') 
 
        .text(input.slice(0, result.start))) 
 
      .append($('<span/>') 
 
        .addClass('sequence') 
 
        .append($('<span/>') 
 
           .addClass('first') 
 
           .text(result.first)) 
 
        .append($('<span/>') 
 
           .text(input.slice(afterFirst, afterSeq)))) 
 
      .append($('<span/>') 
 
        .text(input.slice(afterSeq))); 
 
     } else { 
 
     $('#result').text("No sequence found"); 
 
     $('#highlighted').empty(); 
 
     } 
 
    } else { 
 
     $('#result').text(""); 
 
     $('#highlighted').empty(); 
 
    } 
 
    } 
 
    
 
    $('input,n').on("keyup mouseup", processChange); 
 
    processChange(); 
 
});
#input { 
 
    width: 50%; 
 
    min-width: 200px; 
 
} 
 

 
#n { 
 
    width: 50px; 
 
} 
 

 
.highlighted-result { 
 
    font-family: monospace; 
 
} 
 

 
.highlighted-result .sequence { 
 
    background-color: yellow; 
 
} 
 

 
.highlighted-result .first { 
 
    border: solid black 1px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> 
 
<h1>Input</h1> 
 
<div> 
 
    <input id="input" type="text" value="111121314155" placeholder="input"> 
 
    <input id="n" type="number" value="5" placeholder="n"> 
 
</div> 
 
<h1>Results</h1> 
 
<div id="highlighted" class="highlighted-result"></div> 
 
<pre id="result"></pre>

tôi đã không cố gắng để tối ưu hóa các giải pháp (ví dụ lặp lại firstLen có thể được đoản mạch và toàn bộ chuỗi rest không cần phải được tạo), nhưng tôi đã để nguyên thuật toán rõ ràng hơn.

Các vấn đề liên quan