【问题标题】:C program to take a string as input a count the character with the lowest frequencyC程序将字符串作为输入计算频率最低的字符
【发布时间】:2020-05-19 09:16:30
【问题描述】:

我编写了这段代码来查找频率最低的字符。

所以,输入"We were here",输出应该是

The letter with the minimum frequency is ‘h’ and the frequency is 1. 

但它显示

我的错误是什么?我已经尝试了所有方法,但找不到问题根源。

#include <string.h>

int main()
{
    char s[1000];  
    int  a[1000],i,j,k,count=0,n;

    printf("Enter  the string : ");
    gets(s);

    for(j=0;s[j];j++);
    k=n=j; 

    for(i=0;i<n;i++)  
    {
        a[i]=n;
        count=1;
        if(s[i])
        {
            for(j=i+1;j<n;j++)  
            {   
                if(s[i]==s[j])
                {
                    count++;
                    s[j]='\0';
                }
            }  
            a[i]=count;

            if(count<=k)
                k=count;
       }
    }

    printf("The letter with the minimum frequency is ");
    for(j=0;j<n;j++)  
    {
        if(a[j]==k)
        {
            printf(" '%c',",s[j]);
        }
    }  

    printf("and the frequency is %d t\n ",k);

    return 0;
}

【问题讨论】:

  • 它仍然有效
  • 您的截图与源代码不符...
  • 我已经收录了
  • 阅读我的回答。它清楚地解释了您需要更改哪些内容以使您的检查不区分大小写。

标签: c arrays string


【解决方案1】:

您的程序可以使用多种优化,但让我们关注主要问题。最少出现的字符输入字符串"We were here"实际上是'W''w''h',它们都出现一次。

您的错误是将'W''w' 视为同一个字符。它们不是,因为第一个是大写,第二个是小写,它们有不同的表示。

请注意,如果输入的字符串是"we were here",您将得到预期的输出:

The letter with the minimum frequency is 'h', and the frequency is 1

现在您必须做出设计选择:

  • 您希望您的程序区分大小写吗?保持程序不变。
  • 您希望您的程序不区分大小写吗?您必须将输入字符转换为小写(或大写;这是您的选择)比较它们之前
if(tolower(s[i]) == tolower(s[j]))
{
    count++;
    s[j]='\0';
}

tolower() 函数将单个字符转换为小写(不是整个字符串!),它在ctype.h 中定义。


注意: gets() 函数已弃用,不应使用。这是危险的,因为它不提供对用户插入的字符数的任何检查,因此恶意软件很容易使您的程序崩溃。你可以改用fgets

fgets(s, 1000, stdin);

它一直读取到\n 或输入文件的EOF(在本例中为标准输入)。您只需注意结束 \n 包含在返回的字符串中。

【讨论】:

    【解决方案2】:

    很抱歉,您的代码对于计算字符直方图的给定简单问题来说太复杂了。您只需要对字符串进行一个循环来计算直方图,再加上另一个循环来确定最小值(或者在计算直方图时保持最小计数和相关字母)。

    除此之外,打印的结果是正确的。如果您希望您的计数不区分大小写,可以使用tolower 等。

    【讨论】:

      【解决方案3】:

      在 C 中,您可以利用 char 实际上存储为 int 的事实。下面的ascii 数组用于存储输入字符串中每个 ASCII 字符的频率。如果B 字符,则ascii[66] 递增(B 的 ASCII 码为 66)。

      我实现了一个简单的smallest 函数,它返回ascii 数组中最小项的索引。如果 ascii 是 {1,9,1,2,3,4,5,6,1,8}smallest 将返回一个数组 {0, 2, 8},其中 nf 设置为 3。

      不要使用不安全的gets(),而是使用fgets() 以更安全的方式做你想做的事。

      以下代码仅适用于 ASCII 字符(int 表示 > 127 的任何内容都会导致程序崩溃)。

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <limits.h>
      #include <ctype.h>
      
      #define LEN     128  /* size of ASCII table */
      #define BUFLEN  2048
      
      /* initialized to zero */
      int ascii[LEN];
      char buf[BUFLEN];
      
      /* 
       * function to return the index of minimum numbers
       * within an int array
       * arr - input array
       * len - size of the input array
       * n - size of the returned array
       * f - frequency of the min number
       * the caller has to free() the buffer returned by 
       * this function
       */
      int *smallest(int arr[], size_t len, int *n, int *f){
              int i, j, *ret, min = INT_MAX;
              ret = malloc(len * sizeof(int));
              memset(ret, 0, len);
      
              i = 0; /* index within ret */
              for (j=0; j<len; j++){
                      /* update the min value */
                      if (arr[j] < min && arr[j] != 0) {
                              min = arr[j];
                              /* for a new min, start from index 0 */
                              i = 0;
                              ret[i++] = j;
                              continue;
                      }
      
                      if (arr[j] == min)
                              ret[i++] = j;
              }
      
              *f = min;
              *n = i;         /* number of elements in ret */
              return ret;
      }
      
      int main(){
              int i, f, *p;
      
              printf("Enter the string : ");
              fgets(buf, BUFLEN, stdin);
      
              /* use letters as indices in the ascii[] array */
              for(i=0; i<BUFLEN; i++)
                      ascii[tolower(buf[i])]++; /* case-insensitive */
      
              /* we can reuse i */
              p = smallest(ascii, LEN, &i, &f);
      
              printf("The letter(s) with the minimum frequency = ");
              while(i >= 0){
                      if (isalpha(p[i]))
                              printf("'%c', ", p[i]);
                      i--;
              }
              printf("and the frequency is %d.\n", f);
              free(p);
      
              return 0;
      }
      

      【讨论】:

      • 它仍然将 W 和 w 显示为 2 个不同的字符,我希望它们相同
      • 它将Ww 显示为不同的字符,因为它们不同。如果您想要不区分大小写的解决方案,请在更新 ascii[] 数组之前使用 tolower()。查看修改后的代码
      猜你喜欢
      • 2020-09-16
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 2021-02-26
      • 1970-01-01
      • 2011-10-06
      相关资源
      最近更新 更多