[HDOJ]1004. Let the Balloon Rise

本是一个简单的字符串统计类题目,但本着求是的态度还是想了很多,也准备写很多。
1. 首先想到的方法,把字符串统计到数据结构strvec中,然后逐个统计出现个数,最后选出出现最多个数者。
缺点:出现重复统计情况,浪费时间。虽然数据量小的话根本表现不出来。
本以为一次就可以AC掉的,结果还是粗心了。
在这条语句中:for(int i = 0;i < n;++i),一开始我把n写成了n-1,怎么也没想到如果我这么写的话,就忽略了只有一个字符串的情况了,如果n = 1,那么这样写的后果就是程序输出空string类,囧死...
今天太晚了,先把这个代码贴出啦,明天会有继续的改进,顺便复习下vector容器。

#include  < iostream >
#include 
< string >
using   namespace  std;
int  main()
ExpandedBlockStart.gifContractedBlock.gif
{
    
int n;
    
string strvec[1000];
    
while(cin>>&& n != 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
for(int i = 0;i < n;++i)
            cin
>>strvec[i];
        
int num,max;
        
string temp;
        max 
= 0;
        
for(int i = 0;i < n;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            num 
= 1;
            
for(int j = i + 1;j < n;++j)
                
if(strvec[i] == strvec[j])
                    
++num;
            
if(num > max)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                max 
= num;
                temp 
= strvec[i];
            }

        }

        cout
<<temp<<endl;
    }

    
return 0;
}


今天稍微改进下,加入了一个结果以避免对后面string的重复统计,但感觉这样还不是很完美,代码先附在这里:

#include  < iostream >
#include 
< vector >
#include 
< string >
using   namespace  std;
int  main()
ExpandedBlockStart.gifContractedBlock.gif
{
    vector
<string> strvec;
    vector
<bool> bvec; 
    
string str,temp;
    
int n;
    
while(cin>>&& n != 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
for(int i = 0;i < n;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            cin
>>str;
            strvec.push_back(str);
            bvec.push_back(
true);
        }

        
int num,max = 0;
        
for(int i = 0;i < n;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if(bvec.at(i))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                num 
= 1;
                
for(int j = i+1;j < n;++j)
                    
if(strvec.at(i) == strvec.at(j))
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
++num;
                        bvec.at(j) 
= false;
                    }

                
if(num > max)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    max 
= num;
                    temp 
= strvec.at(i);
                }

            }

        }

        cout
<<temp<<endl;
        strvec.clear();
    }

    
return 0;
}

 

      今天上午又稍微改了下,主要是每统计一次string的个数,就把后面跟他相等的string删除掉,以免到后面会造成不必要的重复统计,删除的工作主要由del函数和第二个
for
循环里面的两条语句完成,代码如下:

#include  < iostream >
#include 
< vector >
#include 
< string >
#include 
< algorithm >
using   namespace  std;
// del函数负责把string容器中位于beg和end之间值等于str的元素覆盖掉,然后返回期间值等于str的元素个数
int  del(vector < string > ::iterator beg,vector < string > ::iterator end, string  str)
ExpandedBlockStart.gifContractedBlock.gif
{
    vector
<string>::iterator it;
    
int count = 0;
    
for(it = beg;it != end;++it)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
if(*it == str)
            
++count;
        
else
            
*(it - count) = *it;    //the procedure of covering
    }

    
return count;
}


int  main()
ExpandedBlockStart.gifContractedBlock.gif
{
    vector
<string> strvec;
    
string str,str_temp;
    
int n,count;
    
while(cin>>&& n != 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
for(int i = 0;i < n;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            cin
>>str;
            strvec.push_back(str);
        }

        
int num,max = 0;
        vector
<string>::iterator it1,it2;
        
for(it1 = strvec.begin();it1 != strvec.end();++it1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            num 
= 1;
            
for(it2 = it1 + 1;it2 != strvec.end();++it2)
                
if(*it1 == *it2)
                    
++num;
            
if(num > max)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                max 
= num;
                str_temp 
= *it1;
            }

            
//把已经统计过的元素删除掉,以免后面会重复统计
            count = del(it1+1,strvec.end(),*it1);
            strvec.erase(strvec.end() 
-count,strvec.end()); 
        }

        cout
<<str_temp<<endl;
        strvec.clear();
    }

    
return 0;
}

 

      本来我想用泛型算法remove_if()来解决在vector<string>中删除元素的问题,但无奈remove_if()函数的第三个参数是一个函数,而我需要在程序中删除元素的操作又不仅仅是一次,所以我就只能放弃了remove_if(),但也正好趁此机会对泛型算法中的remove_if()算是复习了一下,顺便也跟vector中的成员函数erase()做了一下小比较,放在我的博客中。

      其实这样的题目本不用stl就可以解决,但用stl可以给我们带来很多方便,个人感觉,如果题目可以用偏C一点的数据结构解决的话,那还是首选它好了,毕竟那个效率要高些。用stl方便了我们,但在效率
方面还是比不上前者的。

       后续:晕死啊,我错了,在写remove_if()和remove()时候,突然想起来,在上面的那个程序中如果想删除后面重复的元素根本没有必要加入函数del的,直接调用泛型算法remove()不就可以达到目的了吗?囧....
修改后代码如下,提交后AC.

#include  < iostream >
#include 
< vector >
#include 
< string >
#include 
< algorithm >
using   namespace  std;

int  main()
ExpandedBlockStart.gifContractedBlock.gif
{
    vector
<string> strvec;
    vector
<string>::iterator it;
    
string str,str_temp;
    
int n;
    
while(cin>>&& n != 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
for(int i = 0;i < n;++i)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            cin
>>str;
            strvec.push_back(str);
        }

        
int num,max = 0;
        vector
<string>::iterator it1,it2;
        
for(it1 = strvec.begin();it1 != strvec.end();++it1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            num 
= 1;
            
for(it2 = it1 + 1;it2 != strvec.end();++it2)
                
if(*it1 == *it2)
                    
++num;
            
if(num > max)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                max 
= num;
                str_temp 
= *it1;
            }

            
//用泛型算法remove()就可以解决删除重复元素的问题了
           it = remove(it1+1,strvec.end(),*it1);
           strvec.erase(it,strvec.end());
        }

        cout
<<str_temp<<endl;
        strvec.clear();
    }

    
return 0;
}

 

      小结:虽然看了primer后对STL有了初步的了解,但是对STL的运用还不是那么熟练,需要多做题目多看书才可以的说。看到对面宿舍LZW有一本The C++ Standard Library,抽时间借过来看看。

 

转载于:https://www.cnblogs.com/krisdy/archive/2009/04/12/1434004.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值