简体   繁体   中英

Swapping elements in array recursively

I've been trying to swap elements that i store in array recursively.

My array stores a list of upper and lower case letter using the rand() like below.

for (int i = 0; i < size; i++)
{           
    alphabets[i] = (rand() % 26 + 65 + rand() % 2 * 32);          
}

The objective is to swap uppercase and lowercase elements and move all lower case and uppercase to the left and right respectively

Thi function is meant to swaps the element recursively until (i == j) condition is met.

void swapElementR(char alphabets[], int size)
{
    int temp;
    int i = 0;
    int j = size - 1;

    if(i == j)
    {
        return;
    }
    else 
    {
        if (alphabets[i] >= 'A' && alphabets[i] <= 'Z')
        {
            if (alphabets[j] >= 'a' && alphabets[j] <= 'z')
            {
                temp = alphabets[i];
                alphabets[i] = alphabets[j];
                alphabets[j] = temp;                    
            }
            else
               --j;         
        }
        else
            ++i;                         
    }

    swapElementR(alphabets, --size);
}

However, it is returning the same array while only swapping 1 alphabet instead. I tried to add and minus the first and the last array respectively until it reaches a base case of i=j while reducing the size.

Assumingly, the swap works, I call the function and display using my for-loop

void moveElementR(char alphabets[], int size)
{

    cout << "Recursive swap of array" << endl;

    swapElementR(alphabets, size);


    for (int i = 0; i < size; i++)
    {
        cout << alphabets[i] << "   ";
    }

    return;

}

I think you wanted algorithm like this (pseudo C-like language):

//input is `array`, `i` (first char index) and `j` (last char index).
void recursion(char array[], int i, int j) {
    if (j <= i) return; // no more chars to process
    if (array[i] in [a-z]) {
        recursion(array, i+1, j); // [i] was already lower case, skip it
        return;
    }
    if (array[j] in [A-Z]) {
        recursion(array, i, j-1); // [j] was already upper case, skip it
        return;
    }
    // here [i] is upper case and [j] is lower case -> swap them
    swap(array[i], array[j]);
    recursion(array, i+1, j-1); // resolve characters between the swapped ones
}

cout << recursion("ABcdE", 0, 4); // should produce "dcBAE"

BTW, I forgot to add "return" after the "skip it" parts on my first try, this is so abusive usage of recursion, that I had to check my code twice to catch that. But you should debug your original code, if you want to get less rusty. If you want to stay rusty, hire some programmer.

Given the input ABcdE your code will start with

i=0, j=(5-1)=4
alphabets[i]=A, alphabets[j]=E
[j] (E) is uppercase => no swap
i++ = 1 (i is not used again)
swapElementR(alphabets, 4)
    i=0, j=(4-1)=3
    alphabets[i]=A, alphabets[j]=d
    swap => dBcAE
    i++ = 1 (i is not used again)
    swapElementR(alphabets, 3)
        i=0, j=(3-1)=2
        alphabets[i]=d, alphabets[j]=c
        [i] (d) is lowercase => no swap

as of this point, because alphabets[0] is lowercase, and i is always set to 0 at the start of each iteration, no further swaps can occur.

In order to do this properly, you will need a function that considers both the left and right positions to work from:

void swapElementR(char* alphabets, int begin, int end)

Here I'm using the idiomatic naming convention for iterators, where end is past the last element, so it lines up with your use of size in the original.

I would also encourage you to consider using std::swap instead of writing your own swap code

std::swap(alphabets[i], alphabets[j])

and use isupper and islower from <cctype>

#include <cctype>
...
if (isupper(alphabets[i]) && islower(alphabets[j]))

Sounds like you're set on a recursive solution. Just in case an iterative solution could help:

#include <algorithm>
#include <cctype>
#include <string>
#include <vector>

using namespace std;

void partition(vector<char>& chracters) {
  int i = 0, j = chracters.size() - 1;
  while (i < j) {
    while (islower(chracters[i]) && i < j) i++;
    while (isupper(chracters[j]) && j > i) j--;
    swap(chracters[i], chracters[j]);
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM