2010-11-20 2 views
29

Я есть строка strПодсчет числа вхождений полукокса в строке в C

char *str = "100.10b.100.100"; 

Я хочу, чтобы подсчитать число вхождений '.' в str, предпочтительно один вкладыш. (не по возможности не петли)

Мой подход был бы стандартный strchr:

int i = 0; 
    char *pch=strchr(str,'.'); 
    while (pch!=NULL) { 
    i++; 
    pch=strchr(pch+1,'.'); 
    } 
+3

К сумке мантр - что вы пробовали? как насчет этого не работает? ....... – KevinDTimm

+0

@KevinDTimm: Я разместил свой подход. – Mike

+4

Как указал tvanfosson, вы можете сделать это с рекурсией, и, возможно, это то, что ваш учитель хотел видеть, что вы делаете, но это совершенно идиотский способ сделать это. Это приведет к переполнению стека * для достаточно больших строк ... а не к добрым типам SO, которые делают вашу домашнюю работу для вас, плохой вид! ; -) –

ответ

9

без петель будет трудно, так как нет никакой стандартной функции библиотеки C, что делает это, и вы должны смотреть на всех символов :)

возьму очевидное решение:

int i, count; 
for (i=0, count=0; str[i]; i++) 
    count += (str[i] == '.'); 

Не стесняйтесь, чтобы сжать две линии фактического кода в один, если вам нужно :)

+1

'for (i = 0; s [i]; s [i] == '.'? I ++: s ++);' –

+1

Это изменяет s, хоть. Я пытался оставить оригинальные ценности в одиночку :) Кроме этого, хорошо! –

4

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

int count_characters(const char *str, char character) 
{ 
    const char *p = str; 
    int count = 0; 

    do { 
     if (*p == character) 
      count++; 
    } while (*(p++)); 

    return count; 
} 
20

Посмотрите, ma, no петли.

int c = countChars(s, '.'); 

int countChars(char* s, char c) 
{ 
    return *s == '\0' 
       ? 0 
       : countChars(s + 1, c) + (*s == c); 
} 

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

+0

ах, сладость и свет :) - но ты не можешь сделать тройной, так что есть только одно возвращение (и нет, если)? – KevinDTimm

+1

Я думаю, '' 'должен быть': '. Кроме того, «никакие петли» хороши, но это не так легко читать и не поддерживать, как цикл, и это не будет быстрее. (Хотя это может быть не медленнее, благодаря рекурсии хвоста.) Умный код - это не всегда хороший код, особенно когда он запутывает смысл. – cdhowie

+0

@ Кевин - да, но это было бы менее читаемо, ИМО. – tvanfosson

1

Единственный способ сделать это без цикла - это рекурсия. Ниже включен для развлечения, но НЕ рекомендуется в качестве решения:

size_t CountChars(char* s, char c) 
{ 
    return *s ? ((c==*s) + CountChars(s+1)) : 0; 
} 
3

Если вы заинтересованы в однострочника (ну, два):

size_t count = 0; 
while(*str) if (*str++ == '.') ++count; 
+0

Вот он сводится к одному для оператора, включая переменную цикла и вывод: 'for (size_t i = 0; s [i] || printf ("% d \ n", i)> INT_MAX; s [i] == '.'? i ++: s ++); ';-) –

18

ОК, реализация без цикла (и да, это подразумевается как шутка).

