程序一:编写函数any(s1,s2),将字符串s2中的任意字符在字符串s1中第一次出现的位置作为结果返回。如果s1中不包含s2中的字符,则返回-1。(标准库函数strpbrk(其头文件是string.h)具有同样的功能,但它返回的是指向该位置的指针)
解法一:O(n*m)的时间复杂度,这个简单
int any(char s1[], char s2[])
{
int i;
int j;
int pos;
pos = -1;
for(i = 0; pos == -1 && s1[i] != '\0'; i++)
{
for(j = 0; pos == -1 && s2[j] != '\0'; j++)
{
if(s2[j] == s1[i])
{
pos = i;
}
}
}
return pos;
}
解法二:O(n+m) 的时间复杂度
int any(char *s1, char *s2)
{
int i = 0;
char array[256] = {0};
if (s1 == NULL)
{
if (s2 == NULL) return 0;
else return -1;
}
while (*s2 != '\0')
{
array[*s2] = 1;
s2++;
}
while (s1[i] != '\0')
{
if (array[ s1[i] ] == 1)
return i;
i++;
}
return -1; // 容易漏掉哦
}
下面看下测试程序:学习学习
#include <string.h>
#include <stdio.h>
int main(void)
{
char *leftstr[] =
{
"",
"a",
"antidisestablishmentarianism",
"beautifications",
"characteristically",
"deterministically",
"electroencephalography",
"familiarisation",
"gastrointestinal",
"heterogeneousness",
"incomprehensibility",
"justifications",
"knowledgeable",
"lexicographically",
"microarchitectures",
"nondeterministically",
"organizationally",
"phenomenologically",
"quantifications",
"representationally",
"straightforwardness",
"telecommunications",
"uncontrollability",
"vulnerabilities",
"wholeheartedly",
"xylophonically",
"youthfulness",
"zoologically"
};
char *rightstr[] =
{
"",
"a",
"the",
"quick",
"brown",
"dog",
"jumps",
"over",
"lazy",
"fox",
"get",
"rid",
"of",
"windows",
"and",
"install",
"linux"
};
size_t numlefts = sizeof leftstr / sizeof leftstr[0];
size_t numrights = sizeof rightstr / sizeof rightstr[0];
size_t left = 0;
size_t right = 0;
int passed = 0;
int failed = 0;
int pos = -1;
char *ptr = NULL;
for(left = 0; left < numlefts; left++)
{
for(right = 0; right < numrights; right++)
{
pos = any(leftstr[left], rightstr[right]);
ptr = strpbrk(leftstr[left], rightstr[right]);
if(-1 == pos)
{
if(ptr != NULL)
{
printf("Test %d/%d failed.\n", left, right);
++failed;
}
else
{
printf("Test %d/%d passed.\n", left, right);
++passed;
}
}
else
{
if(ptr == NULL)
{
printf("Test %d/%d failed.\n", left, right);
++failed;
}
else
{
if(ptr - leftstr[left] == pos)
{
printf("Test %d/%d passed.\n", left, right);
++passed;
}
else
{
printf("Test %d/%d failed.\n", left, right);
++failed;
}
}
}
}
}
printf("\n\nTotal passes %d, fails %d, total tests %d\n",
passed,
failed,
passed + failed);
return 0;
}
程序二:编写一个函数rightrot(x,n),该函数返回将x循环右移(即从最右端移出的位将从最左端移入)n(二进制)位后所得到的值
解法一:正常思路
unsigned rightrot(unsigned x, unsigned n)
{
while (n > 0) {
if ((x & 1) == 1) // 移出的位是1
x = (x >> 1) | ~(~0U >> 1);
else
x = (x >> 1);
n--;
}
return x;
}
解法二:很不错,主要是最后一句,好好领悟unsigned int rightrot(unsigned int x, unsigned int n)
{
size_t s = sizeof(x) * CHAR_BIT; //多少位
size_t p;
/*限制位到0~s-1*/
if(n < s)
p = n;
else
p = n % s;
if((0 == x) || (0 == p))
return x;
return (x >> p) | (x << (s - p));
}
测试程序:
#include <stdio.h>
int main(void)
{
unsigned x;
int n;
for(x = 0; x < 700; x += 49)
for(n = 1; n < 8; n++)
printf("%u, %d: %u\n", x, n, rightrot(x, n));
return 0;
}