3-7 DNA序列 UVa1368
input:
rows, cols
TATGATAC
TAAGCTAC
AAAGATCC
TGAGATAC
TAAGATGT
output:
TAAGATAC
程序如下:
#include <iostream>
#include <vector>
using namespace std;
typedef vector<char> char_1vec;
typedef vector< char_1vec > char_2vec;
void userMatrixIn(int, char_2vec&);
void all_DNA_seq(const int, char_2vec&);
int computeDist(const char_1vec&, const char_1vec&);
int computeSumDist(const char_2vec&, const char_1vec&);
int getMinVec(const char_2vec&);
void print_vec(const char_1vec&);
void print_mat(const char_2vec&);
int main()
{
int m, n; // m个长度为n的序列
cin >> m >> n;
// 得到用户输入的矩阵
char_2vec ch_matrix;
userMatrixIn(n, ch_matrix);
//cout << "user input matrix is: " << endl;
//print_mat(ch_matrix);
// 得到所有可能得DNA序列
const int len(n);
char_2vec dna_mat;
all_DNA_seq(len, dna_mat);
//cout << "all the DNA sequence is: " << endl;
//print_mat(dna_mat);
//int min_dist = numeric_limits<int>::infinity();
int min_dist = 1001;
//cout << "initial min dist is: " << min_dist << endl;
char_2vec::const_iterator iter = dna_mat.begin();
int thedist;
char_2vec min_dist_vec;
for (; iter!=dna_mat.end(); ++iter) {
thedist = computeSumDist(ch_matrix, *iter);
if (thedist<min_dist) {
min_dist = thedist;
min_dist_vec.clear();
min_dist_vec.push_back(*iter);
}
else if (thedist==min_dist)
min_dist_vec.push_back(*iter);
}
//cout << "min_dist is: " << min_dist << endl;
//print_mat(min_dist_vec);
int min_num = getMinVec(min_dist_vec);
//cout << "min vec is in line: " << min_num << endl;
print_vec(min_dist_vec[min_num]);
return 0;
}
void userMatrixIn(int cols, char_2vec& matrix_in) {
bool isstop = false;
char ch;
char_1vec vec_tmp;
while (!isstop) {
vec_tmp.clear();
for (int i=0; i<cols; ++i) {
cin >> ch;
if (ch=='0') {
isstop = true;
break;
}
vec_tmp.push_back(ch);
}
matrix_in.push_back(vec_tmp);
}
}
// input: length of DNA
// output: all the DNA sequence
// 千万不要返回局部变量的引用!
void all_DNA_seq(const int len, char_2vec& dna_2vec) {
char dna[4] = {'A', 'C', 'G', 'T'};
vector<int> a(len+1, 0);
int n;
vector<char> tmp;
for (a[0]=0; a[0]<4;){
tmp.clear();
for (int i=len-1; i>=0; i--)
tmp.push_back(dna[a[i]]);
dna_2vec.push_back(tmp);
n = 0;
while (a[len] == 0)
if (a[n] == 3)
a[n++] = 0;
else {
a[n]++;
break;
}
if (a[len] == 1)
break;
}
}
int computeDist(const char_1vec& ch1, const char_1vec& ch2) {
int dist(0);
vector<char>::size_type l = ch1.size();
for (vector<char>::size_type i=0; i<l; ++i) {
if (ch1[i]!=ch2[i])
++dist;
}
return dist;
}
int computeSumDist(const char_2vec& in_vec, const char_1vec& ch2) {
int sum(0);
char_2vec::const_iterator it = in_vec.begin();
for (; it!=in_vec.end(); ++it)
sum += computeDist(*it, ch2);
return sum;
}
int getMinVec(const char_2vec& mat_in) {
int num;
char_1vec min_vec(mat_in[0]);
char_2vec::const_iterator it = mat_in.begin();
for (; it!=mat_in.end(); ++it) {
if (*it <= min_vec) {
min_vec = *it;
num = it - mat_in.begin();
}
}
return num;
}
void print_mat(const char_2vec& mat_in) {
char_2vec::const_iterator it = mat_in.begin();
for (; it!=mat_in.end(); ++it)
print_vec(*it);
}
void print_vec(const char_1vec& vec_in) {
char_1vec::const_iterator it = vec_in.begin();
for (; it!=vec_in.end(); ++it)
cout << *it << " ";
cout << endl;
}
我的感想:
1 编写程序,首先要确定所有的功能模块,每个模块要做一件什么事情,确定需要的函数;
2 根据功能确定需要的数据结构,寻找相应的C++工具,最后最好能用typedef加一个别名;
3 vector的初始化:1 vector a(b),用b的副本初始化a; 2 vector a(num, ele), 用num个元素ele初始化vector,
如果是二维vector,则每个ele都是一个vector;3 vector a,如此定义的是一个空的vector,比如vector<vector T> a,
a.resize(num)得到的就是有num个空容器的二维容器,如果在调用push_back,会在num后面添加一维容器;
4 编写循环程序,就是:由特殊到一般的归纳法思维,如本例中产生所有DNA序列的程序;
5 绝对不能返回对局部对象的引用!
6 输出二维容器的所有元素,用两层iterator!
7 vec1 = vec2, 将vec2的值赋给vec1,实际过程:在赋值前先将vec1清空!vec1>vec2,则是将vec1和vec2中的元素依次比较,和string中的比较规则一致;
实际上我这里得到输出的第一个容器已经是最小的vec了,故无需调用该函数。
8 注意本程序中二维数组的输入!每次vec_tmp都有一个清空操作!
3-8 UVa202 循环小数
输入被除数和除数,求出其小数点表示,无限循环用(循环节)表示
input:
5 43
output:
0.(116279069767441860465)
程序如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef vector<int> int_1vec;
typedef vector< vector<int> > int_2vec;
int computeNum(int);
void getNtimes(int&, int);
int main() {
int a(20), b(7), m, n(b), zheng(0); // a:被除数, b:除数, m:商, n:余数
cout << "please input a and b: " << endl;
while (cin >> a) {
if (a==0)
break;
cin >> b;
if (a>b) {
zheng = a/b;
a = a%b;
}
else
zheng = 0;
int b_num = computeNum(b);
int a_num, num_diff, numZero;
bool isloopend = false;
int_1vec yushu_vec(1, a), tmp_vec;
int_2vec shang_vec;
while (!isloopend) {
tmp_vec.clear();
// 求得a和b
// a后面补零使其与b的位数相同,如果a>=b,则完成。否则再补一个零
// 1 求得a和b的位数
// 2 补n个零
a_num = computeNum(a);
num_diff = b_num - a_num;
numZero = num_diff - 1; // 要补零的个数比位数之差小1
getNtimes(a, num_diff);
if (a<b) {
a = a*10;
++numZero;
}
tmp_vec.insert(tmp_vec.begin(), numZero, 0);
// 由m、n求商和余数,如果余数在与之前的余数相同,则结束循环,否则循环继续
m = a/b;
tmp_vec.push_back(m);
shang_vec.push_back(tmp_vec);
n = a%b;
int_1vec::iterator pos= find(yushu_vec.begin(), yushu_vec.end(), n);
if (pos==yushu_vec.end()) {
yushu_vec.push_back(n);
a = n;
}
else {
isloopend = true;
// 输出没有循环的部分
cout << zheng << "." << flush;
int dist = pos - yushu_vec.begin();
int_2vec::const_iterator it=shang_vec.begin();
for (; it!=shang_vec.begin()+dist; ++it) {
int_1vec::const_iterator iter = (*it).begin();
for (; iter!=(*it).end(); ++iter)
cout << *iter << "";
}
// 输出循环的部分,用括号括起来
cout << "(" << flush;
//int dist = pos - yushu_vec.begin();
it=shang_vec.begin()+dist;
for (; it!=shang_vec.end(); ++it) {
int_1vec::const_iterator iter = (*it).begin();
for (; iter!=(*it).end(); ++iter)
cout << *iter << "";
}
cout << ")" << endl;
}
}
}
return 0;
}
int computeNum(int i) {
int m = i, n, num(0);
while (m!=0) {
++num;
n = m%10;
m = m/10;
}
return num;
}
void getNtimes(int& i, int n) {
while (n) {
i = i*10;
--n;
}
}
按照3-7的思维方式,此题在较短时间就做出来了。