例题3-6 最长回文子串
这道题有个好思路即是,找回文的时候,不是从头到尾,而是从中间向两边扩散。
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 5000 + 10
char buf[MAXN];
char str[MAXN];
int pos[MAXN];
void main(){
while(fgets(buf, sizeof(str), stdin)){
int len = 0 , p = 0, max = 0, left = 0, right = 0;
len = strlen(buf);
for(int i = 0; i < len; i++){
if(isalpha(buf[i])){
str[p] = toupper(buf[i]);
pos[p] = i;
p++;
}
}
for(int i = 0; i < p; i++){
for(int j = 0; (i-j) >= 0 && (i+j) < p; j++){
if(str[i-j] != str[i+j])
break;
if(j*2 + 1 > max){
max = j*2 + 1;
left = pos[i-j];
right = pos[i+j];
}
}
for(int j =0; (i-j) >= 0 && (i+j+1) < p; j++){
if(str[i-j] != str[i+j+1])
break;
if(j*2+2 > max){
max = j*2 + 2;
left = pos[i-j];
right = pos[i+j+1];
}
}
}
for(int i = left; i <= right; i++){
printf("%c", buf[i]);
}
printf("\n");
}
}
习题3-1 分数统计
这道题写得有点复杂,重要是想顺带复习学习一下容器的用法
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
node(){}
node(double s, int c){scroe = s; counter = c;}
double scroe;
int counter;
};
bool sortNode(const node *v1, const node *v2){
if(v1->counter == v2->counter){
return v1->scroe > v2->scroe;
}else{
return v1->counter > v2->counter;
}
}
void main(){
map<double, node> nodeMap;
vector<node*> nodeVec;
double score;
while(cin >> score){
map<double, node>::iterator it = nodeMap.find(score);
if(it == nodeMap.end()){
nodeMap.insert(make_pair(score, node(score, 1)));
}else{
it->second.counter++;
}
}
for(map<double, node>::iterator it = nodeMap.begin(); it != nodeMap.end(); it++){
nodeVec.push_back(&(it->second));
}
sort(nodeVec.begin(), nodeVec.end(), sortNode);
int maxCounter = nodeVec[0]->counter;
for(int i = 0; i < nodeVec.size(); i++){
if(nodeVec[i]->counter < maxCounter)
break;
cout << nodeVec[i]->counter << " " << nodeVec[i]->scroe << endl;
}
}
还有几点注意的:
1:vector里不能放引用类型(?)
2:struct/类,当自己写了一个构造函数后,则默认构造函数自动失效
3:map 的 insert 用make_pair 做键值对,在使用vector.resize(n),后vector的size就会变成n,即默认会构建n个默认的对象。
习题 3-3 乘积的末3位
这道题和第二章的阶乘有些类似,即若加,减,乘的整数表示式除以正整数n的余数,可以在每步计算之后对n取余,结果不变。
#include<iostream>
#include<string>
using namespace std;
#define END_NUM 1000
void main(){
long num = 0;
int x = 1;
string str;
while(cin >> str){
//先判断str是否为数字
bool isNum = true;
for(int i=0; i<str.size(); i++){
if(!isdigit(str[i])){
isNum = false;
break;
}
}
if(!isNum) continue;
//将str转换为数字
sscanf(str.c_str(), "%ld", &num);
//取后三位
num%=END_NUM;
//开始计算后三位乘积
x = x*num%END_NUM;
}
cout << x;
}
这道题还有几个点:
1:isdigit() 函数,判断是否char型数据是否为数字(即‘0’~‘9’)
2:sscanf,sprintf,stringstream的用法,这里不再赘述,这几个函数在字符串或string的操作上有很多的用处
习题 3-5,3-7 进制转换
两题合一,进制转换问题
#include<iostream>
#include<vector>
using namespace std;
void main(){
int b = 0;
int n = 0;
vector<int> vec;
cin >> b >> n;
while(n > 0){
vec.push_back(n % b);
n /= b;
}
for(int i = vec.size()-1; i >= 0; i--){
cout << vec[i];
}
cout << endl;
cin >> b >> n;
int c = 1,i = 0;
while(n > 0){
i += c*(n%10);
n /= 10;
c*=b;
}
cout << i << endl;
}