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

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

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

目前,此函数适用于 <= 11 个元素的所有字符串。超过它的任何东西和阵列中的最后三个点都不会移动。请记住,最后一个索引包含空终止符!

这是一个棘手的问题,我已经被困了几个小时。我也不能使用任何标准函数或 vector ,我受困于这些已弃用的数组和简单循环。所以请不要胡扯“你为什么不使用空白函数”......因为相信我,如果可以的话我就不会在这里了。

这是代码,在:

    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

            }

        }
    }
}

最佳答案

如果您尝试完成的唯一目的是将终止字符串中的字符向左移动旋转(并根据您的“helloworld”示例判断“loworldhel” 在 3 类后,情况似乎如此),你正在使这比它需要的更难。

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

1234567890

首先,反转第一个shiftBy槽

1234567890
^-^
3214567890

其次,反转整个序列

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

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

0987654123
^-----^
4567890123

使用标准库会使这微不足道,但显然您是教授认为...作弊。不使用任何 库 api,上述算法不是很难:

#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

如果您真的打算在临时空间中执行此操作,那就这样吧,但我无法理解您为什么要这样做。

祝你好运。

关于c++ - 移动数组元素的功能不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26770674/

相关文章:

c++ - 带有编程构造菜单的 CMFCMenuButton?

c++ - 为什么在struct中使用字符串时出现运行时错误

c++ - 错误:boost::tuple 的 'operator==' 不匹配

c++ - 哪个运算符重载已用于 ifstream 对象以评估为 bool 值

c++ - 试图计算一个字符串

c# - 以编程方式将现有项目添加到新的 VS2012 解决方案失败

c++ - vector 、Size_type 和封装

c++ - 这个程序是异步运行还是同步运行?

c++ - typedef FOO(BAR) 中不允许函数返回函数

c# - 几何对象的可视化调试器