Split a string into a list of tokens I have the following assignment that I succeeded in solving, but the code is very inefficient.  I would appreciate if someone could show me a more efficient way, perhaps with substring. Note that I am not allowed to use imports or regexes or add more functions.

/**
 * Separates a given string into tokens, which are the "words" that are
 * separated by one or more occurrences of the given separator character.
 * Returns the tokens as an array of String values.
 */
public static String[] tokenize (String str, char separator) {
    // Removes all the occurrences of the separator at the beginning and end of str
    String source = trim(str, separator);
    String[] tokens = new String[charRunCount (source,separator)+1];
    String tmp = ""; // a string in order to take a word, then run over this string
    int j = 0;
    int i = 0;
    while (i &lt; tokens.length) {
        if ( source.charAt (j) != separator ) {
            do {
                tmp += source.charAt (j);
                if ( j &gt;= source.length () - 1 ) {
                    break;
                }
                else { // so that we math the source length
                    j++;
                }
            } while (source.charAt (j) != separator); 
        }
        if ( source.charAt (j) == separator ) {
            j++;
            while (source.charAt (j) == separator) {
                j++;
            }
        }
        tokens[i] = tmp;// taking the token into place
        tmp = ""; //resetting the token so we can begin anew

        i++;
    }
    return tokens;
}


the charRunCount() function:

public static int charRunCount(String str, char c){
    char last = 0;
    int counter = 0;
    for (int i = 0; i &lt; str.length(); i++) {
        // whenever a run starts.
        if (last != c &amp;&amp; str.charAt(i) == c) {
            counter++;
        }
        last = str.charAt(i);
    }
    return counter;
}
tmp is never a good name for a variable.  In this case, you should call it token instead, or perhaps word.  And you rightly complain that building strings using repeated += operations is inefficient, and correctly suggest that .substring() would be better.

Logically, then, you need to find the starting and ending indexes of each token!  So, let's define those helper functions (as private static functions):

/**
 * Considering str starting at startIndex, find the index at which the 
 * next token starts.
 *
 * @return The index of the start of a token (or str.length() if no more
 *         tokens).
 */
private static int start(String str, char sep, int startIndex) {
    int i;
    for (i = startIndex; i &lt; str.length() &amp;&amp; str.charAt(i) == sep; i++);
    return i;
}

/**
 * Considering str starting at startIndex, find the index at which the 
 * current token ends.
 *
 * @return The index just beyond the end of a token (the index of a
 *         sep character, or str.length() if this is the last token)
 */
private static int end(String str, char sep, int startIndex) {
    assert(str.charAt(sep) != sep);
    int i;
    for (i = startIndex; i &lt; str.length() &amp;&amp; str.charAt(i) != sep; i++);
    return i;
}


Then, we can use them in tokenize():

public static String[] tokenize(String str, char sep) {
    int tokenCount = 0;
    for (int s, e = 0; (s = start(str, sep, e)) &lt; str.length(); e = end(str, sep, s)) {
        tokenCount++;
    }
    String[] tokens = new String[tokenCount];
    tokenCount = 0;
    for (int s, e = 0; (s = start(str, sep, e)) &lt; str.length(); ) {
        tokens[tokenCount++] = str.substring(s, e = end(str, sep, s));
    }
    assert(tokens.length == tokenCount);
    return tokens;
}


Notice that now you can take advantage of the helper functions to predetermine the size of the array.  Also, a lot of the repetitiveness of your conditions and loops is eliminated.

All of the analysis is done using string indexes, so there is no string manipulation other than just the essential .substring() calls — and even the trim() call is gone!