C 如何知道两个字符串是否有相同的字母?

C 如何知道两个字符串是否有相同的字母?,c,string,C,String,使用,我们可以检查两个字符串是否完全相同。但我想知道两个字符串的成分是否完全相同。 例如,“狗”由'D','O','G'和“上帝”由'G','O','D'组成。这两个字符串的组成部分是'D','O','G',它们完全相同。如何编写一个程序来比较两个字符串的组成部分?如注释中所述,您的问题可以通过计算每个字符串中出现的字符数来解决。然后,您可以比较两者是否具有相同的直方图。如果是,则两个字符串都包含重复次数相同但顺序任意的相同字符 #include <limits.h> #includ

使用,我们可以检查两个字符串是否完全相同。但我想知道两个字符串的成分是否完全相同。
例如,
“狗”
'D'
'O'
'G'
“上帝”
'G'
'O'
'D'
组成。这两个字符串的组成部分是
'D'
'O'
'G'
,它们完全相同。如何编写一个程序来比较两个字符串的组成部分?

如注释中所述,您的问题可以通过计算每个字符串中出现的字符数来解决。然后,您可以比较两者是否具有相同的直方图。如果是,则两个字符串都包含重复次数相同但顺序任意的相同字符

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HIST_SIZE (UCHAR_MAX + 1)

void create_histogram(const char *s, int histogram[HIST_SIZE]) {
  for (size_t i = 0; s[i] != '\0'; i++) {
    unsigned char c = s[i];
    histogram[c]++;
  }
}

int same_histograms(const int histogram1[HIST_SIZE],
                    const int histogram2[HIST_SIZE]) {
  for (size_t i = 0; i < HIST_SIZE; i++) {
    if (histogram1[i] != histogram2[i]) {
      return 0;
    }
  }
  return 1;
}

int same_chars(const char *a, const char *b) {
  int histogram1[HIST_SIZE] = {0};
  int histogram2[HIST_SIZE] = {0};

  create_histogram(a, histogram1);
  create_histogram(b, histogram2);

  return same_histograms(histogram1, histogram2);
}

