n元一维向量旋转问题

文章探讨了如何解决一维n元向量的旋转问题,提出了利用向量翻转和逆运算达到理想解的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:
B.将一个n元一维向量向左旋转i个位置。例如,当n=8且i=3时,向量abcdefgh旋转为defghabc. 简单的代码使用一个n元的中间向量在n步内完成该工作。你能否仅使用数十个额外字节的存储空间,在正比于n的时间内完成该向量的旋转?

问题解析:
1、以正比于n的时间(相当于n步内)完成该操作,那么就是每个元素的移动都差不多一步到位,如将第4位的d一步移动到第1位处,其他元素也也一样。
2、额外空间只有几十个字节,这里说明并不能将前i个保存到临时空间,这样当i很大时,会消耗过多的内存空间。
3、题目条件对运行时间和内存空间都有严格的限制,

解决方案:

作者给出的方案1:

#include <cstdio>
#include <cstdlib>      // srand, rand
#include <cassert>      // assert

// 递归求最大公约数
int gcd(int a,  int b)
{
    assert(a > 0 && b >= 0);
    if (b != 0){ return gcd(b, a%b); }
    return a;
}

/************************************************************************/
// 函数名称:my_reverse
// 函数目的:对输入的数组循环移位进行反转
// 函数参数:arr:要反转的数组 arraysize:数组长度  reversenum:反转个数
/************************************************************************/
void my_reverse(int arr[], int arraysize, int reversenum)
{
    if (reversenum == 0 || reversenum == arraysize) { return; }
    for (int i = 0; i < gcd(reversenum, arraysize); ++i){
        int temp = arr[i];

        int j = i;
        while (1){
            int k  = j + reversenum;
            if (k >= arraysize){ k -= arraysize; }
            if (k == i) { break; }

            arr[j] = arr[k]; j = k;
        }
        arr[j] = temp;
    }

    return;
}


int main()
{
    int a[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'};

    int arraysize  = 12;   // 数组长度
    int reversenum = 5;    // 反转个数

    my_reverse(a, arraysize, reversenum);

    for (int i = 0; i < 12; ++i)
    {
        printf("%c\t", a[i]);
    }
    
    return 0;
}

作者给出的方案2:

利用翻转求逆的性质,得到最终的解决方案,该方案是两个中最完美的一个方案。

#include <iostream>
#include <cassert>

using namespace std;

void my_swap(int arr[], int arrsize, int arr_a, int arr_b)
{
	assert(arr_a >= 0 && (arr_b - arr_a >= 0) && arr_b < arrsize);
	int i = arr_a;
	int j = arr_b;
	for (; i <=j; i++,j--)
	{
		swap(arr[i], arr[j]);
	}
}

void my_reverse(int arr[], int arrsize, int reversenum)
{
	assert(reversenum < arrsize);

	my_swap(arr, reversenum, 0, reversenum - 1);
	my_swap(arr, arrsize, reversenum, arrsize - 1);
	my_swap(arr, arrsize, 0, arrsize - 1);
}



int main()
{
	int a[13] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l','m' };

	int arraysize = 13;   // 数组长度
	int reversenum = 5;    // 反转个数

	my_reverse(a, 13, 5);

	for (int i = 0; i < 13; ++i)
	{
		printf("%c\t", a[i]);
	}


	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值