以递归方式交换数组中的元素

时间:2016-08-23 18:34:10

标签: c++ arrays recursion

我一直试图以递归方式交换存储在数组中的元素。

我的数组使用下面的rand()存储大写和小写字母的列表。

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

目标是交换大写和小写元素并分别向左和向右移动所有小写和大写

Thi函数用于递归交换元素,直到满足(i == j)条件。

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);
}

但是,它只返回相同的数组,而只是交换1个字母。 我试图分别添加和减去第一个和最后一个数组,直到它达到i=j的基本情况,同时减小大小。

假设交换有效,我调用函数并使用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;

}

3 个答案:

答案 0 :(得分:0)

我认为你想要像这样的算法(伪C语言):

//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"
顺便说一句,我忘了在第一次尝试“跳过”部分之后添加“返回”,这是如此滥用的递归,我必须检查我的代码两次才能抓住它。但是如果你想减少生锈,你应该调试原始代码。如果你想保持生疏,请聘请一些程序员。

答案 1 :(得分:0)

鉴于输入ABcdE,您的代码将以

开头
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
到目前为止

,因为alphabets[0]是小写的,并且i在每次迭代开始时始终设置为0,所以不会再进行交换。

为了正确地做到这一点,你需要一个兼顾左右位置的功能:

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

这里我使用了迭代器的惯用命名约定,其中end超过了最后一个元素,因此它与原始大小的使用相符。

我还建议您考虑使用std::swap而不是编写自己的swap代码

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

并使用isupper

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

答案 2 :(得分:0)

听起来像是在设置递归解决方案。以防迭代解决方案可以提供帮助:

#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]);
  }
}