-2
string strings[10];
void split(string s){
    int curr=0,start=0,end=0,i=0;
    
    while(i<=len(s)){
        if(s[i]==' ' or i == len(s)){
            end = i;
            string sub;
            sub.append(s,start,end-start);
            strings[curr] = sub;
            start = end + 1;
            curr += 1 ; 
        }
        i++;
    }
}

for example if the input is " computer laptop screen desktop mouse " then the output string should be: computer laptop screen desktop mouse

I have successfully tried using loops but failed using recursion, can anyone help me solve split() using recursion. Thank you

  • 2
    What, exactly, do you have against vectors? – Taekahn Jul 31 '22 at 15:32
  • 2
    This looks very much like C code, not C++. – Nicol Bolas Jul 31 '22 at 15:51
  • Why recursion, if you don't mind me asking? While it's possible in principle, it would make the code more complex and difficult to read. What's wrong with the loop you have? – Igor Tandetnik Jul 31 '22 at 16:16
  • You ask for recursive solution but, in my opinion, it does not feel natural. There are other problems that you could use to practise recursion. Another approach is to put the sentence string in a stringstream object and read word by word https://stackoverflow.com/questions/18318980/taking-input-of-a-string-word-by-word – AngelosFr Jul 31 '22 at 16:56
  • _Side note:_ With `while (i<=len(s))`, then `s[i]` goes one beyond the end of the string, so you have UB. To fix that, change: `if (s[i]==' ' or i == len(s))` into `if (i == len(s) or s[i] == ' ')`. This is correct because of "short circuit evaluation" – Craig Estey Jul 31 '22 at 16:56

1 Answers1

1

This solution assumes you want only words from the string to enter your array and that you want to split on some predetermined string delimiter like <space>" " or <double-dash>"--".

If you need to keep the void function signature, here is one:

void split_rec(string str_array[], size_t arr_index,
               string s, string delimiter) {
    if (s == "") {
        return;
    }
    size_t str_index = s.find(delimiter);
    string word = s.substr(0, str_index);
    if (word != "") {
        str_array[arr_index++] = word;
    }
    // find type functions return string::npos if they don't find.
    str_index = s.find_first_not_of(delimiter, str_index);
    if (str_index == string::npos) {
        return;
    }
    return split_rec(str_array, arr_index, s.substr(str_index), delimiter);
}

But I would recommend returning the size of the array so you communicate what the function is doing more accurately. Like this:

size_t split_rec(string str_array[], size_t arr_index,
                 string s, string delimiter) {
    if (s == "") {
        return arr_index;
    }
    size_t str_index = s.find(delimiter);
    string word = s.substr(0, str_index);
    if (word != "") {
        str_array[arr_index++] = word;
    }
    str_index = s.find_first_not_of(delimiter, str_index);
    if (str_index == string::npos) {
        return arr_index;
    }
    return split_rec(str_array, arr_index, s.substr(str_index), delimiter);
}

Then the call is like this:

string strings[10];
// I left some extra spaces in this string.
string str = " computer  laptop screen desktop mouse  ";
size_t strings_len = split_rec(strings, 0, str, " ");
cout << "Array is length " << strings_len << endl;
for (size_t i = 0; i < strings_len; i++) {
    cout << strings[i] << endl;
}
Array is length 5
computer
laptop
screen
desktop
mouse
Alex Lopez
  • 70
  • 7