有一个关于Vector的问题

the_passenger 2016-09-19 12:36:38
我现在有两个vector 容器
vector<char> oneword
和 vector<int> fre
前者储存着一个又一个的汉字,每个汉字占一前一后两个char;
后者储存着与之对应的各个汉字出现频率。
所以,fre[i]对应的就是oneword[i*2]和oneword[i*2+1]这两个字符组合起来的汉字的出现频率

现在想根据后面的频率,对汉字进行排序,出现频率越高的放前面。
我考虑的是,使用现有的快速排序方法,对后面的vector<int>进行快排,然后同时修改函数体,使得排序过程中,int型数据交换的同时,前面对应的两个char型数据也进行交换,这样可以实现,对应的位置的改变。最后我顺序输出两者,它们还是一一对应的排好序的。
然而这么做了之后,本身正确的统计结果,排序后程序崩溃 =。=
本身,不排序的话,输出的统计结果是正确的。
请教大家,错误出在哪里?有没有更好更方便的排序方法?

#include<fstream>
#include<locale>
#include<iostream>
#include<string>
#include<vector>
using namespace std;


vector<char> oneword;//存放已统计的每个汉字的vector,全局变量
vector<int> fre; //代表每一个汉字的输入频率的vector,全局变量

void quickSort(int s[], int l, int r)
{
if (l< r)
{
int i = l, j = r, x = s[l];
char p[2];
p[0] = oneword[l*2];
p[1] = oneword[l*2+1];
while (i < j)
{
while(i < j && s[j]>= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
oneword[(i-1)*2] = oneword[j*2];
oneword[(i-1)*2+1] = oneword[j*2+1];
while(i < j && s[i]< x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
oneword[(j+1)*2] = oneword[i*2];
oneword[(j+1)*2+1] = oneword[i*2+1];
}
s[i] = x;
oneword[i*2] = p[0];
oneword[i*2+1] = p[1];
quickSort(s, l, i - 1); // 递归调用
quickSort(s, i + 1, r);
}
}
int main()
{
fstream file;
string str; //文件内容存到的目标字符串 str
unsigned char n[1];
string gstr; //临时变量,用来读入文件
int xx; //xx记录它在oneword数组中的位置
int i,j; //用来计数的变量
file.open("Ci.txt",ios::in|ios::out);
do{
str = str + gstr;
file>>gstr;
}
while(!file.eof());
file.close(); //关闭文件
int length = str.length(); //str的总长度
cout<<str<<endl;
cout<<length;





for(i=0;i<length;i=i+2)
{
n[0]=str[i];
if(n[0] >= 0xB0 && n[0] <= 0xF7) //是汉字字符
{
bool exist;
exist = false;
for(j=0;j<oneword.size();j=j+2)
{
if(oneword[j] == str[i] && oneword[j+1] == str[i+1])
{xx = j;
exist = true;
break;
}
}

if(exist) //已经存在于oneword中
{
fre[xx/2]++; //相应 计数 +1
}
else //还未存在于oneword之中
{
oneword.push_back(str[i]);
oneword.push_back(str[i+1]);
fre.push_back(1);
}
}
}

int *fre1 = new int[fre.size()]; //建立一个名为fre1的int型数组,数据与fre完全相同。为了使用现有函数对fre进行快速排序。
for(i=0;i<fre.size();i++)
{
fre1[i] = fre[i];
}


quickSort(fre1, 0, fre.size()-1); //快速排序函数调用


fstream writefile;
writefile.open("result.txt",ios::out);

for(i=0;i<oneword.size();i=i+2) //将oneword和fre中的数据一一输出到result.txt之中
{
char temp1[3];
temp1[0] = oneword[i];
temp1[1] = oneword[i+1];
temp1[2] = '\0';
writefile<<temp1<<" ";
writefile<<fre1[i/2];
writefile<<endl;
}
writefile.close();
writefile.clear();




return 0;
}
...全文
300 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
hijack00 2016-09-24
  • 打赏
  • 举报
回复
感觉你的数据结构选的不是很恰当。按照你的描述,每个汉字都是16bit的(2字节),那你直接使用vector<int16_t> oneword来表示汉字,而不要使用oneword[i*2]和oneword[i*2+1]这种结构。之后再统计词频并排序
zsQQ513 2016-09-24
  • 打赏
  • 举报
回复
看看能不能有几分
YUSHUIHE 2016-09-23
  • 打赏
  • 举报
回复
因汉字是宽字节类型,所以在程序中需用宽字节类型,也就是用字母W开头的类型。
勤奋的小游侠 2016-09-19
  • 打赏
  • 举报
回复
我建议你定义一个类 class ChineseChar { public: char data[2]; //重载 大于,小于,等于操作 } vector<ChineseChar> list; 这样才是c++的正确用法。 你既用vector,又要将vector转换成数组,你不觉得烦吗? 好好的c++被你当成了c 来用了。
赵4老师 2016-09-19
  • 打赏
  • 举报
回复
处理汉字用wchar_t,wstring,wcout,wfstream
dustpg 2016-09-19
  • 打赏
  • 举报
回复
确定用两个字节的话(汉字的话GB 18030可能4字节, UTF8 3~4字节, UTF16 2~4字节),为何不用
#include <vector>
#include <algorithm>

struct DATA { int i; char c[2]; };

int main() {
    std::vector<DATA> a = {
        xxxxxxxxxxxxxx
    };
    std::sort(a.begin(), a.end(), [](const DATA& a, const DATA& b) {
        return a.i > b.i;
    });
}
ri_aje 2016-09-19
  • 打赏
  • 举报
回复
创建一个类管理汉字及其频率,然后直接放在 set 里就行,或者 vector 加排序也行。
NoEdUl 2016-09-19
  • 打赏
  • 举报
回复
你这么做,访问次数是不是有点。。。多。
paschen 版主 2016-09-19
  • 打赏
  • 举报
回复
用wchar_t来存汉字吧

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