读书人

大写字母出现次数统计有关问题(帮忙看

发布时间: 2012-03-23 12:06:21 作者: rapoo

大写字母出现次数统计问题(帮忙看下)
问题描述:
例如给定一个由大写字母组成的序列
ABCDEFGABCDDD其中ABC分别出现了2次,D出现了4次,EFG分别出现了1次
对于给定的字符序列,求每个大写字符出现的次数,并把出现的次数按从小到大的顺序输出,如出现的次数相同则按字母序列排序输出

对于不是特别大的字母序列,可以用长度为26位数组记录26个字母出现次数,然后遍历的方法输出,但是对于很长的字母序列,似乎那样方法不好吧?
下面是我写的,可能显得麻烦,而且还存在错误,苦于找不到,向各位牛人请求帮忙啊!

我的想法是:出现次数和相应字母用一个结构体存储,对输入序列关于次数从小到大排序后,截取出次数相同的字母集合,调用out函数排序处理输出按字母表顺序的字母序列,并输出该字母集合的出现次数。

程序运行举例:
输入:
ADDAABCBBCECDEDaDEFFGGgGHHHkHHKH

输出:
K:1
F:2
ABCEG:3
D:5
H:6

以下是本人写的code,好像是有点问题,但是我测试了好多数据都找不出来,希望那位帮帮忙吧!先谢过,待解之后给分!

C/C++ code
#include <iostream>#include <string>#include <vector>#include <cstdlib>using namespace std;struct W{    char uper;//字母值    int count;//该字母出现次数};   int cmpCnt( const void *a ,const void *b)//给出现次数排序qsort()时候用到的{    return ((W *)a)->count > ((W *)b)->count ? 1 : -1;}   void out(int size,vector<char> &nn)//处理次数相同的离散字母按从小到大输出字母序列{    char tt[26+1] = {'#'};        for(int j = 0; j < size; j++)            tt[j] = nn.at(j);        for(int k = 0; k < size; k++)            for(int m = k+1; m < size; m++)                if( tt[m] < tt[k] )                {                    char t = tt[m];                    tt[m] = tt[k];                    tt[k] = t;                }                    for(int k = 0; k < size; k++)                cout<<tt[k];            for(int j = size-1; j >= 0 ; j--)                nn.pop_back();}int main(){        W mm[26];    vector<char> nn;    for(int i = 0; i < 26; i++)    {        mm[i].uper = char(i+65);        mm[i].count = 0;    }        string str;    cin>>str;    const char* pstr = str.c_str();    for(int i = 0; i < (int)str.size(); i++)        if( *(pstr+i)  >= 'A' && *(pstr+i) <= 'Z' )        {            int index = int( *(pstr+i) ) - 65;            mm[index].count ++;        };     qsort(mm,26,sizeof(mm[0]),cmpCnt);    int pc = 0;    while( !mm[pc].count ) pc++;    if( pc == 26)        {        cout<<"No Answer"<<endl;        return 0;    }    int old = 65535;    for(int i = pc; i < 26; i++)        {        if( mm[i].count <= old )        {            old = mm[i].count;            nn.push_back(mm[i].uper);        }        else{            out(nn.size(),nn);            old = mm[i].count;            nn.push_back(mm[i].uper);            }        }    out(nn.size(),nn);    return 0;}


[解决办法]
"对于不是特别大的字母序列,可以用长度为26位数组记录26个字母出现次数,然后遍历的方法输出,但是对于很长的字母序列,似乎那样方法不好吧?"

为什么不好?
字母序列越长,反而越能体现出这个方法的优越性;

[解决办法]
对于不是特别大的字母序列,可以用长度为26位数组记录26个字母出现次数,然后遍历的方法输出,但是对于很长的字母序列,似乎那样方法不好吧?

我觉得这个方法很好呀!很长的字母序列就更好了!一个int[26]就排下了。如果你希望用单独的struct来做,

也最好在统计完成之后,将结果int[26]中的结果直接写入到struct里面,然后对struct数组排序输出
[解决办法]
首先,这个问题要求你一定要遍历一遍输入的字符串,所以O(N)的复杂度是必须的

其次,要将找到的字符串按照出现次数排序输出,由于排序的长度为26,因此这个代价可以忽略不计

不管如何,遍历一遍再记录是很好的方法。
[解决办法]
4楼的写的真好!!!!
学习了。
[解决办法]
把A到Z的ASC码减个数,让A对应0,Z对应25,连struct W都可以省了,直接用一个int w[26]就搞定了.
[解决办法]
class CountLetters
{
private int[] counter=new int[26];
public uint CountAlpha(string s)
{
char currentChar="";


foreach(currentChar in s)
{
if(currentChar<="A"&&currentChar>="Z")
counter[currentChar-"A"]++;
}
}
public void Output()
{
uint counts="";
uint index=0;
foreach(counts in counter)
writeline((index+++"A").ToString()+":"+counts.ToString());
}
}

读书人网 >软件架构设计

热点推荐