移动数组元素不起作用的功能

时间:2014-11-06 02:17:46

标签: c++ visual-c++ visual-studio-2012 c++11

我有一个空终止的字符数组。也称为c弦。我编写了一个函数,它将在每个索引左侧移动元素,< ----由给定数量的索引。例如,当“hello world”的char数组传递给函数时,shiftBy值为3,它应该将char数组转换为:“lo worldhel”。

目前,此功能适用于< = 11 elelements的所有字符串。除此之外的任何东西和数组中的最后三个点都不会移位。请记住,最后一个索引是持有空终止符!

这是一个棘手的问题,我被困了好几个小时。我也不能使用任何标准函数或向量,我坚持使用这些不赞成使用的数组和简单的循环。因此,请不要使用“为什么不使用空白功能”....因为相信我,如果可以,我就不会在这里。

以下是代码:at at:

    void shiftLeft (char szString[], int size, int shiftBy)
{
    if(shiftBy > size){
        shiftBy = shiftBy - size;
    }

    if(size == 1){
        //do nothing, do nothing, exit function with no change made to myarray
    }
    else{
        char temp;
        //for loop to print the array with indexes moved up (to the left) <-- by 2
        for (int i = 0; i <= size-shiftBy; i++)//size = 11
        {//EXAMPLE shift by 3  for a c-string of `hello world`
            if(i < size-shiftBy){
                temp = szString[shiftBy + i];//temp = h
                szString[shiftBy + i] = szString[i];//d becomes l
                szString[i] = temp;//h becomes l
            }
            else{//it will run once while i=8
                temp = szString[i];//temp = l
                szString[i] = szString[i+1];//8th element becomes h
                szString[i+1] = szString[size-1];//9th element becomes e
                szString[size-1] = temp;//last element becomes l

            }

        }
    }
}

2 个答案:

答案 0 :(得分:0)

来自azillionmonkeys.com/qed/case8.html

void shiftLeft(char szString[], int size, int shiftBy) {
            int c, tmp, v;

            if (size <= 0) return;
            if (shiftBy < 0 || shiftBy >= size) {
                shiftBy %= size;
                if (shiftBy < 0) shiftBy += size;
            }
            if (shiftBy == 0) return;

            c = 0;
            for (v = 0; c < size; v++) {
                int t = v, tp = v + shiftBy;
                char tmp = szString[v];
                c++;
                while (tp != v) {
                    szString[t] = szString[tp];
                    t = tp;
                    tp += shiftBy;
                    if (tp >= size) tp -= size;
                    c++;
                }
                szString[t] = tmp;
            }
        }

答案 1 :(得分:0)

如果你想要完成的唯一目的是在一个已终止的字符串中移动字符旋转(并根据"helloworld"的样本判断结果为"loworldhel"一个三班制,似乎是这种情况),你使这个很多比它需要的更难。

在O(N)时间内没有临时空间要求的传统算法是反转移位的左侧,然后是整个序列,然后是移位的右侧, all 基于序列的开头。例如,假设我们要左移以下字符串3个插槽:

1234567890

首先,反转第一个shiftBy插槽

1234567890
^-^
3214567890

其次,颠倒整个序列

3214567890
^--------^
0987654123

最后,反转(length-shiftBy)插槽:

0987654123
^-----^
4567890123

使用标准库会使这个琐碎,但显然你是教授认为......作弊。不使用任何库apis,无论如何,上述算法都不是很难:

#include <iostream>

void shiftLeft(char sz[], size_t shiftBy)
{
    const char *p = sz;
    while (*p) ++p;
    std::size_t len = p - sz;

    if (len > 1 && (shiftBy %= len))
    {
        char *ends[] = { sz+shiftBy, sz+len, sz+(len - shiftBy) };
        for (std::size_t i=0; i<3; ++i)
        {
            char *start = sz, *end = ends[i];
            while (start < --end)
            {
                char ch = *start;
                *start++ = *end;
                *end = ch;
            }
        }
    }
}

int main()
{
    char sz[] = "1234567890";
    std::cout << sz << '\n';

    shiftLeft(sz, 11);
    std::cout << sz << '\n';

    shiftLeft(sz, 4);
    std::cout << sz << '\n';

    shiftLeft(sz, 1);
    std::cout << sz << '\n';

    shiftLeft(sz, 20);
    std::cout << sz << '\n';
}

<强>输出

1234567890
2345678901
6789012345
7890123456
7890123456

如果你真的准备在临时空间做这件事,那就这样吧,但是我无法理解为什么你会这样做。

祝你好运。