0

I came across a programming exercise and was stuck. The problem is:

You need to define a valid password for an email but the only restrictions are:

The password must contain one uppercase character and the password should not have numeric digit.

Now, given a String, find the length of the longest substring which is a valid password.

I am able to solve this in Java but not able to figure out how to do in javascript.

Here is my Java solution:

public int lengthOfLongestSubstring(String s) {
    int n = s.length();
    Set<Character> set = new HashSet<>();
    int ans = 0, i = 0, j = 0;
    while (i < n && j < n) {
        if (!set.contains(s.charAt(j))){
            set.add(s.charAt(j++));
            ans = Math.max(ans, j - i);
        }
        else {
            set.remove(s.charAt(i++));
        }
    }
    return ans;
}
  • Am sure this is present somewhere on SO. Search for it before you start getting downvotes and close votes. – Rahul Apr 21 '17 at 06:11
  • I already did but I am not able to find it in javascript. –  Apr 21 '17 at 06:12
  • Based on given specifications I came up with [this regex](https://regex101.com/r/gbswYI/1/). Also provide some valid and invalid matches according to your specifications. – Rahul Apr 21 '17 at 06:13
  • It's there in the question already. –  Apr 21 '17 at 06:14
  • There could be many combinations like `aBa0a`. In this case should `aBa` considered as a match ? – Rahul Apr 21 '17 at 06:18
  • Yeah I think so. –  Apr 21 '17 at 06:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/142239/discussion-between-rahul-and-user5447339). – Rahul Apr 21 '17 at 06:23
  • 1
    see this http://stackoverflow.com/questions/5142103/regex-to-validate-password-strength .you can change this regex pattern as your wish . more explanation also there. – prasanth Apr 21 '17 at 06:24
  • Is there a specific reason why you would want to get the substring? Your case is easily solvable using regex. – MortenMoulder Apr 21 '17 at 06:34

4 Answers4

2

Use two Regular Expressions to validate desired strings: \D+ and [A-Z]:

try {
   var o = "a0Ba".match(/\D+/g).map(x => x.match(/[A-Z]/) ? x.length : -1);
   console.log(Math.max.apply(null, o));
} catch (e) {
   console.log(-1);
}
revo
  • 47,783
  • 14
  • 74
  • 117
  • Impressive code. Would it be an alternative to map `x => x.match(/[A-Z]/) ? x.length : -1` in line three and then do `Math.max.apply(null, arrayOfX)` saving yourself `filter`, `sort`, and `typeof`? (bow) – Björn Apr 21 '17 at 09:09
  • Thank you, applied. – revo Apr 21 '17 at 09:25
1

The password must contain one uppercase character and the password should not have numeric digit.

Based on your current specification following regex will match all valid sub-string from given string. From there on you can check for string lengths for longest sub-string.

Regex: (?=[^\d]*[A-Z])[^\d]+

Explanation:

(?=[^\d]*[A-Z]) will lookforward for non-digits followed by an Upper Case letter.

[^\d]+ will match more than one characters other than digits.

Regex101 Demo

Check out the following demo.

document.getElementById('btnfindLength').onclick = function() {
  // Try with input "aa0Baa0aaBaa00aa0Ba"
  var re = /(?=[^\d]*[A-Z])[^\d]+/g;
  var str = document.getElementById('st').value;
  var match;
  var len = 0;
  var longestSubString = null;
  do {
    match = re.exec(str);

    if (match != null) {
      console.log(match + " " + match[0].length);
      if (match[0].length > len) {
        longestSubString = match;
        len = match[0].length;
      }
    }
  } while (match);
  if (len != 0) {
    alert("Longest substring is `" + longestSubString + "` having length " + len);
  } else {
    alert('No substring found.');
  }
}
<input type="text" id="st">
<input type="button" id="btnfindLength" value="Find Length">
Rahul
  • 2,658
  • 12
  • 28
0

I've literally translated your Java code into Javascript code, but I'm not sure that your code works, anyway if you want to do it with Javascript, see follow:

function lengthOfLongestSubstring(s) {
    var n = s.length;
    var set = [];
    var ans = 0, i = 0, j = 0;
    while (i < n && j < n) {
        if (!set.indexOf(s.charAt(j))){
            set.push(s.charAt(j++));
            ans = Math.max(ans, j - i);
        }
        else {
            set = set.splice(s.charAt(i++), 1);
        }
    }
    return ans;
}

function test() {
  var input = document.getElementById("txtTest");
  var val = input.value;
  console.log(lengthOfLongestSubstring(val));
}
<input type="text" id="txtTest">
<input type="button" id="btnTest" onclick="test()" value="Test">
Alessandro
  • 4,382
  • 8
  • 36
  • 70
0

You can use .match() with RegExp /[\DA-Z]+/g to match one or more characters which are not digit characters, including uppercase letters. If no matches are found in string set variable to -1, else use .map(), RegExp.prptotype.test() to check if match contain [A-Z], if true, get .length of each matching substring, else return -1. Pass resulting array to Math.max() called with Function.prototype.apply() to get greatest number from resulting array of numbers.

let checkstr = str => {
  let matches = str.match(/[\DA-Z]+/g);
  return matches 
         ? Math.max.apply(Math
           , matches.map(match => /[A-Z]/.test(match) ? match.length : -1)) 
         : -1
};

console.log(checkstr("a0Ba"), checkstr("a0bb"), checkstr("aa0aaBa"));
guest271314
  • 1
  • 15
  • 104
  • 177
  • 1
    For string `aa0aaBa` this will also match `aa` as match. It should have atleast one Upper Case letter. – Rahul Apr 21 '17 at 06:37
  • For `a0bb` it gives 0 but instead it should give -1? –  Apr 21 '17 at 06:49