2012-06-17 3 views
5

Как я могу подсчитать количество вхождений в строке С из /?Как я могу подсчитать количество вхождений символа '/' в строку C?

Я могу это сделать:

int countSlash(char str[]) 
{ 
    int count = 0, k = 0; 
    while (str[k] != '\0') 
    { 
      if (str[k] == '/') 
       count++; 
      k++; 
    } 
    return count; 
} 

Но это не элегантный способ; любые предложения о том, как его улучшить?

+3

У вас достаточно элегантно ИМО ... –

+1

Главной критикой может быть довольно специализированный интерфейс по сравнению с 'int countChar (char const * str, char c)', который (а) обещает не изменять переданную им строку и (b) можно использовать для подсчета звездочек, пробелов и т. д., практически без потери эффективности. Вы можете написать простую функцию 'int countSlash (char const * str) {return countChar (str, '/'); } ', если вам действительно нужен менее общий интерфейс. У вас есть достойный шанс, что компилятор будет оптимизировать это для вас, если включена инкрустация и т. Д. –

+0

Элегантность, может быть по-разному. Это может быть кратчайший или наиболее читаемый или наиболее понятный. И наиболее читаемый, также может быть самым нечитаемым для другого человека. Поэтому «Элегантность» - это субъективная мысль. Может быть, вы должны спросить об ЭФФЕКТИВНО, с точки зрения скорости. – ChinoCarloSedilla

ответ

5

strchr бы меньший цикл:

ptr = str; 

while ((ptr = strchr(ptr '/')) != NULL) 
    count++, ptr++; 

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

+1

Правда, но нет оснований писать такой код в 21 веке! –

+1

@ OliCharlesworth HA возможно так. У меня нет проблем с такого рода 1-лайнером в стандартном C, но опять же петли вроде этого не часто заканчиваются в моем собственном коде. – pb2q

+3

Как код кодера 21-го века написал код, @OliCharlesworth? Я 20-й C Coder, который все еще работает; то, что pb2q написал, выглядит хорошо для меня как тело функции countSlash(). –

2

Ваш достаточно хорошо. Может быть, это будет выглядеть красивее, чтобы некоторые из них:

int countSlash(char * str) 
{ 
    int count = 0; 
    for (; *str != 0; ++str) 
    { 
     if (*str == '/') 
      count++; 
    } 
    return count; 
} 
0

Это также будет работать:

int count=0; 
char *s=str; 
while (*s) count += (*s++ == '/'); 
+3

Почему нет пробелов? Почему актеры? Почему не просто 'n + = (* s ++ == '/');'? –

+0

@JonathanLeffler: Да, было бы проще на глазу;) - cast: потому что str [] - это массив, а не строка, и это C – slashmais

+1

@slashmais, я уверен, что явное приведение полностью избыточно. Прошло много времени с тех пор, как я выполнил какое-либо реальное кодирование в C, но, насколько я помню, когда вы передаете переменную, ссылающуюся на массив, она автоматически понижается до указателя на первый элемент указанного массива. Следовательно, 'char str []' и 'char * str' должны быть полностью взаимозаменяемы для всех целей и задач. –

2

Generic интерфейс, очевидный подход, соответствующие типы и чисто идиоматические выражения:

size_t str_count_char(const char *s, int c) 
{ 
    size_t count = 0; 

    while (s && *s) 
     if (*s++ == c) 
      ++count; 

    return count; 
} 

Oli Чарльзуорт вероятно, вызовет озабоченность по поводу заданий и условностей на одной строке, но я думаю, что это довольно хорошо скрыто ;-)

+0

+1 для идеи, ей понравилось – ron

+0

Я мог ошибаться, но я думаю, что ваш цикл инвариант можно упростить до просто 'while (* s)'. Необходимо только проверить, что '' 'не является указателем' NULL' в самом начале выполнения. –

+0

@GregE: Вы правы, проверка «NULL» требуется не чаще всего здесь. Я твердо верю, что компилятор умнее меня, поэтому я полагаюсь на компилятор, чтобы его оптимизировать. Это должно быть легко, поскольку мы не изменяем '' 'в любой точке этой функции. – Philip

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