I need help for a project that requires creating lists upong a String. Let's say for example I have the next string
(defun sum( 1 2))
What I need to do is turn that string into an array, which I have already done using the the split method.
So now, I want to check the whole array in look for (
. if the loop finds a (
it creates an array/list and appends the following elements. But if the loop finds a )
it stops adding elements to the last array/list created, but it continues to add in the other list. I want my program to do that until there is no more elements to add (or well, when the whole string was separated into lists). Right now this is what I have:
public ArrayList<String> SaveInLists(String command) {
String delimiter = "(";
ArrayList<String> list_global = new ArrayList<String>();
String[] commandlist = command.split("");
for(int i = 0;i<commandlist.length;i ){
if(commandlist[i].equals("(")){
//create new arraylist and add the next elements of commandlist to the array until it finds a ')'.
//then it closes the arraylist, but keep adding the other elements next to ')'
}
}
//then all the arrays created need to be added to the list_global
return list_global;
}
CodePudding user response:
This how my proposed solution could look like. As far as I understand the resulting global list must be represented as the list of inner lists, not just an ArrayList<String>
, because in this case we don't have any inner lists, just an array of strings. So, I thought the resulting global list must be of List<List<String>>
data type. Below is the possible implementation:
public List<List<String>> saveInLists(String command) {
if (command == null) {
throw new IllegalArgumentException("Input command cannot be null!");
}
List<List<String>> globalList = new ArrayList<>();
String openingDelimiter = "(";
String closingDelimiter = ")";
String[] commandList = command.split("");
int openDelimitersCount = 0;
int closingDelimiterCount = 0;
int innerListsCount = 0; int lastInnerListIndex = -1;
for (int i = 0; i < commandList.length; i ) {
if (openingDelimiter.equals(commandList[i])) {
// the next inner list should be created for adding "non-bracket" elements
innerListsCount ;
lastInnerListIndex ;
List<String> innerList = new ArrayList<>();
globalList.add(innerList);
openDelimitersCount ;
} else if (closingDelimiter.equals(commandList[i])) {
// the next "non-bracket" elements should be added to the previous list
lastInnerListIndex--;
closingDelimiterCount ;
} else {
// it's not a bracket, it's some other "non-bracket" element
if (innerListsCount == 0) {
// no brackets at the beginning of the sequence, so we should create the very first list
innerListsCount ;
lastInnerListIndex ;
List<String> innerList = new ArrayList<>();
innerList.add(commandList[i]);
globalList.add(innerList);
} else {
// we already have some inner list
if (lastInnerListIndex < 0) {
throw new RuntimeException("Last inner list index reached negative value!");
}
List<String> lastInnerList = globalList.get(lastInnerListIndex);
lastInnerList.add(commandList[i]);
}
}
}
if (openDelimitersCount != closingDelimiterCount) {
// you can check here and throw an exception in case there's some mismatch regarding the count of ( and )
throw new RuntimeException("The count of ( and ) brackets in the input expression does not match!");
}
// return the global list of inner lists
return globalList;
}
The usage of this method and sample cases:
List<List<String>> result1 = saveInLists("(defun sum( 1 2))");
System.out.println(result1);
// 2 inner lists inside global list: [[d, e, f, u, n, , s, u, m], [ , , 1, , 2]]
List<List<String>> result2 = saveInLists("(defun sum( 1 2) a bc d)");
System.out.println(result2);
// 2 inner lists inside global list: [[d, e, f, u, n, , s, u, m, , a, , b, c, , d], [ , , 1, , 2]]
List<List<String>> result3 = saveInLists("defun sum( 1 2) a bc d");
System.out.println(result3);
// The same as previous, despite the absence of outer brackets pair: [[d, e, f, u, n, , s, u, m, , a, , b, c, , d], [ , , 1, , 2]]
List<List<String>> result4 = saveInLists("(defun sum( 1 2 (some internal expr)) a bc d)");
System.out.println(result4);
// 3 inner lists inside global list: [[d, e, f, u, n, , s, u, m, , a, , b, c, , d], [ , , 1, , 2, ], [s, o, m, e, , i, n, t, e, r, n, a, l, , e, x, p, r]]
List<List<String>> result5 = saveInLists("defun sum( 1 2 (some internal expr)) a bc d)");
System.out.println(result5);
// this will throw an exception, because we're missing the very first opening bracket.
Please, let me know if this solution works for you.
CodePudding user response:
The implementation can be the following one:
public List<String> saveInLists(String command) {
List<String> result = new ArrayList<>();
LinkedList<Integer> startPositions = new LinkedList<>();
for (int i = 0; i < command.length(); i ) {
if (command.charAt(i) == '(') {
startPositions.addFirst(i);
} else if (command.charAt(i) == ')') {
result.add(command.substring(startPositions.removeFirst(), i 1));
}
}
return result;
}
Every time (
is found the start position is saved in the startPositions
list and every time )
is found the substring is saved in the result
list.
Notice that you can access the command string directly like a char array.
Example:
(defun sum( 1 (- 5 2) 2))
Output:
["(- 5 2)", "( 1 (- 5 2) 2)", "(defun sum( 1 (- 5 2) 2))"]