Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Найти по маске из списка номеров красивые


Автор: dizler 27.10.2012, 23:56
Миссия: есть список из тысяч телефонных номеров типа:
79103501525
79103510000
79120656565
...

И есть шаблоны (маски) типов номеров золотые, платиновые.
Платина:
******AAAA
******0000
******AAAA
*****00000
*****AAAAA
****000000
***AABAAAA
(Где А - одинаковые цифры, B - другие одинаковые цифры)

Ну и золотые другие.
***AAAA***
***AAAAA**
***AAAAABB
***AAAAABC
***AAAABBA
и т.д.

Нужно хотя бы просто найти в списке csv файла номера под маской платина.

Подскажите как поступить?, пробовал через регулярные выражения никак не проходит

Автор: feodorv 28.10.2012, 02:09
Я бы так сделал: ввел бы понятие наложение шаблона (****ABABAB) на телефонный номер (79120656565) - это преобразование шаблона в номер по правилам:
  • 1. сначала сравниваем шаблон и номер на совпадение циферных символов (если в шаблоне на какой-то позиции есть цифра '0'-'9', то и в телефонном номере на этой же позиции должна быть эта же цифра)
  • 2. потом читаем образец посимвольно как массив символов
  • 2.1 если символ '*', то идём дальше
  • 2.2 если цифра, то идём дальше (уже проверили)
  • 2.3 если в образце встретилась буква, то
    • 2.3.1 смотрим на цифру номера, стоящей в той же позиции, что и буква в шаблоне; обозначим её d
    • 2.3.2 проходим вторым циклом оставшейся хвост шаблона
    • 2.3.2.1 если в хвосте шаблона встретилась та же буква, то сравниваем цифру в соответствующей позиции с d; не совпала - номер не удовлетворяет шаблону, если совпала, тогда в шаблоне нашу букву заменяем на '*' (чтобы при первом цикле из п.2 эту букву уже не проверять)
    • 2.3.2.2 если в хвосте шаблона встретилась другая буква, то сравниваем цифру в соответствующей позиции с d; совпала - номер не удовлетворяет шаблону (ведь A != B)
  • 2.4 если конец шаблона, то номер удовлетворяет шаблону.
 
Задачка интересная, я даже программку под неё накатал:
Код

#include <stdio.h>

const char *numberTable[] =
{
  "9103501525",
  "9103510000",
  "9120656565",
  "9157777667",
  "9167777767",
  "9167777766",
  NULL
};

const char *patternTable[] =
{
  "******AAAA",
  "******0000",
  "******AAAA",
  "*****00000",
  "***AAAA***",
  "***AAAAA**",
  "***AAAAABB",
  "***AAAAABC",
  "****ABABAB",
  "***AAAABBA",
  NULL
};

#define IS_DIGIT(x) ((x) >= '0' && (x) <= '9')

int superposition( const char *pattern, const char *number)
{
  char sp[11];                                               // собственно наложение
  int i, j;

  for( i = 0; i < 10; i++)                                 // п.1 только и цифры в наложении тоже заменяем на '*'
    if( IS_DIGIT( pattern[i] ) )
    {
      if( number[i] != pattern[i] ) return 0;
      sp[i] = '*';
    }
    else
      sp[i] = pattern[i];

  for( i = 0; i < 10; i++)
    if( sp[i] != '*' )                                          // п.2.1 и п.2.2
      for( j = i+1; j < 10; j++)                         // п.2.3.2
        if( sp[j] != '*' )                                      
          if( sp[j] == sp[i] )
          {
            if( number[j] != number[i] ) return 0;
          }
          else
            if( number[j] == number[i] ) return 0;

  return 1;
}

int main( void )
{
  const char **n, **p;

  for( p = patternTable; *p != NULL; p++)
    for( n = numberTable; *n != NULL; n++)
      printf( "%10s  %10s  %s\n", *p, *n,
        superposition( *p, *n) ? "YES" : "NO");

  return 0;
}


Вот что получилось:
Цитата

******AAAA  9103501525  NO
******AAAA  9103510000  YES
******AAAA  9120656565  NO
******AAAA  9157777667  NO
******AAAA  9167777767  NO
******AAAA  9167777766  NO
******0000  9103501525  NO
******0000  9103510000  YES
******0000  9120656565  NO
******0000  9157777667  NO
******0000  9167777767  NO
******0000  9167777766  NO
******AAAA  9103501525  NO
******AAAA  9103510000  YES
******AAAA  9120656565  NO
******AAAA  9157777667  NO
******AAAA  9167777767  NO
******AAAA  9167777766  NO
*****00000  9103501525  NO
*****00000  9103510000  NO
*****00000  9120656565  NO
*****00000  9157777667  NO
*****00000  9167777767  NO
*****00000  9167777766  NO
***AAAA***  9103501525  NO
***AAAA***  9103510000  NO
***AAAA***  9120656565  NO
***AAAA***  9157777667  YES
***AAAA***  9167777767  YES
***AAAA***  9167777766  YES
***AAAAA**  9103501525  NO
***AAAAA**  9103510000  NO
***AAAAA**  9120656565  NO
***AAAAA**  9157777667  NO
***AAAAA**  9167777767  YES
***AAAAA**  9167777766  YES
***AAAAABB  9103501525  NO
***AAAAABB  9103510000  NO
***AAAAABB  9120656565  NO
***AAAAABB  9157777667  NO
***AAAAABB  9167777767  NO
***AAAAABB  9167777766  YES
***AAAAABC  9103501525  NO
***AAAAABC  9103510000  NO
***AAAAABC  9120656565  NO
***AAAAABC  9157777667  NO
***AAAAABC  9167777767  NO
***AAAAABC  9167777766  NO
****ABABAB  9103501525  NO
****ABABAB  9103510000  NO
****ABABAB  9120656565  YES
****ABABAB  9157777667  NO
****ABABAB  9167777767  NO
****ABABAB  9167777766  NO
***AAAABBA  9103501525  NO
***AAAABBA  9103510000  NO
***AAAABBA  9120656565  NO
***AAAABBA  9157777667  YES
***AAAABBA  9167777767  NO
***AAAABBA  9167777766  NO

Автор: dizler 28.10.2012, 15:10
feodorv, 
спасибо большое за идею и даже реализацию!
вроде бы универсально обрабатывает, пока неточностей не нашел

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)