1

I was recently asked this question in an interview(3+ experience). No String function allowed including String.length. I was given 5 minutes to write the complete code.

Example

String ="abcfedbca"
subString = "fed" 

Actually i asked him to elaborate a little more to which he said "it's easy java implementation what should i elaborate" and on basis of this question only he said my core java is very weak.

10
  • 7
    you're going to have to elaborate a bit more if you want anyone to understand what it is your asking... Commented Dec 11, 2013 at 20:48
  • 6
    Only correct answer: "I'm not a monkey. Because of that, I'm not interested in reinventing the wheel". Commented Dec 11, 2013 at 20:52
  • 2
    You didn't explain the question like a 3+ experience guy! Commented Dec 11, 2013 at 20:52
  • 1
    +1 @DwB This is a terrible interview question, IMO. Commented Dec 11, 2013 at 20:52
  • 4
    Anyone asking this question in an interview deserves the sassiest answer you can come up with. How about this: public String subString(String str, int i, int j) { p = Runtime.getRuntime().exec("echo " + str + "| cut -c"+i+"-"+j); p.waitFor(); return new BufferedReader(new InputStreamReader(p.getInputStream())).readLine();} (*NIX only) Commented Dec 11, 2013 at 20:56

7 Answers 7

3

Note that you're question is not very precise and hence your requirements are not very clear.

Simple way :

String st = new StringBuilder(s).substring(3,6); 

Or you can directly construct the new String using reflection to get the char array:

public static String substring(String s, int from, int to){
        Field f = String.class.getDeclaredField("value");
        f.setAccessible(true);
        char [] tab = (char[])f.get(s);
        f.setAccessible(false);
        return new String(tab, from, to - from);
}


Those can also be options (note that it works only if the original String fits an hexadecimal format) :

String s ="abcfedbca";
BigInteger bi = new BigInteger(s, 16);
bi = bi.and(new BigInteger("16699392")); //0xfed000 in hexa
bi = bi.shiftRight(12);
System.out.println(bi.toString(16));

Or more simple :

String s ="abcfedbca";
System.out.println(Integer.toHexString((int)(Long.parseLong(s, 16) & 16699392) >> 12));

If you want a more general method, this one might suits your case :

public static void main(String [] args){
    String s ="abcfedbca";
    System.out.println(substring(s, 2, 5, 9));
}

    public static String substring (String s, int from, int to, int length){
            long shiftLeft = 0;
            long shiftRight = (length - to - 1) * 4;
            for(int i = 0; i < to - from - 1; i++){
                shiftLeft += 15;
                shiftLeft = shiftLeft << 4;
            }
            shiftLeft += 15;
            return Long.toHexString((Long.parseLong(s, 16) & (shiftLeft << shiftRight)) >> shiftRight);
  }
Sign up to request clarification or add additional context in comments.

6 Comments

@PeterLawrey The OP is not allowed to use directly String functions "No String function allowed " (even though StringBuffer will use them, that's why I said the requirements were not very clear).
Given that StringBuffer was replaced by StringBuilder almost ten years ago, do you really need to use StringBuffer?
If synchronisation is required yes. If not, you're totally right that using a StringBuilder is the way to go.
I learn a new thing today =). So the conclusion is : should I always use a StringBuilder ?
IMHO, in the unlikely event you need a thread safe StringBuilder, synchronized/Lock it yourself (which is what you would end up having to do for StringBuffer but it wouldn't be as clear)
|
2

You can use a StringBuilder and call substring on it. Don't know whether that'd be allowed.

Here is the other way (although I am ashamed of this solution):

String str = "abcfedbca";
int from = 3, length = 3;
java.lang.reflect.Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
char[] value = (char[]) valueField.get(str);
char[] sub = new char[length];
System.arraycopy(value, from, sub, 0, length);
String substring = new String(sub);

Comments

1
String buff = "abcfedbca";
System.out.println("substring is = " + buff.substring(3, 6));

how about this?

1 Comment

Well StringBuffer constructor with a String parameter call super(str.length() + 16);
0

StringBuilder seems like a cheat to me since it's based on strings. I'd argue that you have to go down to byte primitives to meet the spirit of the test. Of course this calls getBytes which is technically a String function, so that breaks it also.

public static void main(String[] args) {
    String full ="abcfedbca";
    String desiredsubString = "fed";

    byte[] fullByte = full.getBytes();  
    byte[] desiredByte = desiredsubString.getBytes();
    byte[] foundStorage = new byte[desiredByte.length];

    boolean foundStart = false;
    int inserted = 0;

    for (byte b : fullByte) {
        if ( !foundStart && (b == desiredByte[0]) )
        {
            foundStorage[0] = b;
            inserted++;
            foundStart = true;
        }
        else if (foundStart && (inserted < foundStorage.length))
        {
            foundStorage[inserted] = b;
            inserted++;

            if ( inserted >= foundStorage.length )
            {
                break;
            }
        }
    }

    System.out.println("These should be equal: " + new String(desiredByte).equals(new String(foundStorage)));

}

1 Comment

I think String.getBytes can be considered a "string method".
0

Maybe:

    String value = "abcfedbca";
    BigInteger bi = new BigInteger(value, 16);
    bi = bi.divide(BigInteger.TEN);
    bi = bi.divide(BigInteger.TEN);
    bi = bi.divide(BigInteger.TEN);
    bi = bi.divide(BigInteger.TEN);
    bi = bi.divide(BigInteger.TEN);
    bi = bi.divide(BigInteger.TEN);
    bi = bi.divide(BigInteger.TEN);     
    int val = bi.subtract(BigInteger.valueOf(535)).intValue();
    String hex = Integer.toHexString(val);  

    System.out.println(hex);

Output: fed

Comments

0

How about using a JPasswordField to get the chars:

private static String substring(String str, int beginIndex, int endIndex) {
    return new String(new JPasswordField(str).getPassword(), beginIndex, endIndex - beginIndex);
}

And the String constructor is not a String method, isn't it?

Comments

0
public String submethod(String data, int firstindex, int lastindex) {
        char[] chars=data.toCharArray();
        char[]charnew= new char [lastindex];
        for(int i=firstindex; i< lastindex;i++) {
            charnew[i]=chars[i];
        }
        return new String(charnew); 
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.