1.请实现字符串右循环移位函数,比如:“abcdefghi”循环右移2位就是“hiabcdefg”.
函数原型:void RightLoopMove(char *pStr, unsigned short steps)
函数参数说明: pStr: Point to a ‘\0’ terminated string steps: The rotate shift numbers*/
解法一:常规解法(万不得已时候考虑使用),直接采用指针移动
void _fun(char *pStr, unsigned short steps)
{
assert(pStr != NULL && steps > 0);
int n = strlen(pStr);//abcdefghi
char * p = pStr; //p指向 abcdefghi
char *back = (p + n - steps);//back 指向 ghi
char *temp = (char*)malloc(sizeof(char)*steps + 1);//开辟temp 存取要移动到前面的字符
strcpy(temp, back); //先把后面要移动的字符拷贝到temp
while (p != back)
{
for (int i = 0; i < n; ++i)
{
*(pStr + steps + i) = *(p + i);
}
p++;
}
strcpy(pStr, temp);
free(temp);
}
int main()
{
char *a = (char *)malloc(sizeof(char) * 20);
strcpy(a, "abcdefghi");
char * p = a;
while (*p != '\0') { cout << *p; p++; }
cout << endl;
_fun(a, 2);
p = a;
while (*p != '\0') { cout << *p; p++; }
cout << endl;
free(a);
return 0;
}
解法二:采用临时空间来存放一个值,先把最后一个值存放其中,然后整体右移动 时间复杂度为O(n+m)
void RightLoopMove(char *pStr, unsigned short steps)
{
assert(pStr != NULL && steps > 0);
int str_len = strlen(pStr);
steps %= str_len;
char tmp;
while (steps > 0)
{
tmp = *(pStr + str_len - 1);
for (int i = str_len - 1; i > 0; --i)
{
*(pStr + i) = *(pStr + i - 1);
}
pStr[0] = tmp;
steps--;
}
}
2..功能:实现对一个8 bit数据(unsigned char类型)的指定位(例如第n位)的置0或者置1操作,并保持其他位不变。
函数原型:
void bit_set(unsigned char *p_data, unsigned char position, bool flag)
函数参数说明: P_data 是指定的源数据,position是指定位(取值范围1~8);flag表示是置0还是置1操作,true: 置1 flase:置0*/
思路:通过移动1,或等和与等取反(移动后的1)来实现位操作
void bit_set(unsigned char *p_data, unsigned char position, bool flag)
{
assert(p_data != NULL, position >= 1 && position <= 8);
//边界值的问题
/*if (p_data == NULL){}
if (position < 1 || position >8){}*/
if (flag)//1
{
*p_data |= ((0x01) << (position - 1));
}
else //0
{
*p_data &= ~((0x01) << (position - 1));
}
}
3.有一个16位的整数,每4位为一个数,写函数求他们的和。
例如:整数1101010110110111,和 1101+0101+1011+0111 = 13+5+11+7=36*/
方法一:
int fun(unsigned short a)
{
assert(a <= 65535);
int x[4] = { 0 };
int y[4] = { 0 };
int result = 0;
x[0] = 15; x[1] = 240; x[2] = 3840; x[3] = 61440;
for (int i = 0; i < 4; i++)
y[i] = x[i] & a;
y[1] >>= 4; y[2] >>= 8; y[3] >>= 12;
for (int i = 0; i < 4; i++)
result += y[i];
return result;
}
int main()
{
unsigned short a = 54711;
int b = sum(a);
cout << b << endl;
return 0;
}
方法二:
int sum(unsigned short value)
{
int sum = 0;
for (int i = 0; i < 4; ++i)
{
sum += ((value&(0x0f << i * 4)) >> (i * 4));
}
return sum;
}
4.给出unsigned char value, 判断value中的二进制1的个数,要求算法效率尽可能高
方法一:
int main()
{
unsigned char value = 'A';
int a[30], i = 0, x = (int)value, y, n = 0;
while (x != 0)
{
y = x % 2;
a[i] = y;
i++;
x = x / 2;
}
i--;//按照循环i多加一次,所以要减去一
for (; i >= 0; --i)
{
printf("%d", a[i]);
}
cout << endl;
for (int i = 0; i < 30; ++i)
if (a[i] == 1)
n++;
cout << "value中的二进制1的个数 = " << n << endl;
}
方法二:
int main()
{
unsigned char v = '15';
int count = 0;
while (v)
{
count += v & 0x1;
v >>= 1;
}
cout << count << endl;
return 0;
}
方法三:
int fun(int v)
{
int count = 0;
while (v)
{
v &= (v - 1);
count++;
}
return count;
}
int main()
{
int i = fun(100);
cout << i << endl;
return 0;
}
5、通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。
压缩规则:
1、仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc"。
2、压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"。
要求实现函数:
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr);
输入pInputStr: 输入字符串lInputLen: 输入字符串长度
输出 pOutputStr: 输出字符串,空间已经开辟好,与输入字符串等长;
注意:只需要完成该函数功能算法,中间不需要有任何IO的输入输出
示例
输入:“cccddecc” 输出:“3c2de2c”
输入:“adef” 输出:“adef”
输入:“pppppppp” 输出:“8p”
#include<stack>
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr)
{
assert(pInputStr != NULL);
stack<int> st;
long n = strlen(pInputStr);
const char *p = pInputStr;
char *out = pOutputStr;
int count = 1;
while (*p != '\0')
{
if (*p == *(p + 1))
{
count++;
}
else
{
if (count != 1)
{
while (count)
{
st.push(count % 10);
count /= 10;
}
while (!st.empty())
{
*pOutputStr++ = st.top() + '0';
st.pop();
}
}
count = 1;
*pOutputStr++ = *p; //cout << *p;//
}
*pOutputStr = '\0';
p++;
}
}
int main()
{
const char *str = "cccddecc";
long n = strlen(str);
char output[30] = { 0 };
stringZip(str, n, output);
/*char *p = output;
while (p != NULL)
{
cout << *p;
p++;
}*/
for (int i = 0; i < 10; i++)
cout << output[i];
cout << endl;
return 0;
}
6、如果一个字符串str, 把字符串str前面任意的部分挪到后面形成的字符串叫做str的旋转词,比如str=”12345”,
str的旋转词有”12345”, ”23451”, “34512”, “45123”, “51234”, 给定两个字符串a和b,请判断a和b是否为旋转词。
int main()
{
char str[] = "12345";
char RotatetWord[] = "45123";
int count = 0, n = strlen(str) + 1;
char *temp;
temp = (char*)malloc(sizeof(char) * 2 * n - 1);
strcpy(temp, str);
strcat(temp, str); //tmp 1234512345
char *T = temp, *R = RotatetWord;
while (*R != '\0')
{
while (*T != '\0')
{
if (*R == *T)
{
count++;
R++;
}
T++;
}
}
if (count == (n - 1))
{
cout << "a是b的旋转词。" << endl;
}
else
{
cout << "a不是b的旋转词。" << endl;
}
return 0;
}
7、给定一个字符类型的数组chas, 请在单词间做逆序调整, 只要做到单词顺序逆序即可,对空格的位置没有特别要求。
例如:如果把chas看作字符串为“dog loves pig”, 调整为 “pig loves dog”
如果把chas看作字符串为 “ I’ m a student . ” 调整为 “student. a I’m ”
void reverse(char *str, int start, int end)
{
while (start <= end)
{
char tmp = str[start];
str[start] = str[end];
str[end] = tmp;
start++;
end--;
}
}
void RotateWord(char*str)
{
if (str == NULL || *str == '\0')
return;
int len = strlen(str);
reverse(str, 0, len - 1);/*先把整个字符串倒过来*/
/
int left = 0, right = 0;
for (int i = 0; i <= len; ++i)
{
if (str[i] == ' '|| str[i] == '\0')
{
right = i - 1;
reverse(str, left, right);
left = i + 1;
}
}
}
int main()
{
char str[] = "dog loves pig";
RotateWord(str);
cout << str << endl;
return 0;
}
8.给定一个字符数组,判断字符数组中是否所有的字符都只出现过一次
根据两个要求,分别实现两个函数。在保证额外空间复杂度为O(1)的前提下,实现时间复杂顿尽量低的方法。
bool oneCharacter(char* str) //char a[] = "awwbc";
{
int n = strlen(str),i = 0,j=i+1;
while (*str != '\0')
{
while(*(str+j) !='\0')
{
if (*(str) == *(str + j))
{
return false;
}
++j;
}
j = i+1;
++i;
++str;
}
return true;
}
int main()
{
char a[] = "awwbc";
bool result = oneCharacter(a);
cout << result << endl;
return 0;
}
9.给定一个字符串str, 返回str的最长无重复字符子串的长度;
例如:str=”abcd” ,返回 4 str=”aabcb”, 最长无重复字符子串为“abc”, 返回3
int lengthOfLongestSubstring(string s) {
// write your code here
int ret = 0;
map<char, int> m;
int start = 1;
for (int i = 1; i <= s.length(); i++)
{
char c = s[i - 1];
if (m[c] >= start)
{
start = m[c] + 1;
m[c] = i;
}
else
{
m[c] = i;
ret = max(ret, i - start + 1);
}
}
return ret;
}
int main()
{
char str[] = "aabcb";
int i = lengthOfLongestSubstring(str);
cout << i << endl;
return 0;
}
10.请编写函数实现,找出一个字符数组中第一个只出现一次的字符。
void Judge(char *str)
{
assert(str != NULL);
int i;
int pindu = 256;
int Index = 23;
int cnt = 0;
int Count[256] = { 0 };
int sequence[256] = { 0 };
for (i = 0; str[i] != '\0'; i++)
{
Count[(int)(*(str + i))] ++;
sequence[(int)(*(str + i))] = cnt++;
}
for (i = 0; i < 256; i++)
{
if (Count[i] == 1)
{
if (sequence[i] < pindu)
{
pindu = sequence[i];
Index = i;
}
}
}
cout << "数组下标为:" << pindu << endl;
cout << "第一次只出现一次的字符为: " << str[pindu] << endl;
}
int main()
{
char str[] = "aaaaaassssssbsssddggaafewfasfwefewwffadaccbeez"; //qwertyuiqwer
Judge(str);
return 0;
}