C++编程:输入一串字符,统计其中出现的每一种字符的个数(包括中文字符)

题目描述

任意输入一串字符,统计其中出现的每一种字符的个数(包括中文字符)

输入

一个中英文混合的字符串

输出

字符 数量

字符 数量

...

字符 数量

english 总英文字符数

chinese 总中文字符数

注:英文在前,中文在后,按其值从小到大按序输出。
void stat(cha*s,int num[])
{
memset(num,0,128*4)
while(*s!='\0')
{num[*s]++;
s++;
}
}

/*
   没有仔细进行代码测试,如果有问题,欢迎继续提问。
*/
#include <iostream>

using namespace std;
struct Chinese
{
 char                 chr1Chinese[2]; //文字占2个字节的空间,因为已知汉字占2个字节,所以不需要增加一个字节保存结束符
 int                  intApearTimes;  //该文字出现的次数
 struct Chinese*      next;           //指向下一个节点
};
class ChineseCache //中文字符缓存
{
 private:
  Chinese*        stcCacheHead;  //缓存首地址
  Chinese*        stcCacheCur;   //缓存当前的操作位置,一般指向尾部,每次增加一个节点,它也随着移动一个单位

  void AddCache(const char* chr1Chinese);

 public:
  ChineseCache();
  ~ChineseCache();

  void AddApearTimes(const char* chr1Chinese);
  void ShowAllCache();
};
ChineseCache::ChineseCache()
{
   stcCacheHead = NULL;
}
ChineseCache::~ChineseCache()
{
   //释放缓存
   if (stcCacheHead)
   {
     Chinese* ChineseTemp;
     while(stcCacheHead)
     {
       ChineseTemp = stcCacheHead;
       stcCacheHead = stcCacheHead->next;
       delete ChineseTemp;
     }
   }
}
void ChineseCache::AddCache(const char* chr1Chinese) //增加一个汉字的缓存空间。chr1Chinese:一个中文字符,即一个汉字
{
   int loop;
   if (stcCacheHead)
   {/*
     Chinese* ChineseNew;
     ChineseNew = new Chinese;
     stcCacheCur->next = ChineseNew;      //将上一个节点与新节点连接起来
     stcCacheCur = ChineseNew;            //将记录当前操作位置的标记,移至新节点的位置
     */
     //以下作用和上面代码一样,但在循环时效率比上面代码稍高
     stcCacheCur->next = new Chinese;
     stcCacheCur = stcCacheCur->next;
     stcCacheCur->intApearTimes = 0;
   }
   else //如果是第一次增加缓存
   {
     stcCacheCur = stcCacheHead = new Chinese;
     stcCacheCur->intApearTimes = 0;     //该文字出现的次数初始化为0,以便后续进行累加运算
   }
   //将参数提供的汉字缓存起来,如果字符数组chr1Test[2]保存的数据为“中”
   //那么在计算机内部它2个元素的值分别为:chr1Test[0] == -42,chr1Test[1] == -48
   for (loop = 0; loop < 2; loop ++)
      stcCacheCur->chr1Chinese[loop] = chr1Chinese[loop];
   stcCacheCur->next = NULL;
}
void ChineseCache::AddApearTimes(const char* chr1Chinese)
{
   bool bMatch = false; //是否与形参相匹配,在缓存中是否找到该汉字*chr1Chinese。
   if (stcCacheHead)
   {
     Chinese* chn;
     //找出缓存中与参数相同的汉字,如果找到则将露面次数加1
     for (chn = stcCacheHead; chn; chn = chn->next)
     {
        //因为chn成员chr1Chinese没有结束符,故而不能使用strcmp函数
        //而且此处运算简单,更不需要调用库函数,增加负担
        if (chn->chr1Chinese[0] == chr1Chinese[0] && chn->chr1Chinese[1] == chr1Chinese[1])
        {
          chn->intApearTimes ++;
          bMatch = true; //找到目标,标记为真
          break;
        }
     }
     //如果没有匹配到要查询的汉字,则将该汉字增加到缓存中
   }
   if (bMatch == false)
   {
     AddCache(chr1Chinese);
     stcCacheCur->intApearTimes ++;
   }
}
void ChineseCache::ShowAllCache()
{
   if (stcCacheHead)
   {
     Chinese* ChnTemp;
     char chn[3] = "";
     for (ChnTemp = stcCacheHead; ChnTemp; ChnTemp = ChnTemp->next)
     {
        //因为ChnTemp->chr1Chinese没有结束符,所以不能使用cout输出
        //需要借助有2个字节以上的字符数组来输出
        chn[0] = ChnTemp->chr1Chinese[0], chn[1] = ChnTemp->chr1Chinese[1];
        cout<<chn<<"  "<<"数量: "<<ChnTemp->intApearTimes<<endl;
      }
   }
}
class EnglishCache //英文字母缓存
{
  //由于已知英文字母只有26个,所以可用顺序表结构存储之,而不是链表。
 private:
  //某个字母出现的次数。0到25表示A到Z,不区分大小写
  //如果int1ApearTimes[2]的值等于4,则表示字母C出现了4次
  int          int1ApearTimes[26];

