注册 登录
编程论坛 C++教室

小菜b求大神解答,所有分数送上,希望能指出存在的问题,今晚坐等。。

哒哒哒啦啦啦 发布于 2016-04-12 22:42, 5550 次点击
程序是这样子滴
从输入中读取若干string对象并查找连续重复出现的单词(一个单词后面紧跟着这个单词本身)。要求记录连续重复出现的次数以及对应单词。如果存在,输出重复出现次数最多的单词及数目。例如: how now now now brown cow cow,答案是now出现了三次。
******************************************************************************************
#include<iostream>
#include<vector>
#include<string>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
void main()
{
    vector<string> v;      //这个是存放单词的
    vector<int> v1;        //这个是存放每个重复过的单词的容器,奇数位是单词在容器v中的位置,以便于比较后输出,偶数位是对应奇数位重复出现的最大数字
    vector<int> v2;        //这个是比较v1的遍数哪个大,将大的存在里面
    string i;
    int n1 = 1;
    while (cin >> i)
        v.push_back(i);
    int j = v.size();
    int n = 0,n1=0;
    for (n; n + 1 <= j; ++n)
    {
        if (v[n] == v[n + 1])
        {
            ++n1;
        }
        if ((v[n] != v[n + 1])&&(n1>0))      //有过重复,但这次不是,就把这个重复记录对应的v中的单词位置,重复次数放入v1中
    {
            v1.push_back(n1);//n1遍
            v1.push_back(n-1);//v中的单词位置,用于以后输出
        }
    }
    for (j = 0; j < (v1.size() / 2); j += 2)
    {
        int t;
        if (v1[j] < v1[j + 2])                   //哪个重复次数多就把谁放入v2中
        {
            v2.push_back(v1[j + 2]);
            v2.push_back(v1[j + 3]);
        }
        else {
            v2.push_back(v1[j]);
            v2.push_back(v1[j + 1]);
        }
        cout << "出现次数最多的单词是" << v[v2[1]] << endl;
        cout << "出现次数是" << v1[v2[0]] << endl;
    }
}






18 回复
#2
alice_usnet2016-04-12 22:53
程序代码:
//仅供参考
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;

int main()
{
  map<string,size_t> word_count;
  string word;
  while(cin >> word)
    ++word_count[word];
  for(const auto &w : word_count)
    cout<<w.first<<" occurs"<<w.second<<((w.second>1)?" times":" time")<<endl;
}
#3
lin51616782016-04-12 22:54
程序代码:
#include<iostream>
#include<vector>
#include<string>
#include<map>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::map;
int main()
{
    vector<string> vecStr;
    map<string, int> mapStrCount; //存储字符串出现次数
    string str;
    while (cin >> str)
        vecStr.push_back(str);
        
    int j = vecStr.size();
    for (int i = 1; i < j; ++i)
    {
        if(vecStr[i] == vecStr[i-1])//处理连续出现
            ++mapStrCount[vecStr[i]];
    }
    int nMax = 0;
    for (map<string, int>::iterator it = mapStrCount.begin();
         it != mapStrCount.end();
         ++it)
    {
        if(nMax < it->second)
        {
            nMax = it->second;
            str = it->first;
        }
    }
    if(nMax > 0)
    {
        cout << "出现次数最多的单词是" << str << endl;
        cout << "出现次数是" << nMax+1 << endl;//因为第一次出现没有记录到map里面 所以 出现次数要加一
    }
}


[此贴子已经被作者于2016-4-12 23:00编辑过]

#4
lin51616782016-04-12 23:01
回复 2楼 alice_usnet
你和我一样 没有注意到 连续出现 这个条件
1 2 2 3 3 3 2 2
你的做法会输出 2 出现 4 次
但要按照题目要求 应该输出 3 出现 3 次
因为 2 连续出现的次数 只有 2 次
#5
lin51616782016-04-12 23:04
        cout << "出现次数最多的单词是" << v[v2[1]] << endl;
        cout << "出现次数是" << v1[v2[0]] << endl;

