Linkedin Interview Question
Front-end Software EngineersCountry: United States
Interview Type: Phone Interview
This is my C# solution to the problem, unfortunately I couldn't be able to write it on time due to my nerves! Best of luck guys!
public static bool IsNumber(string number)
{
int n = number.Length, dots = 0;
if (number[0] == '.' || number[n - 1] == '.' || number[n - 1] == '-')
return false;
if ((number[0] < 48 || number[0] > 57) && number[0] != '-')
return false;
for (var i = 1; i < n; i++)
{
if (dots > 1)
return false;
if (number[i] < 48 || number[i] > 57)
{
if (number[i] == '.')
{
if (i == 1 && number[0] == '-')
return false;
else
dots++;
}
else
return false;
}
}
return true;
}
int
is_num(char *ch)
{
char c = *ch;
return ((c >= '0') && (c <= '9'));
}
int
IsNumber(char *str)
{
int is_number = 1;
assert(str);
while (*str != '\0') {
if (is_num(str) == 0) {
is_number=0;
break;
} else {
str++;
}
}
if (is_number) {
printf("string is a number.\n");
} else {
printf("string is NOT a number.\n");
}
return (is_number);
}
public static boolean isNumber(String str)
{
char[] charArray=str.toCharArray(); /*in java internally String is maintained as charecter
array, so atleast we have to use this function*/
char strt='0';
char end='9';
for(char ch: charArray)
{
if(ch<strt || ch> end)
return false;
}
return true;
}
Lets assume that string is represented as a sequence of ASCII chars. Hence there exist mapping char -> int. Next you know that in this preresentations characters 0-9 is a continuous sequence. Given a string, for each of its character check if it is a character between '0' and '9'.
A sample code in java is shown below:
public boolean isNumber(String s) {
for (char c : S)
if (c < '0' || c > '9') return false;
return true;
}
Not sure how it would work for Unicode but I think it should. I the number was negative, just check for char '-' at position 0.
I forgot to put some test cases like:
incorrect numbers: "-.15", "12.3-", "4fe", ".15", "15.", "15-", "1-5" // return false
correct numbers: "154", "-23", "15.36", "-1.25" // return true
In some languages like C# above mentioned condition fails as 'c' returns ASCII code not the actual number in the above statement.
So we should use the condition as
public boolean isNumber(String SrcStr)
{
foreach (char c in SrcStr)
{
if (c-'0' < '0' || c-'0' > '9')
{
return false;
}
}
return true;
}
* ad folats: you are right, it handles only positive integers, the code was to demonstrate the approach.
* ad C#: First, it is a java code, second, as you said, I am also comparing ASCII codes and take advantage of the fact that digit characers follows each other in a single sequence in ASCII representation. Do you agree?
Please give some feedback on this code. Thanks!
public static boolean isNumber(String input)
{
boolean dotFlag=true; // to check dot occurs only once for floating numbers
for(int k=0; k< input.length(); k++)
{
final char c= input.charAt(k);
if ( ( c == '.' ) && (k != input.length() -1 ) && dotFlag ) // Dot can appear only once and not at last position
{
dotFlag=false;
continue;
}
if( ( (c == '-') || ( c== '+' ) )&& k == 0 ) continue; // Negative/Postive sign can appear only at beginning
if ( (c >= '0') && (c <= '9') ) continue;
return false;
}
return true;
}
If they ask this you're probably meant to ask to specify what kind of numbers they want. If it's integers, the solutions is simple:
def isNumber(num):
return all(x in ['1','2','3','4','5','6','7','8','9','0'] for x in num)
If they also want numbers which have decimal part in them, you'll have to check for the separator, which is usually a dot but varies, eg comma is quite common too.
As noted - "without using built in functions". The point here is to actually write an algorithm to do it yourself, not to use the framework. Since his original solution was C#, he could have just written "return double.TryPrase(num, out result);" if framework calls were allowed.
class CheckFormat{
public static boolean isNumber(String input){
char[] arr = input.toCharArray();
boolean isNumber = true;
boolean isDotted = false;
for(int n = 0; n < arr.length; n++){
if(arr[n] == '-' && n == 0)
continue;
else if(((arr[n] - '0') >= 0) && ((arr[n]-'0') <= 9))
continue;
else if(arr[n] == '.' && !isDotted){
isDotted = true;
continue;
}
else{
isNumber = false;
break;
}
}
if(isDotted && (arr[arr.length - 1] == '.'))
isNumber = false;
return isNumber;
}
}
Here is C++ version of solution
#include<string>
#include<iostream>
using namespace std;
bool is_sign(char c)
{
return (c=='+' || c =='-');
}
bool is_num(char c)
{
return (c>='0' && c<='9');
}
bool IsNumber(string num)
{
bool hasDot = false;
bool hasNum = false;
for(int i = 0; i < num.length(); i++)
{
if (num[i] == ' ')
continue;
if (i ==0)
{
if (!is_sign(num[i]) && !is_num(num[i]))
return false;
hasNum = is_num(num[i]);
} else if (num[i] == '.')
{
if (hasDot)
return false;
if (!hasNum)
return false;
if (i == num.length()-1)
return false;
hasDot =true;
} else {
if(!is_num(num[i]))
return false;
if (!hasNum)
hasNum = true;
}
}
return (hasNum);
}
// ASCII of numbers 0-9 is 48-57, ASCII of . is 46, ASCII of - is 45, ASCII of , is 44, ASCII of + is 43
public boolean isNumber(String str){
if(str == null || str.isEmpty()) return false;
boolean answer = true;
int temp = str.charAt(0);
if(temp >=48 && temp<57){
answer = answer && true;
}else if(temp==45 || temp == 43){
answer = answer && true;
}
for(int i=1; i< str.length(); i++){
temp = str.charAt(i);
if(temp >= 48 && temp <= 57){
answer = answer & true;
} else if(temp == 46 || temp == 44){
answer = answer && true;
} else {
answer = false;
break;
}
}
return answer;
}
Cases considered are
System.out.println("isNumber " + lq.isNumber("0123"));
System.out.println("isNumber " + lq.isNumber("123.67"));
System.out.println("isNumber " + lq.isNumber("-8"));
System.out.println("isNumber " + lq.isNumber("-12.ab12345"));
System.out.println("isNumber " + lq.isNumber("12,345"));
System.out.println("isNumber " + lq.isNumber("+98987"));
System.out.println("isNumber " + lq.isNumber("98-987"));
public class Number {
private enum State {
INIT, SIGN, INTEGER, DOT, FRACTION
}
public static boolean isNumber(String str) {
// RegEx: [+-]? [0-9]+ (\.[0-9]+)?
State state = State.INIT;
for (final char ch : str.trim().toCharArray()) {
switch (state) {
case INIT:
if (ch == '+' || ch == '-') {
state = State.SIGN;
} else if (ch >= '0' && ch <= '9') {
state = State.INTEGER;
} else {
return false;
}
break;
case SIGN:
if (ch >= '0' && ch <= '9') {
state = State.INTEGER;
} else {
return false;
}
break;
case INTEGER:
if (ch == '.') {
state = State.DOT;
} else if (ch < '0' || ch > '9') {
return false;
}
break;
case DOT:
if (ch >= '0' && ch <= '9') {
state = State.FRACTION;
} else {
return false;
}
break;
case FRACTION:
if (ch < '0' || ch > '9') {
return false;
}
break;
}
}
return (state == State.INTEGER || state == State.FRACTION);
}
public static void main(String[] args) {
final String str[] = { "1", "10", "0123", "-20", "+40", ";", "10.", "-", "-23.45" };
for (final String s : str) {
System.out.println("Test: \"" + s + "\" is" + ((Number.isNumber(s)) ? " " : " not ") + "a number");
}
}
}
Javascript:
function isNumber(str) {
var dotFlag = false;
for (var i=0, len=str.length; i<len; i++) {
var c = str[i];
// removes preceding - or +
if (!i && c == '-' || c == '+') {
continue;
}
// if dot
if (c == '.') {
// if already found before
if (dotFlag) {
return false;
}
// save for next time
dotFlag = true;
} else if (!(c < 10)) {
return false;
}
}
return true;
};
Clear java solution with custom string iterator (accepted on Leetcode):
leetcode.com/problems/valid-number/
public class Solution
{
/** A helper class for iterating over string characters (more like a queue) */
private static class StringIterator
{
private final String str;
private int index;
public StringIterator(String str)
{
this.str = str;
this.index = -1;
}
/** True, if the next character is one of the characters from the string */
public boolean checkNext(String chars)
{
return hasNext() && chars.indexOf(peek()) != -1;
}
/** True, if the next character is one of the characters from the string + skip it */
public boolean skipNext(String chars)
{
if (checkNext(chars))
{
next();
return true;
}
return false;
}
/** Has more characters */
public boolean hasNext()
{
return index + 1 < str.length();
}
/** Check the next character without removing it */
public char peek()
{
return str.charAt(index + 1);
}
/** Remove and return next character */
public char next()
{
return str.charAt(++index);
}
/** Number of available characters */
public int available()
{
return str.length() - (index + 1);
}
}
private enum DigitBase
{
Dec, // decimal
Hex, // hexadecimal
}
public boolean isNumber(String s)
{
s = s.trim();
if (s.length() == 0) return false;
StringIterator iter = new StringIterator(s);
// check sign
if (iter.skipNext("+-") && !iter.hasNext()) return false;
// if only one char is available - it should be a digit
if (iter.available() == 1) return isValidDigit(iter.next(), DigitBase.Dec);
DigitBase digitBase = DigitBase.Dec; // decimal by default
boolean hasIntegerPart = false;
boolean hasFracPart = false;
// check next numbers
if (iter.skipNext("0"))
{
// simple zero
if (!iter.hasNext()) return true;
if (iter.skipNext("xX"))
{
if (!iter.hasNext()) return true;
digitBase = DigitBase.Hex;
}
else
{
hasIntegerPart = true;
}
}
boolean hasDecimalPoint = false;
boolean hasExponent = false;
// check chars one by one
while (iter.hasNext())
{
char c = iter.next();
if (c == ' ')
{
return false; // can't have any spaces
}
else if (c == '.')
{
// can only have a single decimal point and no exponent yet
if (hasDecimalPoint || hasExponent || digitBase != DigitBase.Dec) return false;
hasDecimalPoint = true;
}
else if (isValidDigit(c, digitBase)) // valid character for the selected base
{
if (hasDecimalPoint)
{
hasFracPart = true; // if decimal point was found - then we have a fracture part
}
else if (!hasExponent)
{
hasIntegerPart = true; // if exponent was not found - we have an integer part
}
}
else if (oneOf(c, "eE")) // found exponent?
{
if (!iter.hasNext()) return false; // if no character after - invalid number
// we should have a single exponent and at least either an integer or a fracture part
if (hasExponent || !hasIntegerPart && !hasFracPart) return false;
hasExponent = true;
// an optional +/- sign
if (iter.skipNext("-+") && !iter.hasNext()) return false;
digitBase = DigitBase.Dec; // HACK: only expect decimal digits
}
else
{
return false; // something unexpected
}
}
return true; // all good!
}
/** Is a valid digit for the selected base */
private boolean isValidDigit(char c, DigitBase digitBase)
{
switch (digitBase)
{
case Hex: return c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';
}
return c >= '0' && c <= '9';
}
/** True is char is one of the characters from the string */
private boolean oneOf(char c, String chars)
{
return chars.indexOf(c) != -1;
}
}
A clear java solution with a custom string iterator (accepted on LeetCode):
public class Solution
{
/** A helper class for iterating over string characters (more like a queue) */
private static class StringIterator
{
private final String str;
private int index;
public StringIterator(String str)
{
this.str = str;
this.index = -1;
}
/** True, if the next character is one of the characters from the string */
public boolean checkNext(String chars)
{
return hasNext() && chars.indexOf(peek()) != -1;
}
/** True, if the next character is one of the characters from the string + skip it */
public boolean skipNext(String chars)
{
if (checkNext(chars))
{
next();
return true;
}
return false;
}
/** Has more characters */
public boolean hasNext()
{
return index + 1 < str.length();
}
/** Check the next character without removing it */
public char peek()
{
return str.charAt(index + 1);
}
/** Remove and return next character */
public char next()
{
return str.charAt(++index);
}
/** Number of available characters */
public int available()
{
return str.length() - (index + 1);
}
}
private enum DigitBase
{
Dec, // decimal
Hex, // hexadecimal
}
public boolean isNumber(String s)
{
s = s.trim();
if (s.length() == 0) return false;
StringIterator iter = new StringIterator(s);
// check sign
if (iter.skipNext("+-") && !iter.hasNext()) return false;
// if only one char is available - it should be a digit
if (iter.available() == 1) return isValidDigit(iter.next(), DigitBase.Dec);
DigitBase digitBase = DigitBase.Dec; // decimal by default
boolean hasIntegerPart = false;
boolean hasFracPart = false;
// check next numbers
if (iter.skipNext("0"))
{
// simple zero
if (!iter.hasNext()) return true;
if (iter.skipNext("xX"))
{
if (!iter.hasNext()) return true;
digitBase = DigitBase.Hex;
}
else
{
hasIntegerPart = true;
}
}
boolean hasDecimalPoint = false;
boolean hasExponent = false;
// check chars one by one
while (iter.hasNext())
{
char c = iter.next();
if (c == ' ')
{
return false; // can't have any spaces
}
else if (c == '.')
{
// can only have a single decimal point and no exponent yet
if (hasDecimalPoint || hasExponent || digitBase != DigitBase.Dec) return false;
hasDecimalPoint = true;
}
else if (isValidDigit(c, digitBase)) // valid character for the selected base
{
if (hasDecimalPoint)
{
hasFracPart = true; // if decimal point was found - then we have a fracture part
}
else if (!hasExponent)
{
hasIntegerPart = true; // if exponent was not found - we have an integer part
}
}
else if (oneOf(c, "eE")) // found exponent?
{
if (!iter.hasNext()) return false; // if no character after - invalid number
// we should have a single exponent and at least either an integer or a fracture part
if (hasExponent || !hasIntegerPart && !hasFracPart) return false;
hasExponent = true;
// an optional +/- sign
if (iter.skipNext("-+") && !iter.hasNext()) return false;
digitBase = DigitBase.Dec; // HACK: only expect decimal digits
}
else
{
return false; // something unexpected
}
}
return true; // all good!
}
/** Is a valid digit for the selected base */
private boolean isValidDigit(char c, DigitBase digitBase)
{
switch (digitBase)
{
case Hex: return c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F';
}
return c >= '0' && c <= '9';
}
/** True is char is one of the characters from the string */
private boolean oneOf(char c, String chars)
{
return chars.indexOf(c) != -1;
}
}
- Bharat Kumar Arya January 13, 2015