size_t CountChars(const char *s, char c) 
{ 
    size_t nCount=0; 
    if (s[0]) 
    { 
    nCount += (s[0]==c); 
    if (s[1]) 
    { 
     nCount += (s[1]==c); 
     if (s[2]) 
     { 
     nCount += (s[2]==c); 
     if (s[3]) 
     { 
      nCount += (s[3]==c); 
      if (s[4]) 
      { 
      nCount += (s[4]==c); 
      if (s[5]) 
      { 
       nCount += (s[5]==c); 
       if (s[6]) 
       { 
       nCount += (s[6]==c); 
       if (s[7]) 
       { 
        nCount += (s[7]==c); 
        if (s[8]) 
        { 
        nCount += (s[8]==c); 
        if (s[9]) 
        { 
         nCount += (s[9]==c); 
         if (s[10]) 
         { 
         /* too long */ 
         assert(0); 
         } 
        } 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
    return nCount; 
} 
+4

Я думаю, что вы удвоили свой 8 здесь: 'nCount + = (s [88] == c);'. Вы должны написать генератор кода C, который называется 'cc' через' system', чтобы получить окончательный результат. Или даже лучше, рекурсивный генератор кода, чтобы избежать циклов в генераторе кода. –

+0

+1 для умения! –

+0

Семь лет спустя кто-то проголосовал за это, даже не замечая, почему. Это был комичный кусок кода и говорит так наверху. Это иллюстрирует непрактичность вопроса. Кто-то беспокоится, что это плохой стиль ??? –

68

Вот как я это сделать (минимальное число переменных требуется):

for (i=0; s[i]; s[i]=='.' ? i++ : *s++); 
+5

Это один хороший ответ, + 1 –

+2

Нет, я увеличиваю либо '' или 'i' в зависимости от того,' '' '' '' '.'', либо нет. Выражение 's + i' всегда увеличивается ровно на 1 на каждой итерации, но это может быть счетчик (' i') или базовый указатель ('s'), который увеличивает' s + i'. –

+2

Упс, похоже, комментарий, на который я отвечал, получил удаленный .. –

1

Я не люблю Гото, до сих пор,

int i=0,count=0; 
    char *str = "100.10b.100.100"; 
    a: 
    if(str[i]=='.') 
     count++; 
    i++; 
    if(str[i]) 
    goto a; 
+2

Очевидно, что петля – KevinDTimm

+0

и где есть петля: P? –

0

каждый раз запустить этот код ребенка dijkstra плачет :)

1 
    2 
    3 
    4 #include <ctype.h> 
    5 #include <stdio.h> 
    6 #include <stdlib.h> 
    7 #include <string.h> 
    8 
    9 
10 size_t bytewise_pop_count(
11  unsigned char * bp, size_t l 
12) { 
13  if ((bp) && (l)) { 
14   return bytewise_pop_count(bp+1, l-1) + (bp[0] ? 1 : 0); 
15  } 
16  return 0; 
17 } 
18 
19 void mercilessly_complement_bytes(
20  unsigned char * bp, size_t l 
21) { 
22 /* 
23  transform 
24   0 -> 1 
25   !0 -> 0 
26 */ 
27  if ((bp) && (l)) { 
28   bp[0] = bp[0] ? 0 : 1; 
29   mercilessly_complement_bytes(bp+1, l-1); 
30  } 
31 } 
32 
33 void xor_bytes(
34  unsigned char * bp1, unsigned char * bp2, size_t l 
35) { 
36  /* stores result in bp2 */ 
37  if ((bp1) && (bp2) && (l)) { 
38   bp2[0] ^= bp1[0]; 
39   xor_bytes(bp1+1, bp2+1, l-1); 
40  } 
41 } 
42 
43 
44 int main(int argc, char * * argv) { 
45  char c; 
46  size_t count; 
47  size_t l; 
48  char * string; 
49  char * t; 
50 
51  if (argc < 3) { 
52   fprintf(stderr, 
53    "\n" 
54    "==> not enough arguments -- need char and string\n" 
55    "\n" 
56  ); 
57   return EXIT_FAILURE; 
58  } 
59 
60  c = argv[1][0]; 
61  string = argv[2]; 
62 
63  if (l = strlen(string)) { 
64   t = malloc(l); 
65   memset(t, c, l); 
66   xor_bytes(string, t, l); 
67   mercilessly_complement_bytes(t, l); 
68   count = bytewise_pop_count(t, l); 
69   free(t); 
70  } else { 
71   count = 0; 
72  } 
73 
74  if (isprint(c)) { 
75   printf(
76    "\n" 
77    "==> occurences of char ``%c'' in string ``%s'': %zu\n" 
78    "\n" 
79    , c, string ? string : "<NULL>", count 
80  ); 
81  } else { 
82   printf(
83    "\n" 
84    "==> occurences of char ``%hhu'' in string ``%s'': %zu\n" 
85    "\n" 
86    , c, string ? string : "<NULL>", count 
87  ); 
88  } 
89  return EXIT_SUCCESS; 
90 } 
+0

Не совсем «одна строка (если возможно, не петли)», просил! – Andrew

+0

AAAAAAAAAAAAAAAAHHH – Fractaly

1

// Я думаю, это должно Работа. Одна строка и отсутствие цикла.

int countChar(char *s, char letter) { 
    return ((*s) ? (((*s++ == letter)? 1:0)) + countChar (s, letter)): 0); 
} 
Смежные вопросы