这个结果必须在上一个循环 计算完成才能知道
所以你应该把输出结果的语句写在 for 外面
#6
哒哒哒啦啦啦2016-04-12 23:08
回复 5楼 lin5161678
放在外面也不对呢。。我就是想知道我这个怎么改。。。
map还没学,想看看我的这种到底哪里错了。。
#7
哒哒哒啦啦啦2016-04-12 23:13
回复 2楼 alice_usnet
厉害。。能看看我这种哪里错了吗?
#8
lin51616782016-04-13 00:22
你说的错误是 语法错误?
拜托这种问题要提前说清楚

void main()

不要用void main
程序代码:
    int n1 = 1;
    while (cin >> i)
        v.push_back(i);
    int j = v.size();
    int n = 0,n1=0;

n1 你定义2次
这种问题 除了不仔细之外 更重要的是 你不明确你每一个变量要做什么 而且变量名随便写
不要用这种编号 忘记数到几 分分钟懵逼

程序代码:
    for (n; n + 1 <= j; ++n)
    {
        if (v[n] == v[n + 1])
        {
            ++n1;
        }

for(n;..)
这种奇葩的写法 真不知道你们是怎么总结出来的
毫无意义 不想设置初值 就直接写分号跳过 for(;...)
你这里的 n+1 <= j 也是 难以理解
为什么不写 n < j ?
最后 这个循环的 n 的最大值是 j - 1
那么循环里面的v[n + 1] 的最大值就是 v[j]
j 的值是 v.size()
因为 v 下标从 0 开始 最大值猜到 j - 1 而已
会导致越界错误

程序代码:
        if ((v[n] != v[n + 1])&&(n1>0))      //有过重复,但这次不是,就把这个重复记录对应的v中的单词位置,重复次数放入v1中
    {
            v1.push_back(n1);//n1遍
            v1.push_back(n-1);//v中的单词位置,用于以后输出
        }

这个对齐写得很不好
对齐缩进非常重要 不要敷衍
然后 你整个 if 是做什么的 为什么要存储重复次数?
直接存储一个重复最多次 和 对应字符串不就完事了?
程序代码:
        if ((v[n] != v[n + 1])&&(n1>0))      //有过重复,但这次不是,就把这个重复记录对应的v中的单词位置,重复次数放入v1中
    {
            v1.push_back(n1);//n1遍
            v1.push_back(n-1);//v中的单词位置,用于以后输出
        }

因为你前面 脑子不清醒的没找出最多次 现在要写一个毫无意义的循环
#9
lin51616782016-04-13 00:37
程序代码:
#include<iostream>
#include<vector>
#include<string>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
int main()
{
    vector<string> vecStr; // 存储输入的数据
   
    string str;
    while(cin >> str)
        vecStr.push_back(str);
        
    int nCur = 1; // 记录当前扫描的字符串已经出现的次数
    int nMax = 0; // 记录出现字符串出现次数最多是多少
    string strRes; // 记录出现次数最多的字符串
    for(int i = 0; i < vecStr.size() - 1; ++i) //注意 循环到 size - 1 就可以退出
    {
        if(vecStr[i] == vecStr[i+1]) // 每次比较当前字符串和后一个字符串是否相等  这就是为什么只需要循环到 size - 1
        {
            ++nCur;
        }
        else if(nCur > nMax) // 如果当前字符串和后一个字符串不相等 就检查当前字符串出现次数是不是最多次
        {
            nMax = nCur;
            nCur = 1; // 注意nCur要重置 因为接下来的字符串连续出现的次数只有 1 次
            strRes = vecStr[i]; // 记录出现次数最多的字符串
        }
    }
    cout << "出现次数最多的单词是" << strRes << endl;
    cout << "出现次数是" << nMax << endl;
    return 0;
}


[此贴子已经被作者于2016-4-13 00:43编辑过]

#10
alice_usnet2016-04-13 09:10
回复 4楼 lin5161678
多谢提醒
#11
yangfrancis2016-04-13 18:40
回复 楼主 哒哒哒啦啦啦
//已测试
#include<iostream>
#include<vector>
#include<string>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
int main()
{
    vector<string> v;      //这个是存放单词的
    vector<int> v1;        //这个是存放每个重复过的单词的容器,奇数位是单词在容器v中的位置,以便于比较后输出,偶数位是对应奇数位重复出现的最大数字
    vector<int> v2;        //这个是比较v1的遍数哪个大,将大的存在里面
    string i;
    int n1 = 1;
    while (cin >> i)
        v.push_back(i);
    cout<<"Input Finished!\n";
    string*active=v.begin();
    cout<<"The inputed words:";
    while(active!=v.end())
    {
        cout<<*active<<" * ";active++;
    }
    cout<<endl;
    string KeyWord="xxxxxxxxxxxxxxxxxxxxxx";//连续最高频的词
    string LastWord="mmmmmmmmmmmmmmmmmmmmmm";//上一个词
    short num=0;//连续最大的次数
    short n=0;//当前单词连续次数
    active=v.begin();
    while(active!=v.end())
    {
        if(*active!=LastWord)
        {
            if(n>num)//更新连续最高频单词
            {
                num=n;KeyWord=LastWord;//刷新单词
            }
            n=1;//当前单词从1开始计数
            LastWord=*active;//更新单词
        }
        else
            n++;
        active++;
    }
    cout<<"The word selected: "<<KeyWord<<"\t"<<num;
    return 0;
}
#12
c9742884322016-04-13 18:41
这WHILE(COUT>>I) 是怎么结束的
#13
哒哒哒啦啦啦2016-04-13 19:55
经过各位大神点播,改正了原程序,测试没问题~
#include<iostream>
#include<vector>
#include<string>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
void main()
{
    vector<string> v;      //这个是存放单词的
    vector<int> v1 = { 0,0 };        //这个是存放每个重复过的单词的容器,奇数位是单词在容器v中的位置,以便于比较后输出,偶数位是对应奇数位重复出现的最大数字
    vector<int> v2;        //这个是比较v1的遍数哪个大,将大的存在里面
    string i;
    int n1 = 1;
    while (cin >> i)
        v.push_back(i);

    int j = v.size();
    for (int n = 0; n + 1 < j; ++n)
    {
        if (v[n] == v[n + 1])
        {
            ++n1;
        }
        if (((v[n] != v[n + 1]) && (n1 > 1)) || (n+2==j))   //n+2==j,是为了判断当最后一组是重复次数最多的数时,要放入v1
        {
            if (v1[0] < n1)
            {
                v1[0] = n1;              //把目前重复次数最多的一组放里面
                v1[1] = n;
            }
            n1 = 1;
        }
    }
    cout << "出现次数最多的单词是" << v[v1[1]] << endl;
        cout << "出现次数是" << v1[0] << endl;
}
   
#14
哒哒哒啦啦啦2016-04-13 19:55
回复 12楼 c974288432
没有输入就结束了
#15
yangfrancis2016-04-13 19:59
回复 12楼 c974288432
回车之后Ctrl+z,再回车,结束
#16
哒哒哒啦啦啦2016-04-13 20:02
回复 11楼 yangfrancis
谢谢,改完跟你的思路有点像
#17
哒哒哒啦啦啦2016-04-13 20:04
回复 9楼 lin5161678
多谢,很详细,分数给你的最多啦~
#18
c9742884322016-04-15 16:40
回复 14楼 哒哒哒啦啦啦
试了几次没成  在看看去
#19
c9742884322016-04-15 16:53
回复 15楼 yangfrancis
擦  我的要CTRL Z 回车  CTRL Z 回车  谢了哈
1