2012-04-18 4 views
2

Мне нужно сравнить строку следующим образом. Может ли кто-нибудь предоставить мне некоторое понимание или алгоритм в C++. Например:сравнить две буквенно-цифровые строки

"a5" < "a11"  - because 5 is less than 11 
"6xxx < 007asdf" - because 6 < 7 
"00042Q < 42s"  - because Q < s alphabetically 
"6 8" < "006 9" - because 8 < 9 

ответ

1

Я предполагаю, что вы хотите, чтобы сравнение выполнялось в следующем порядке: наличие цифр в диапазоне 1-9; значение цифр; количество цифр; значение строки после цифр.

Это в C, но вы можете легко преобразовать его в класс std :: string C++.

int isdigit(int c) 
{ 
    return c >= '1' && c <= '9'; 
} 

int ndigits(const char *s) 
{ 
    int i, nd = 0; 
    int n = strlen(s); 

    for (i = 0; i < n; i++) { 
     if (isdigit(s[i])) 
      nd++; 
    } 
    return nd; 
} 

int compare(const char *s, const char *t) 
{ 
    int sd, td; 
    int i, j; 

    sd = ndigits(s); 
    td = ndigits(t); 

    /* presence of digits */ 
    if (!sd && !td) 
     return strcasecmp(s, t); 
    else if (!sd) 
     return 1; 
    else if (!td) 
     return -1; 

    /* value of digits */ 
    for (i = 0, j = 0; i < sd && j < td; i++, j++) { 
     while (! isdigit(*s)) 
      s++; 
     while (! isdigit(*t)) 
      t++; 

     if (*s != *t) 
      return *s - *t; 
     s++; 
     t++; 
    } 

    /* number of digits */ 
    if (i < sd) 
     return 1; 
    else if (j < td) 
     return -1; 

    /* value of string after last digit */ 
    return strcasecmp(s, t); 
} 
+0

. Что относительно пробела, которое я пробовал как «5 a» <«5 b» –

+0

@ user765443: Для («5 a», «5 b») у вас есть цифры, val цифр равны, число цифр равно - последняя строка 'return strcmp (s, t);' будет оценена. strcmp сравнивает остатки строк в соответствии с таблицей ASCII. Это означает, что мы сравниваем (0x20 0x61) с (0x20 0x62). Первая строка меньше. –

+0

Обратите внимание, что это * не * обрабатывает случай «a5» «a11» правильно - было немного поспешным, когда я его написал. Вам нужно будет добавить внутренний цикл к значению '/ * цифр * /'. –

-3

Попробуйте это и прочитать о std::string.compare:

#include <iostream> 
using namespace std; 


int main(){ 
    std::string fred = "a5"; 
    std::string joe = "a11"; 

    char x; 

    if (fred.compare(joe)) 
    { 
     std::cout << "fred is less than joe" << std::endl; 
    } 
    else 
    { 
      std::cout << "joe is less than fred" << std::endl; 
    } 


    cin >> x; 
} 
+1

Вы не обрабатывает возвращаемое значение сравнения() правильно: 0 означает равна, в противном случае знак указывает, что больше http://www.cplusplus.com/reference/string/string/compare/ –

+1

Вы не ответили на вопрос OP и предоставили плохой пример – Ulterior

2

Ваши примеры только показывают цифры, буквы и пробелы. Поэтому на данный момент я предполагаю, что вы игнорируете любой другой символ (эффективно относитесь к ним как к пробелам). Вам также кажется, что нужно рассматривать прописные и строчные буквы как эквивалентные.

Также представляется, что вы интерпретируете пробеги цифр как «термин» и пробежки букв как «термин», причем любой переход между буквой и цифрой эквивалентен пробелу. Единое пространство считается эквивалентным любому числу пространств.

(Примечание: Вы явно не хватает пример того, что делать в таких случаях, как:

"5a" vs "a11" 
"a5" vs "11a" 

Таким образом, вы должны решить, что делать, когда вы сталкиваетесь сравнение числового термина со строкой Вы также не говорите о неотъемлемых равенствах ... таких как «5 a» == «5a» только потому, что «5 a» < «5b»?)

Одним из ясных способов сделать это будет превратите строки в std::vector из «терминов», а затем сравните эти векторы (вместо того, чтобы пытаться сравнить строки напрямую). Эти термины будут либо числовыми, либо строковыми. Это может помочь вам начать работу, особенно STL ответа:

how to split a string value that contains characters and numbers

хитрых методы, которые работали на струнах себя без посредника будет быстрее в разовых сравнениях. Но их, вероятно, будет сложнее понять и изменить, и, возможно, медленнее, если вы собираетесь неоднократно сравнивать те же структуры.

Хорошим аспектом анализа в структуре является то, что вы получаете внутреннюю «очистку» данных в процессе. Получение информации в canonical form часто является целью в программах, допускающих такое разнообразие входов.

3

Я предлагаю вам взглянуть на алгоритм strverscmp - действительно, возможно, эта функция выполнит эту работу за вас.

Что делает эта функция, следующая. Если обе строки равны, return 0. В противном случае найдите позицию между двумя байтами с свойством , что перед ним обе строки равны, а сразу после есть разница. Найдите наибольшие последовательные строки цифр , содержащие (или начинающиеся с или завершающие) эту позицию. Если один или оба из них пустые, верните то, что strcmp (3) будет возвращено (числовое упорядочение байтовых значений). В противном случае сравните цифры цифр , где цифры цифр с одним или несколькими ведущими нулями интерпретируются так, как если бы они имели десятичную точку впереди (так что в отдельных символьных строках с более высокими нулями приходят перед цифрами строк с меньшим количеством ведущих нули). Таким образом, порядок составляет 000, 00, 01, 010, 09, 0, 1, 9, 10.

Смежные вопросы