int main() {
  printf("Result: %d\n", same_chars("dog", "god"));

  return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#定义历史大小(UCHAR\u MAX+1)
无效创建直方图(常量字符*s,整数直方图[历史大小]){
对于(大小i=0;s[i]!='\0';i++){
无符号字符c=s[i];
直方图[c]++;
}
}
int相同的直方图(常量int直方图1[历史大小],
常数int Historogram2[历史大小]){
对于(大小i=0;i
如注释中所述,您的问题可以通过计算每个字符串中出现的字符数来解决。然后,您可以比较两者是否具有相同的直方图。如果是,则两个字符串都包含重复次数相同但顺序任意的相同字符

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HIST_SIZE (UCHAR_MAX + 1)

void create_histogram(const char *s, int histogram[HIST_SIZE]) {
  for (size_t i = 0; s[i] != '\0'; i++) {
    unsigned char c = s[i];
    histogram[c]++;
  }
}

int same_histograms(const int histogram1[HIST_SIZE],
                    const int histogram2[HIST_SIZE]) {
  for (size_t i = 0; i < HIST_SIZE; i++) {
    if (histogram1[i] != histogram2[i]) {
      return 0;
    }
  }
  return 1;
}

int same_chars(const char *a, const char *b) {
  int histogram1[HIST_SIZE] = {0};
  int histogram2[HIST_SIZE] = {0};

  create_histogram(a, histogram1);
  create_histogram(b, histogram2);

  return same_histograms(histogram1, histogram2);
}

int main() {
  printf("Result: %d\n", same_chars("dog", "god"));

  return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#定义历史大小(UCHAR\u MAX+1)
无效创建直方图(常量字符*s,整数直方图[历史大小]){
对于(大小i=0;s[i]!='\0';i++){
无符号字符c=s[i];
直方图[c]++;
}
}
int相同的直方图(常量int直方图1[历史大小],
常数int Historogram2[历史大小]){
对于(大小i=0;i
另一种方法是对两个字符串排序,然后比较它们

如果排序的字符串匹配,则它们必须包含完全相同的字母:

#define _XOPEN_SOURCE 700

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compareChars( const void *a, const void *b )
{
    char aa = *( ( char * ) a );
    char bb = *( ( char * ) b );
    return( aa - bb );
}

// use qsort to sort the string
char *sortStr( const char *str )
{
    char *sortedStr = strdup( str );
    qsort( sortedStr, strlen( sortedStr ), 1, compareChars );
    return( sortedStr );
}

int sameLetters( const char *a, const char *b )
{
    char *sortedA = sortStr( a );
    char *sortedB = sortStr( b );

    int result = strcmp( sortedA, sortedB );

    free( sortedA );
    free( sortedB );

    return( !result );
}

对于短字符串,排序可能更有效,但必须复制字符串或修改原始字符串。随着字符串大小的增加,我强烈怀疑直方图方法会更加有效——复制每个字符串并对其排序可能需要很长时间,而且复制一个字符串可能需要大量内存。

另一种方法是对两个字符串进行排序,然后比较它们

如果排序的字符串匹配,则它们必须包含完全相同的字母:

#define _XOPEN_SOURCE 700

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compareChars( const void *a, const void *b )
{
    char aa = *( ( char * ) a );
    char bb = *( ( char * ) b );
    return( aa - bb );
}

// use qsort to sort the string
char *sortStr( const char *str )
{
    char *sortedStr = strdup( str );
    qsort( sortedStr, strlen( sortedStr ), 1, compareChars );
    return( sortedStr );
}

int sameLetters( const char *a, const char *b )
{
    char *sortedA = sortStr( a );
    char *sortedB = sortStr( b );

    int result = strcmp( sortedA, sortedB );

    free( sortedA );
    free( sortedB );

    return( !result );
}

对于短字符串,排序可能更有效,但必须复制字符串或修改原始字符串。随着字符串大小的增加,我强烈怀疑直方图方法会更加有效——复制每个字符串并对其排序可能需要很长时间,而且复制一个字符串可能需要大量内存。

您可以对两个字符串进行排序,然后比较它们

#include <string.h>
#include <stdlib.h>

static int compareFunction(const void* a, const void* b) 
{ 
    return *(const char*)a- *(const char*)b; 
} 
int compareComponents(const char* a, const char* b) 
{ 
    int lenA = strlen(a);
    int lenB = strlen(b);
    int returnVal;

    char *tempA = malloc(sizeof(char)*(lenA+1));
    char *tempB = malloc(sizeof(char)*(lenB+1));
    strcpy(tempA,a);
    strcpy(tempB,b);
    qsort(tempA, lenA, sizeof(char), compareFunction); 
    qsort(tempB, lenB, sizeof(char), compareFunction); 
    returnVal=strcmp(tempA,tempB); 
    free(tempA);
    free(tempB);
    return returnVal;
} 

#包括
#包括
静态int比较函数(常数void*a,常数void*b)
{ 
返回*(常量字符*)a-*(常量字符*)b;
} 
int compareComponents(常量字符*a,常量字符*b)
{ 
int lenA=strlen(a);
int lenB=strlen(b);
int returnVal;
char*tempA=malloc(sizeof(char)*(lenA+1));
char*tempB=malloc(sizeof(char)*(lenB+1));
strcpy(tempA,a);
strcpy(tempB,b);
qsort(tempA、lenA、sizeof(char)、compareFunction);
qsort(tempB、lenB、sizeof(char)、compareFunction);
returnVal=strcmp(tempA,tempB);
自由(坦帕);
免费(tempB);
返回值;
} 

对于前面的解决方案,返回值是对两个排序字符串进行排序的
strcmp
的返回。也就是说,如果两个字符串相等,则为零。

您可以对两个字符串进行排序,然后比较它们

#include <string.h>
#include <stdlib.h>

static int compareFunction(const void* a, const void* b) 
{ 
    return *(const char*)a- *(const char*)b; 
} 
int compareComponents(const char* a, const char* b) 
{ 
    int lenA = strlen(a);
    int lenB = strlen(b);
    int returnVal;

    char *tempA = malloc(sizeof(char)*(lenA+1));
    char *tempB = malloc(sizeof(char)*(lenB+1));
    strcpy(tempA,a);
    strcpy(tempB,b);
    qsort(tempA, lenA, sizeof(char), compareFunction); 
    qsort(tempB, lenB, sizeof(char), compareFunction); 
    returnVal=strcmp(tempA,tempB); 
    free(tempA);
    free(tempB);
    return returnVal;
} 

#包括
#包括
静态int比较函数(常数void*a,常数void*b)
{ 
返回*(常量字符*)a-*(常量字符*)b;
} 
int compareComponents(常量字符*a,常量字符*b)
{ 
int lenA=strlen(a);
int lenB=strlen(b);
int returnVal;
char*tempA=malloc(sizeof(char)*(lenA+1));
char*tempB=malloc(sizeof(char)*(lenB+1));
strcpy(tempA,a);
strcpy(tempB,b);
qsort(tempA、lenA、sizeof(char)、compareFunction);
qsort(tempB、lenB、sizeof(char)、compareFunction);
returnVal=strcmp(tempA,tempB);
自由(坦帕);
免费(tempB);
返回值;
} 
对于前面的解决方案,返回值是对两个排序字符串进行排序的
strcmp
的返回。也就是说,如果两个字符串相等,则为零。

一个好答案的变体

对字符串
a
b
中的字符进行普查。增加
a
中字符的填充,减少
b
中字符的填充。完成后,如果任何普查计数不为0,则字符串不同

#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>

bool same_chars(const char *a, const char *b) {
  const unsigned char *ua = (const unsigned char *) a;
  const unsigned char *ub = (const unsigned char *) b;

  size_t population[UCHAR_MAX + 1] = {0};  // Only 1 table needed.
  while (*ua && *ub) {
    population[*ua++]++;
    population[*ub++]--;
  }
  if (*ua || *ub) {
    return false; // One longer than the other
  }
  for (unsigned i = 0; i <= UCHAR_MAX; i++) {
    if (population[i]) {
      return false; // mis-match
    }
  }
  return true; // match;
}
#包括
#包括
#包括
布尔相同字符(常量字符*a,常量字符*b){
常量无符号字符*ua=(常量无符号字符*)a;
常量无符号字符*ub=(常量无符号字符*)b;
大小\u t填充[UCHAR\u MAX+1]={0};//只需要1个表。
而(*ua&&*ub)