编程之美:旋转字符串

1: 设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),

且只允许使用两个附加变量。既 abcd1234,右移k=4位,变为1234abcd

#include<iostream>
using namespace std;
//---------------------------------------
//方式1,每次右移动1位,时间复杂度为O(m*N)
void RightShift(char *s,int k)
{
	int len = strlen(s);
	int m = k%len;
	while (m--)
	{
		char tempc = s[len -1];
		for (int i = len - 2; i >=0; i--)
		{
			s[i+1] = s[i];
		}
		s[0] = tempc;
	}
}
//-----------------------------------------
//方式2:利用求逆
//1、首先分为俩部分,X:abc,Y:def;
//2、X->X^T,abc->cba, Y->Y^T,def->fed。 
//3、(X^T,Y^T)^T=YX,cbafed->defabc,即整个翻转。
void reverse(char *s,int begin,int end)
{
	for (;begin<end;begin++,end--)
	{
		char tempc = s[begin];
		s[begin] = s[end];
		s[end] = tempc;
	}
}

void RightShift2(char *s,int k)
{
	int len = strlen(s);   //abcdef123456,  XY 
	int m = k%len;
	reverse(s,0,len - m - 1);  
	reverse(s,len - m,len-1);//654
	reverse(s,0,len-1);
}

int main()
{
	char s[] = "abcde12345";
	RightShift(s,5);
	printf("%s\n",s);
	RightShift2(s,7);
	printf("%s\n",s);
	system("pause");
	return 0;
}

STL rotate算法:

1:gcd原理

公约数:30的约数为1,2,3,5,6,10.15.30., 24的约数为:1,2,3,4,6,12,14,则30和24的公约数为1,2,3,6

gcd(a,b)=gcd(b,a mod b)(a非负,b为正整数)

公约数的重要性质为:d|a(d为a的约数)并且d|b,则d|(a+b),并且d|(a-b),更一般为d|a.d|b蕴含d|(ax+by);(x,y为整数)

则此证明很简单,gcd(a,b)|gcd(b,a MOD b), 假设 d = gcd(a,b),则d|a,d|b, 又a MOD b = a – qb(q= a/b),既根据以上性质有d|(a MOD b)

gcd(b,a MOD b)|gcd(a,b),和以上证明类似 d|b,d|(a MOD b), a = qb+(a MOD b) (q = a/b),既a为b和(a MOD b)的线性组合,则d|(qb+(a MOD b)),既d|a, 则有 d|b,和d|a,所以gcd(a,b)|gcd(b,a MOD b);

——————————————————-

相关问题1:循环移位后是否包含

相关问题2:一个字符串中的所有字母,是否被另外一个字符串完全包含

位图法:

#include<iostream>
#include<bitset>
using namespace std;
#define SHIFT 5
#define N 26
#define MASK 0x01f
#define WORDLEN 32

int a[N/WORDLEN+1];
void setbit(int i)
{
	a[i>>SHIFT] |= 1<<(i&MASK);
}
void clearbit(int i)
{
	a[i>>SHIFT] &= ~(1<<(i&MASK));
}
int test_i(int i)
{
	return a[i>>SHIFT] & (1<<(i&MASK));
}
char s1[] = "AABCDEFCDEFGMLNOP";
char s2[] = "CDAAEFGMNOP";
int main()
{
	int str1len = strlen(s1);
	int str2len = strlen(s2);
	for(int i = 0; i < str2len; i++)//较短的字符串设置bit
	{
		int m = (int)(s2[i] - 'A');
		setbit(m);
	}
	cout<<bitset<26>(a[0])<<endl;
	for (int i = 0; i < str1len; i++)//较长的字符串清除bit
	{
		int m = (int)(s1[i] - 'A');
		clearbit(m);
	}
	cout<<bitset<26>(a[0])<<endl;
	if(a[0] == 0)cout<<"str2 的所有字母在str1中"<<endl;//26位,没有位置1
	system("pause");
	return 0;
}



    原文作者:xiaobo620
    原文地址: https://blog.csdn.net/xiaobo620/article/details/7530316
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