程序设计能力实训之排序算法(以及去重)
冒泡排序和选择排序明显超时,个人又觉得快速排序超出了我这个数学和逻辑思维不好的人的接受范畴,因此准备采用简单方法完成.
于是找到在algorithm库中的sort函数进行排序大大的节省了时间.
先排序再去重:有相当简化的算法:
if(s == 'A')sort(a,a + i + 1,greater<int>());
if(s == 'D')sort(a,a + i + 1,less<int>());
for(; i >= 0; i--)
{
if(a[i+1] != a[i])
cout << a[i] << ' ';
}
cout << endl;
顺便一提:include <bits/stdc++.h>库包含了所有的c++头文件
向量容器 vector设置动态数组的用法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, const char * argv[]) {
vector<int> vecInt = {10, 20, 30};
vecInt.push_back(40);
/*for(int i = vecInt.size()-1; i >= 0; i--)
{
cout << vecInt[i] << endl;
}*/
//遍历
vector<int>::iterator it;
for(it = vecInt.begin(); it < vecInt.end(); ++it)
{
cout << *it << endl;
}
//排序的另外一种使用方法(先顺后逆序)
sort(vecInt.begin(), vecInt.end());
reverse(vecInt.begin(), vecInt.end());
return 0;
}
需要注意的点:
vec中没有重载运算符 << 因此不能用cin来输入数据
使用vec.push_back(temp)
字符串相关处理
1.想要读入带空格的字符串:getline(cin, stringName)
换言之:因为getline会读入空格和前导,因此若前面使用了cin而没有读入之后的换行的话:需要用cin.get()把前面的换行给读入.
2.字符串倒置:reverse函数 前面已经提及 需要调用string库
3.string只能==" "内的内容
4.换行停止读入的办法:
while(cin >> a)
{
if (cin.get() == '\n')
break;
}
5.统计字符串中字符个数:
调用string函数库
int len = ch.length();
int len = ch.size();
6.清空字符串的办法:
str.erase(str.begin(),str.end());
1029 排序后统计出现非重复字符串的个数
麻烦的地方有两点:
1.统计字符串中非重复字符的个数
目前采用的方法是:定义一个函数,用数组记录下每次第一个出现的字符,循环遍历,count++
int f(char *p)
{
int count = 0,i;
char A[20],a;
while(a = *p++)
{
for(i = 0; i < count && a != A[i]; i++);
if(i == count) A[count++] = a;
}
return count;
}
2.如何让字符串的顺序能够按照不同字符从多到少的顺序输出:
本先采用了定义字符串数组+数组的方式,通过选择/快速/插入排序的时候一起交换掉
显然使用结构体的方法更加简单,也更难?
1)声明一个结构体指针,需要初始化,再运用qsort函数:
(我觉得太麻烦了,没有搞懂)
2)结构体+sort函数(bool类型cmp完成)
大大优化了排序和定义的过程
3.需要注意的地方:
1.string类型char的差别还是有的(或者说蛮大的)
直接采用string类型的话可以用数组完成✅就不要指针了
这里可以转换为指针来完成
关于string转char:
#include <string>
const char* p = str.data();
//或者 char *p =(char *)str.c_str();
传入函数的类型必须与其定义内的类型保持一致
2.string的compare函数使用
#include<string>
string A,B;
A.compare(B) = 1;
//(前者的ascii值减去后者的,>0返回1,<0返回-1,=0返回0)
A.compare(0,3,B,1,3) = -1;
//索引:A的数组下标为0,B的数组下标为1
//长度:A取长度为3,B取长度为3
#1036 search web page
要求我们在排序后输出最大值的网页,有多组数据则按照输入顺序输出.
此时我们使用结构体储存输入顺序,再编写cmp就好啦
KL函数中涉及的一点感想
1.关于强制四舍五入:
kl[i].kl = (double)(int)(kl[i].kl * 10000 + 0.5) / 10000 ;
或者
double kld=0.0; //初始化KL值
kld = (int)(kld*10000.0+0.5)/10000.0; //4位四舍五入
位数可以根据需求改变.
2.1e-7在c或者c++里面的意思是:10的-7次方
其他同理可以推出
1 位数排序
题目是要求按照64位补码来排序,此时定义一定要用 long long int
同数制专题中:
int x = 1;
for(int j = 0; j < 64; j++)
{
if(I[i].num & x) I[i].ones++;
x <<= 1;
}
行数据排列
关于character missing的一点感想:
如果有这种问题的话,一般是内存不足(比如数组大小只有50但是有51个数据?之类的)本题是选择扩大了数组的大小,就过了(还有一次的话好像是输出的时候删除了行末的空格?就过了。我这种渣渣的不能再渣渣的人也不是很懂的起eoj测试平台的脑回路)
字符频率
1.在输入输出的时候遇到问题
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
char cha[20];
int i = 0;
while(cin >> cha[i])
{
if(cin.get() == '\n') break;
cout << cha[i] <<' ';
i++;
}
return 0;
}
这时候如果输入:thisisaexample
输出会变成:t i i a x m l
经过查阅资料发现了自己的错误:while的判断条件是cin>>会读入一次,并储存在数组内,循环内cin.get()会再读入一次,作为判断,但是没有储存,导致偶数次读入的字符丢失
而在读入整数时该方法可以使用的原因时:10 20 30 40
读入这些数据的后面都有一个空格,刚好cin.get()可以读取而不储存,并不影响cin的读入
改进办法:
cin.get();
while((cha[b].cha = cin.get()) != '\n')
{
}
前面一定要加上cin.get()把换行符给搞掉!!!!!不然会读入\n从而导致输出结果出现非常神奇的现象
文献排序
关于string类型:string是可以直接用“=”赋值的
string类型的大小比较:按字典顺序一个一个比较,大小写敏感
另外就是string1 = string2.substr(n,m);//位置n开始,长度为m