使用memset()和memcpy()函数

时间:2019-02-07 18:32:08

标签: c++ memcpy memset

// CPP Program to find all the common characters 
// in n strings 
#include <bits/stdc++.h> 
using namespace std; 

const int MAX_CHAR = 26; 

void commonCharacters(string str[], int n) 
{ 
  // primary array for common characters 
  // we assume all characters are seen before. 
  bool prim[MAX_CHAR] = {true}; 
  //memset(prim, true, sizeof(prim)); 

  // for each string 
  for (int i = 0; i < n; i++) { 

    // secondary array for common characters 
    // Initially marked false 
    bool sec[MAX_CHAR] = { false }; 

    // for every character of ith string 
    for (int j = 0; str[i][j]; j++) { 

      // if character is present in all 
      // strings before, mark it. 
      if (prim[str[i][j] - 'a']) 
        sec[str[i][j] - 'a'] = true; 
    } 

    // copy whole secondary array into primary 
    //memcpy(prim, sec, MAX_CHAR); 

    for(int k=0;k<n;k++)
      prim[k] = sec[k];
  } 


  // displaying common characters 
  for (int i = 0; i < 26; i++) 
    if (prim[i]) 
      printf("%c ", i + 'a'); 
} 

// Driver's Code 
int main() 
{ 
  string str[] = { "geeksforgeeks", 
                   "gemkstones", 
                   "acknowledges", 
                   "aguelikes" }; 
  int n = sizeof(str)/sizeof(str[0]); 
  commonCharacters(str, n); 
  return 0; 
}

我们使用两个大小为26的哈希数组(对于a-z,其中0为a,z为25)。 这种方法很简单,如果我们在标记字符之前就已经看到了该字符,并且如果没有看到该字符,则因为它不是一个普通字符而忽略了它。 为什么这段代码没有给出期望的输出?而如果我使用memset(prim,true,sizeof(prim))而不是bool prim[MAX_CHAR] = {true};进行初始化,而用memcpy(prim,sec,MAX_CHAR)而不是for(int k=0;k<n;k++) prim[k] = sec[k];来复制prim []中的布尔数组sec [],它就可以正常工作。

1 个答案:

答案 0 :(得分:4)

警告

bool prim[MAX_CHAR] = {true}; 

不等于memset(prim, true, sizeof(prim));

MAX_CHAR是26,并且您只用{true}给出1值,所以prim[0] true 初始化,而所有下25个条目都用初始化。 0( false )。 true 直到数组末尾都不会使用。

但是

bool prim[MAX_CHAR] = {true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true }

初始化26个条目(如果我算数不错的话)

当然,memcpy(prim,sec,MAX_CHAR)for(int k=0;k<n;k++) prim[k] = sec[k];是不相等的,因为 n 是字符串数(4),而不是MAX_CHAR(26)< / p>

执行您的代码:

pi@raspberrypi:/tmp $ ./a.out
pi@raspberrypi:/tmp $

使用 memset {}中的26个 true 执行,然后将for(int k=0;k<n;k++)替换为for(int k=0; k<MAX_CHAR; k++)

pi@raspberrypi:/tmp $ ./a.out
e g k s pi@raspberrypi:/tmp $ 

弗朗索瓦·安德列(FrançoisAndrieux)的一项提案(在下面的删除备注中)消除了有关 prim 初始化的问题:反转 prim 中的布尔值,所以

void commonCharacters(string str[], int n) 
{ 
  // primary array for common characters 
  // we assume all characters are seen before. 
  // (false means seen before, reverse logic)
  bool prim[MAX_CHAR] = {false}; 

  // for each string 
  for (int i = 0; i < n; i++) { 

    // secondary array for common characters 
    // Initially marked false (standard logic)
    bool sec[MAX_CHAR] = { false }; 

    // for every character of ith string 
    for (int j = 0; str[i][j]; j++) { 

      // if character is present in all 
      // strings before, mark it. 
      if (!prim[str[i][j] - 'a']) 
        sec[str[i][j] - 'a'] = true; 
    } 

    // copy negation of whole secondary array into primary         
    for(int k=0; k<MAX_CHAR; k++)
      prim[k] = !sec[k];
  } 

  // displaying common characters 
  for (int i = 0; i < 26; i++) 
    if (!prim[i]) 
      printf("%c ", i + 'a'); 
} 

执行:

pi@raspberrypi:/tmp $ ./a.out
e g k s pi@raspberrypi:/tmp $ 

但是 prim 的反向逻辑和 sec 的标准逻辑可能会令人困惑