 public:
  EnglishCache();
  void AddApearTimes(char letter);
  void ShowAllCache();
};
EnglishCache::EnglishCache()
{
   int loop;
   for (loop = 0; loop < 26; loop ++)
      int1ApearTimes[loop] = 0;
}
void EnglishCache::AddApearTimes(char letter)
{
   int loop;
   for (loop = 0; loop < 26; loop ++)
      //不区分大小写
      if (65 + loop == letter || 97 + loop == letter)
      {
        int1ApearTimes[loop] ++;
        break;
      }
}
void EnglishCache::ShowAllCache()
{
   int loop;
   char ch;
   for (loop = 0; loop < 26; loop ++)
   {
      if (int1ApearTimes[loop])
      {
        ch = 65 + loop;
        cout<<ch<<"  "<<"数量: "<<int1ApearTimes[loop]<<endl;
      }
   }
}
void StatisticsCharacter(const char* str)
{
   int intChnCount = 0, intEngCount = 0;//中文、英文字符出现的总次数
   ChineseCache ChnCache;
   EnglishCache EngCache;
   while (*str)
   {
      //如果这样写if (*str >= 65 && *str <= 90 || *str >= 97 && *str <= 122) //判断是否为字母,否则为汉字
      //则会忽略标点符号。如果字符串中有标点符号,那么将把标点符号看成中文。所以没有采用此算法。
      if (*str < 0) //如果是汉字,汉字在计算机内实际值为负数
      {
        ChnCache.AddApearTimes(str);
        intChnCount ++;
        str += 2; //汉字占2个字节,所以一次要跑2个字节
      }
      else //如果是英文字母
      {
        EngCache.AddApearTimes(*str);
        intEngCount ++;
        str ++;
      }
   }
   EngCache.ShowAllCache();
   ChnCache.ShowAllCache();
   cout<<"english 总英文字符数: "<<intEngCount<<endl;
   cout<<"chinese 总中文字符数: "<<intChnCount<<endl;
}
void main()
{
   char string[1000];
   cout<<"1.英文字母不区分大小写。2.请不要输入空格,否则空格后的所有字符将被舍弃"<<endl<<endl;
   cout<<"请输入字符串"<<endl;
   cin>>string;
   ::StatisticsCharacter(string);
}

追问

空格也要统计 输出样例
2
B 1
P 1
T 1
U 1
e 1
i 1
l 1
o 1
v 1
,1
爱 1
北 1
我 1
邮 1
english 11
chinese 5

温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-10-07
英文字符是指字母吗?中文字符是指汉字吗?请给出输入输出样例追问

空格也要统计 输出样例
2
B 1
P 1
T 1
U 1
e 1
i 1
l 1
o 1
v 1
,1
爱 1
北 1
我 1
邮 1
english 11
chinese 5
无论什么字符都要统计
最好英文大小写能区分 空格计入英文 标点符号计入中文 谢谢谢谢谢谢谢谢谢

相似回答