从0到开始<七>:字符串相关及位运算

程序一:编写函数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;
}

你可能感兴趣的:(从0到开始<七>:字符串相关及位运算)