简体   繁体   English

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

[英]How to know if two strings have the same letters?

Using strstr , we can check if two strings are absolutely same each other or not.使用strstr ,我们可以检查两个字符串是否完全相同。 But I want to know if the components of two strings are exactly same.但我想知道两个字符串的组成部分是否完全相同。 For example, "DOG" consists 'D' , 'O' , 'G' and "GOD" consists 'G' , 'O' , 'D' .例如, "DOG"'D''O''G' ”组成, "GOD"'G''O''D'组成。 The components of the two strings are 'D' , 'O' , 'G' , which are exactly same.两个字符串的组成部分是'D''O''G' ,它们完全相同。 How can I write a program that compares the components of two strings?如何编写一个程序来比较两个字符串的分量?

As mentioned in the comments, your problem can be solved by computing a histogram of the characters occurring in each string.如评论中所述,您的问题可以通过计算每个字符串中出现的字符的直方图来解决。 Then you can compare if both have the same histogram.然后您可以比较两者是否具有相同的直方图。 If so, both strings contain the same characters with the same number of repetitions, but with arbitrary order.如果是这样,两个字符串都包含相同的字符,重复次数相同,但顺序任意。

#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;
}

Another method would be to sort the two strings, and then compare them.另一种方法是对两个字符串进行排序,然后比较它们。

If the sorted string match, they have to contain exactly the same letters:如果排序后的字符串匹配,它们必须包含完全相同的字母:

#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 );
}

And main() (separated to eliminate scroll bars):main() (分开以消除滚动条):

int main( int argc, char **argv )
{
    if ( argc < 3 )
    {
        return( -1 );
    }

    // compare consecutive argument strings
    for ( int ii = 1; ii < ( argc - 1 ); ii++ )
    {
        if ( sameLetters( argv[ ii ], argv[ ii + 1 ] ) )
        {
            printf( "'%s' has the same letters as '%s'\n",
                argv[ ii ], argv[ ii + 1 ] );
        }
    }

    return( 0 );
}

Sorting is probably more efficient for short strings, but suffers from either having to either copy the string or modify the original.对于短字符串,排序可能更有效,但必须复制字符串或修改原始字符串。 As the string size grows, I strongly suspect the histogram method would be much more efficient - it can take a long time to copy and then sort each string, and it could take a lot of memory to make a copy.随着字符串大小的增加,我强烈怀疑直方图方法会更有效 - 复制然后对每个字符串进行排序可能需要很长时间,并且可能需要大量 memory 来制作副本。

You could sort both strings then compare them您可以对两个字符串进行排序然后比较它们

#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;
} 

For the previous solution, the return value is the return of strcmp ing the two sorted strings.对于前面的解决方案,返回值是strcmp两个排序后的字符串的返回。 That is, zero iff both strings are equal.也就是说,如果两个字符串相等,则为零。

A variation on @f9c69e9781fa194211448473495534 good answer. @f9c69e9781fa194211448473495534的一个变体很好的答案。

Perform a census of the characters in strings a and b .对字符串ab中的字符执行普查。 Increase the population for characters in a and decrease for b .增加 a 中字符a数量并减少b中的字符数量。 When done, if any of the census counts are not 0, strings differ.完成后,如果任何人口普查计数不为 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;
}

Performing the operation as unsigned char avoids the case of negative char as an array index.将操作作为unsigned char执行可以避免负char作为数组索引的情况。 For the pedantic: On long lost non 2's complement machines with signed char , this handles -0 correctly.对于书呆子:在长期丢失的带有signed char的非 2 的补码机器上,这可以正确处理 -0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM