7

プロの好奇心から、C で 2 つの完全な数値文字列を比較する最も安全/最速/最も効率的な方法は何ですか?

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

int main(void){

char str1[5] = "123";
char str2[5] = "123";
char *ptr;

if(atoi(str1) == atoi(str2))
    printf("Equal strings");

if(strtol(str1,&ptr,10) == strtol(str2,&ptr,10))
    printf("Equal strings");

if(strcmp(str1,str2)==0)
    printf("Equal strings");

return 0;
}
4

6 に答える 6

9

strcmp ()私の意見では、数値変換は必要ありません。ただし、この場合、そのうちの 1 つに数字のみを含む文字列が格納されていることを確認する必要があります。

memcmp ()また、文字列で行うこともできます

編集1

先頭のゼロについて他の人が指摘したように、先頭のゼロを手動でスキャンして呼び出すstrcmp ()memcmp ()、ゼロ以外の最初の数字へのポインターを渡すことができます。

EDIT2

以下のコードは、私が言おうとしていることを示しています。これは浮動小数点数ではなく、整数専用です。

int main (void)
{
  char s1[128], s2[128];
  char *p1 = s1, *p2 = s2;

  /* populate s1, s2 */

  while (*p1 && (*p1 == '0'))
    p1++;

  while (*p2 && (*p2 == '0'))
    p2++;

  if (strcmp (p1, p2) == 0)
    printf ("\nEqual");
  else
    printf ("\nNot equal");

  printf ("\n");
  return 0;
}

浮動小数点数の場合、小数点以下の末尾のゼロは手動で切り取る必要があります。

または、すべてを手動で行います。

EDIT4

また、この浮動小数点のコードもご覧ください。これにより、小数点の前の先頭のゼロと小数点の後の後続のゼロが検出されます。例えば

00000000000001.10000000000000そして、以下のコードになり1.1ますEqual

int main (void)
{
  char s1[128], s2[128];
  char *p1, *p2, *p1b, *p2b;

  printf ("\nEnter 1: ");
  scanf ("%s", s1);
  printf ("\nEnter 2: ");
  scanf ("%s", s2);

  p1 = s1;
  p2 = s2;
  /* used for counting backwards to trim trailing zeros
   * in case of floating point
   */
  p1b = s1 + strlen (s1) - 1;
  p2b = s2 + strlen (s2) - 1;


  /* Eliminate Leading Zeros */
  while (*p1 && (*p1 == '0'))
    p1++;

  while (*p2 && (*p2 == '0'))
    p2++;

  /* Match upto decimal point */
  while (((*p1 && *p2) && ((*p1 != '.') && (*p2 != '.'))) && (*p1 == *p2))
  {
    p1++;
    p2++;
  }

  /* if a decimal point was found, then eliminate trailing zeros */
  if ((*p1 == '.') && (*p2 == '.'))
  {
    /* Eliminate trailing zeros (from back) */
    while (*p1b == '0')
      p1b--;
    while (*p2b == '0')
      p2b--;

    /* match string forward, only upto the remaining portion after
     * discarding of the trailing zero after decimal
     */
    while (((p1 != p1b) && (p2 != p2b)) && (*p1 == *p2))
    {
      p1++;
      p2++;
    }
  }

  /* First condition on the LHS of || will be true for decimal portion
   * for float the RHS will be . If not equal then none will be equal
   */
  if (((*p1 == '\0') && (*p2 == '\0')) ||  ((p1 == p1b) && (p2 == p2b)))
    printf ("\nEqual");
  else
    printf ("\nNot equal");

  printf ("\n");
  return 0;
}

使用前にテストが必要です。

于 2011-06-17T18:11:52.620 に答える
4

str(n)cmp最速かつ最も安全です。

于 2011-06-17T18:10:35.710 に答える
0

それらが同一であることを探していると仮定するとstrncmp、変換なしで直接比較できるため、最も高速で安全です。また、一般的に よりも安全であると考えられていstrcmpます。

00ただし、とを等しくしたい0場合、または同じ数値をわずかに異なる方法で表現できる場合は、 を使用する必要がありますatoi

于 2011-06-17T18:12:40.343 に答える
-1

次のように簡単に使用できます。

if(strcmp("123","123") == 0)

{

  printf("The strings are equal");

}

そうしないと

{

  printf("The strings are not equal.");

}

私の意見では、それはうまくいくはずです。

于 2011-06-17T18:36:00.023 に答える
-1

整数については、次の方法をお勧めします。

int strcmp_for_integers(char *aa, char *bb){
    char aa2[11] = "";
    char bb2[11] = "";
    int answer;

    sprintf(aa2, "%010d", atoi(aa));
    sprintf(bb2, "%010d", atoi(bb));
    answer = strcmp(aa2, bb2);

    return answer;
}
于 2012-02-26T16:55:45.627 に答える
-1

私の意見では、「最も安全な」方法は、両方の引数を整数に変換してからテストすることです。そうすることで、潜在的な先行ゼロの問題を回避できます。ただし、これはおそらく最速または最も効率的な方法ではありません。

于 2011-06-17T18:13:35.213 に答える