0

私は C の初心者です。自分の機能を完了するために助けが必要です。

ミッションは次のとおりです。

string を受け入れる関数を作成しますmaximum length of 256 characters containing characters from 'a' to 'z'

各文字の出現回数を出力する関数。

例: 入出力abbaは次のようになります。

a = 2 b = 2 c = 0 d = 0 .... z = 0

関数の実行中は if を使用しないでください。

このプログラムを完成させるために、あなたの助けをお願いします。

これは私のコードです

#include "stdlib.h"
#include "conio.h"
#include "stdio.h"
#include "string.h"
#define size 256



void repeat(char *str);
void main()
{
    char str[size];
    printf("Please enter a string:\n");
    flushall;
    gets(str);
    repeat(str);
    system("pause");
    return ;
}
void repeat(char *str)
{

    char temp=strlen(str);
    int i, count=0;
    do
    {
    for (i=0; i<temp ; i++)
        {
            count += (*str == str[temp-i]);
        }
    printf("Char %c appears %d times\n ",*str,count);
    count=0;
    }
    while(*(str++));
}



    Please enter a string:
abbba
Char a appears 1 times
 Char b appears 2 times
 Char b appears 1 times
 Char b appears 0 times
 Char a appears 0 times
 Char   appears 0 times
 Press any key to continue . . .

これが出力です!同じ建物でやりたいです。Char a が 2 回表示され、Chars b が 3 回表示されるようにする必要があります。

4

5 に答える 5

3

を使用しないことを規定しifます。これはその制限を満たします。

#include <stdio.h>

int main(void) {
    int i, c;
    int counts[256] = { 0 };
    const char lower[] = "abcdefghijklmnopqrstuvwxyz";
    while ((c = getchar()) != EOF) {
        counts[c] += 1;
    }
    for (i = 0; lower[i]; ++i) {
        c = lower[i];
        printf("Char %c appears %d times.\n", c, counts[c]);
    }
    return 0;
}

あなたの試みの問題は、どの文字についての情報をすでに出力したかを記憶するための状態を追跡していないことです。また、カウントの一部として検討中の文字を含めることもできません。また、各文字のカウント情報を収集するために文字列に対して複数のパスを作成しますが、これは正確性には影響せず、パフォーマンスだけに影響します。どの文字の情報を既に出力したかをどうにかして覚えていて、同じ文字が文字列の後半に現れたときに同じ文字を再び出力しないようにすることができる場合、メソッドは表示される文字のカウントを出力する必要があります。その後、まったく表示されなかった文字のゼロ カウントを出力する必要があります。出力をアルファベット順にする必要がある場合は、それにも注意する必要があります。

情報を適切に追跡し、出力をアルファベット順に印刷できるようにする 1 つの方法は、配列内の各文字のカウントを維持することです。文字列をパスし、見つかった各文字に関連付けられたカウントをインクリメントした後、カウント配列を反復処理してカウントを出力できます。


次のプログラムは zubergu 用です。

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

int main (void) {
    int i, c;
    int counts[26] = { 0 };
    const char lower[] = "abcdefghijklmnopqrstuvwxyz";
    while ((c = getchar()) != EOF) {
        switch (c) {
        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
        case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
        case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
        case 'v': case 'w': case 'x': case 'y': case 'z':
            counts[strchr(lower, c) - lower] += 1;
            break;
        default:
            break;
        }
    }
    for (i = 0; lower[i]; ++i) {
        printf("Char %c appears %d times.\n", lower[i], counts[i]);
    }
    return 0;
}
于 2013-09-09T08:44:44.050 に答える
1

これは最も醜いソリューションの 1 つかもしれませんが、最も単純なソリューションでもあります。

while(*str!='\0')
{
  switch(tolower(*str))
  {
    case 'a': a_count++;break;
    case 'b': b_count++;break;
    .
    .
    .
  }
  str++;
}

str が有効な文字を指しているかどうかを確認し、小文字に変換するため、大文字と小文字は区別されません (「A」は「a」文字と同じになります)。「if」は使用されず、「\0」文字で終了するすべての長さの文字配列で機能します。

于 2013-09-09T09:03:11.230 に答える
0

最適化されたソリューション。complex O(N) , N - 入力文字列の長さ。

あなたのボイドリピート機能は次のようになります。

void repeat(char *str)
{

    int temp=strlen(str);// use int here
    int i, count=0;
int charCount[26] = {0};


#if 0
//your logic, traverses the string (n*n) time, n - input string length.
    do
    {
        for (i=0; i<temp ; i++)
        {
            count += (*str == str[temp-i]);
        }
        printf("Char %c appears %d times\n ",*str,count);
        count=0;
    }
    while(*(str++));
#endif

#if 1
// This logic traverses string once only. n time, n - input string length.
for (i=0; i<temp ; i++)
    {
        charCount[str[i]%'a']++;
    }

for (i=0; i<26 ; i++)
    {
        printf("%c appears :  %d times \n", 'a'+i, charCount[i]);
    }
#endif
}

【編集】こちら

charCount[str[i]%'a']++; // 'a' is used a its ASCII Value.

として使用できます

charCount[str[i]%97]++;
  1. 小文字と大文字の両方を数えたい場合。

このように使用します

if(str[i] >= 'a' && str[i] <= 'z'){
        iMap = str[i]%97; // 97 is ASCII Value of 'a'
        charCount[iMap]++;
    }else if(str[i] >= 'A' && str[i] <= 'Z'){
        iMap = str[i]%65; // 65 is ASCII Value of 'A'
        charCount[iMap]++;
    }
//iMpa is a integer (int iMap;), used for better undersanding.
于 2013-09-09T10:22:17.033 に答える