   the most difficult method I've ever tried to write
  Wow I am at a complete loss here guys. I'm not looking for the solutions but maybe someone could take an in-depth look at this and point me in the right direction here.It doesn't seem that complex until you roll up your sleeves and start tinkering around with a solution...I am writing a function (in Java) that takes a string, composed primarily of numbers, and initializes an array of shorts composed of the numbers in the string. The string is actually written in set notation, for example:String str = "3,5,7 - 14, 28, 56"Would imply that I need an array of twelve (12) shorts that looks like the following:short[] tempArray = { 3,5,7,8,9,10,11,12,13,14,28,56 };Ergo we would use the comma operator ',' to tokenize the string, and the hyphen operator '-' to identify ranges in between which numbers must be allocated. But here's the kicker(s):(1) The string comes from user input, and so I have to check for all sorts of error conditions (which I explain below).(2) The user can specify "odd" or "even" after a range, whereupon doing so only odd or even numbers are allocated into the array:String str = "3,5,8 - 14 even, 28,56";// Makesshort[] tempArray = { 3,5,8,10,12,14,28,56 };The error conditions are numerous. You could have the set notation listed out of numerical order (e.g. "3,37,14,108 - 109, 52"). You could have ranges listed in reverse order (e.g. "4,14 - 6, 9"). You could have character input that makes nonsense (e.g. "3,14 - x, d,12"). You could have "odd" and "even" misspelled or capitalized in multiple variations....I think you see how difficult this will be to write.I don't have a lot of experience with string manipulation/parsing here, but I really want the challenge of trying to do this with as little help as I can get. Then again, I don't want to reinvent the wheel, so if anybody knows as solution or has seen one before, I'm all ears.hisDudenessps - My best attempt, doesn't work and is shoddy at best:short[] makeNumberingScheme(String str){short[] scheme = new short[];int i;int j;String tempArray[];String buffArray[];String temp = "";int tempIndex, buffIndex;tempIndex = buffIndex = 0;boolean isBuffering = false;boolean oddsOn = false;boolean evensOn = false;boolean rangeSet = false;short[] numbers;int countNumbers;for(i = 0; i < str.length(); i++){// 1. Parse the string and tokenize it./*ADD INPUT ERROR CONTROL:20,25,26,even 30 - 38etc.or 13 - 39 evenor 14 - 6 */if(str.charAt(i) >= '1' && str.charAt(i) <= '9' && !isBuffering){if(str.charAt(i+1) >= '1' && str.charAt(i+1) <= '9'){isBuffering = true;temp += str.charAt(i);buffArray[buffIndex] = temp;buffIndex++;temp = "";}else // else its a number between 1 and 9{temp += str.charAt(i);tempArray[tempIndex] = temp;tempIndex++;temp = "";}}else if(str.charAt(i) >= '1' && str.charAt(i) <= '9' && isBuffering){if(str.charAt(i+1) >= '1' && str.charAt(i+1) <= '9'){temp += str.charAt(i);buffArray[buffIndex] = temp;buffIndex++;temp = "";}else {temp += str.charAt(i);isBuffering = false;buffArray[buffIndex] = temp;buffIndex++;temp = "";}}else if((str.charAt(i) < '1' || str.charAt(i) > '9') && buffArray != null){// Dump 'buffArray' into 'tempArray'.String s = "";for(j = 0; j < buffArray.length; j++)s += buffArray[j];{tempArray[tempIndex] = s;tempIndex++;}// Clear buffArray for future buffing.buffArray = null;}else if(str.charAt(i) == '0')printError("The value zero (0) is an invalid value for a question number.");else if(str.charAt(i) == '-'){if((str.charAt(i-1) >= '1' && str.charAt(i-1) <= '9') &&(str.charAt(i+1) <= '1' && str.charAt(1+1) <= '9')){tempArray[tempIndex] = "-";tempIndex++;}else printError("Invalid question number syntax. Too many subsequent hyphens used specify an invalid range.");}else if(str.charAt(i) == ' ')continue;else // else its a word or garbage{if(str.charAt(i) == 'e' || str.charAt(i) == 'E' || str.charAt(i) == 'o'|| str.charAt(i) == 'O'){if(str.charAt(i) == 'e' || str.charAt(i) == 'E'){tempArray[tempIndex] = "even";tempIndex++;}else if((str.charAt(i) == 'o' && str.charAt(i+1) == 'd') ||(str.charAt(i) == 'O' && (str.charAt(i+1) == 'D' || str.charAt(i+1) == 'd'))){tempArray[tempIndex] = "odd";tempIndex++;}else if(str.charAt(i) == 'o' && str.charAt(i+1) == 'n' &&str.charAt(i+2) == 'l' && str.charAt(i+3) == 'y'){i += 3;continue;}else printError("You entered an invalid character or word into the assignment's question numbers. Valid identifiers are even or odd.");}else printError("You entered an invalid character or word into the assignment's question numbers. Valid identifiers are even or odd.");}}// 2. Now iterate the tokens and append numbers to the scheme.for(i = 0; i < tempArray.length; i++){int k = 0;if(tempArray.charAt(0) >= '1' && tempArray.charAt(0) <= '9')if(tempArray[i+1].charAt(0) >= '1' && tempArray[i+1].charAt(0) <= '9'){scheme[k] = (short)this.stringToInt(tempArray);k++;}else if(tempArray.charAt(0) == '-'){// First check to see if any odd/even specifiers are present.if(tempArray[i+2].charAt(0) == 'o')oddsOn = true;if(tempArray[i+2].charAt(0) == 'e')evensOn = true;// Look at the final number in the range and turn it into an int.short beginning = (short)this.stringToInt(tempArray[i-1]);short end = (short)this.stringToInt(tempArray[i+1]);if(oddsOn || evensOn){while(beginning <= end){scheme[k] = beginning;beginning += 2;k++;}}else if((!evensOn && !oddsOn) || (evensOn && oddsOn)){while(beginning <= end) {scheme[k] = beginning;beginning++;k++;}}}}return scheme;}
  I'd do it like this, you'd first tokenize the string using the comma.  You then classify each token as either a number or a range or invalid (for this you'd output an error).  For a number you simply add it into a list, for a range you have another function that processes them.  This function would grab the numbers either side of the hyphen and check they're valid (if not output an error) and then generate the range.  To check for the odd or even thing convert the entire thing to upper case (so you don't have to worry about stuff like Even verses even) and act appropiately when generating the range (if the bit at the end says something other than odd or even output an error).  Finally this function would return the range as a list or an array or something that would be added to the main list.  You'd then convert the list to an array and you're done.   ;  Your grammar for this problem is:L = V '⊥'| V ',' L   V = N    (V1)  | N '-' N   (V2)N = [0-9]+    (N)As an invariant, you can keep an array to be filled. The rule (N) will return the integer value of the number being read. (V1) simply appends the number to the array, while (V2) would append all integers between its first and second number.Hence the pseudocode:remove whitespace from STRINGcall L() on STRING[0..end]L( STRING) =  STRING = call V() on string[0..end]  if next character is ',' then call L() on STRING[1..end]  else CHECK that next character is '⊥'V( STRING ) =  (START,STRING) = call N() on STRING[0..end]  if next character is '-' then (END,STRING) = call N() on STRING[1..end]  else END = START  for i = START:END append i to ARRAY  return STRINGN( STRING ) =  i = first character of regexp [^0-9] in STRING  CHECK that i > 0  INT = read STRING[0..i-1] as an integer  CHECK that INT is bigger than previously read integers  return (INT,STRING[i..end])Which should be trivially translated to java. You can also easily extend this solution to take into account the 'even/odd' modifier.   ;  My solution is not optimized (and most of it is similar to the above's posters) but clear, you can take it as a reference though:Clean the input string (spaces, double commas, double hyphens, double 'even' or 'odd' etc etc...) to make sure it is error-free.Read all the number, hyphens... into a temporary array (is it called tokenize ?, I'm not sure)Take care of all the hyphens first: Check from 1st (not 0) place if you want1. Read the two strings nearby the hyphen.2. If they are 'even' or 'odd', then back (forward) one element, then fill in the desired numbers in the target array.3. Repeat the procedure until out of hyphens add the last numbers in the input string to the target array.Here you go!. Good luck.;  I would you suggest to rely more on the Java utils already ready to use.I would follow the way Mondor has suggested and considering the implications of ToohrVyk's pseudocode. It may be implemented like this:(It is too much work to post the routine into parts, so I have commented it hopefully thoroughly)import java.text.ParseException;import java.util.ArrayList;   public int[] parse(String str)   throws ParseException, NumberFormatException { final java.util.ArrayList<Integer> buffer = new java.util.ArrayList<Integer>(); // split input into parts separated by comma and iterate parts final String[] parts = str.split(","); for(int index=0; index<parts.length; ++index) {    // isolate part and trim whitespace    final String part = parts[index].trim();    // split the part into an interval    final String[] interval = part.split("-");    if(interval.length>2) {  // but at most one minus is allowed, else there is an error  throw new java.text.ParseException("too many minusses",index);    }    // the start value of the interval was left of the minus    final int from = Integer.parseInt(interval[0].trim());    if(from<=0) {  throw new ParseException("invalid number",index);    }    int until = from;    // ... and the even/odd keyword (if any) at the end ...    boolean even = true;    boolean odd = true;    if(interval.length==2) {  interval[1] = interval[1].trim();  odd = !interval[1].endsWith("even");  even = !interval[1].endsWith("odd");  // cut off the keyword  if(!odd) {interval[1] = interval[1].substring(0,interval[1].length()-4).trim();  }  if(!even) {interval[1] = interval[1].substring(0,interval[1].length()-3).trim();  }  until = Integer.parseInt(interval[1]);  // check whether until is greater than from  if(until<=from) {throw new ParseException("not ascending interval",index);  }    }    // ... and the end value at the right; using from instead if there was no right side    if(until<=0) {  throw new ParseException("invalid number",index);    }    // check whether the from is big enough    if(buffer.size()>0) {  if(buffer.get(buffer.size()-1).intValue()>=from) {throw new ParseException("interval start too low",index);  }    }    // append to list    for(int counter=from; counter<=until; ++counter) {  if(((counter&1)==0) && even) {buffer.add(new Integer(counter));  }  if(((counter&1)==1) && odd) {buffer.add(new Integer(counter));  }    } } // convert list into array final int[] result = new int[buffer.size()]; for(int index=0; index<result.length; ++index) {    result[index] = buffer.get(index).intValue(); } // done return result;   }(Not totally tested code. Please verify carefully!)I don't know why you are parsing floating point numbers since I expect only ordinal numbers to be valid for question numbering? So the suggestion above don't allows floating point numbers at all.EDIT: There are some tricks with the even/odd stuff. As you can see I'm using the inverse of the opposite condition. So later the "true" values could be used nicely.[Edited by - haegarr on December 13, 2005 1:04:56 PM]