北京理工2019上机

1、碎片字符串

形如aabbaaacaa的字符串,可分为五个相同连续字母组成的碎片:‘aa’,‘bb’,‘aaa’,‘c’,‘aa’,其中每个碎片只出现一次,即该字符串包含’aa’,‘bb’,‘aaa’,'c’四个碎片,且输出时按字典序排序。

 输入:aabbaaacaa
 输出:
        aa
        aaa
        bb
        c

1.模拟过程,每次把得到子串的长度放到一个二维数组里,各行按a~z索引,每一列记录子串长
思想:先记录信息到一张表,再从表中取出数据

#include <iostream>
#include <cmath>
#include<string>
using namespace std;

#define check(c) cout<<c<<endl


int data_[28][20];

int getpos(int hang,int n){//第i行里有没有n
	bool flag = false;
	int i = 0;
	for (; i < 20&&data_[hang][i]!=-1; i++) {
		if (data_[hang][i] == n) {
			flag = true;
			break;
		}
	}
	if (!flag) {
		return i;
	}
	return -1;
}

void show(int i, int n) {
	string str="";
	char c = i-1 + 'a';
	while (n--) {
		str += c;
	}
	cout << str << endl;
}
int main() {
	//data
	for (size_t i = 0; i < 28; i++)
	{
		for (size_t j = 0; j < 20; j++) {
			data_[i][j] = -1;
		}
	}

	//input
	string str = "";
	cin >> str;


	//count
	int i = 0;
	while (i < str.size()) {
		char ch = str.at(i);
		int num = 0;
		//字符的下标一定要先检查后访问
		while (i<str.size()&&str.at(i) == ch) {
			i++;
			num++;
		}
		if (num) {
			int j = ch - 'a'+1;
			int c = getpos(j,num);
			if (c != -1)
				data_[j][c] = num;
		}
	}
	//output
	for (int i = 1; i < 27; i++) {
		if (data_[i][0] != -1) {
			//check(i);
			for (int j = 0; j < 20&&data_[i][j] != -1; j++){
				//输出访问之前数据要合理
				show(i, data_[i][j]);
			}
			//check(i);
		}
	}

	//system("pause");
	return 0;
}

1.2,借助数组set的元素唯一性,将所有的子串加入到一个set中,最后输出结果

#include<iostream>
#include<set>
#include<string>
using namespace std;

int main() {
	//data
	set<string> set_str;
	string str = "";
	//input
	cin >> str;
	//exe
	for (int i = 0; i < str.length(); i++) {
		string temp = "";
		temp += str[i];
		while (str[i] == str[i + 1]) {
			temp += str[i++];
		}
		set_str.insert(temp);//这一步是核心,将重复子串删除
	}

	//output
	for(string s: set_str) {
		cout << s << endl;
	}
	return 0;
} 

2、哈夫曼树
输入n,以及n个数(用,隔开),构造哈夫曼树,输出其最小带权路径长度
思想:不断合并最小的两个数,并且更新他的权重,使得新值的和合并前的值等价

输入: 
4
2,4,5,7
输出:35

输入:
4
1,1,1,1
输出:8
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;

#define check(x) cout<<x<<endl


typedef struct weight_ {
	int num;
	double weight;
}Wt;

Wt arr[30];


void get_arr(string str) {
	int t = 0;
	for (int i = 0; i < str.length(); ++i) {
		if (str.at(i) != ',') {
			arr[t].num = str.at(i) - '0';
			arr[t].weight = 0.0;
			++t;
		}
	}
}

void copy(Wt &a, Wt &b) {
	a.num = b.num;
	a.weight = b.weight;
}
void swap_(Wt &a, Wt &b) {
	Wt temp;
	copy(temp, a);
	copy(a, b);
	copy(b, temp);
}

void get_t_min(int first,int n) {
	for (int i = first; i < n; i++) {
		bool update = false;
		for (int j = first; j < n-1; j++) {
			if (arr[j].num > arr[j + 1].num) {//注意j+1的合法性
				//建议手写优先
				swap_(arr[j], arr[j+1]);
				update = true;
			}
		}
		if (!update) return;
	}
}

int main() {
	//data
	int n = 0;
	string str = "";

	//input
	cin >> n;
	cin >> str;
	get_arr(str);

	//exe
	int first = 0;

	while (first < n-1) {
		get_t_min(first,n);//	取得arr中first到n的最小的两个数,冒泡排序
		
		/*check是否正确排序
		for (int i = first; i < n; i++) {
			cout << arr[i].num << " " << arr[i].weight << "**";
		}
		check("");
		*/

		int sum = arr[first].num+arr[first+1].num ;
		double weight = (arr[first].num *(arr[first].weight+1)+ 
			arr[first + 1].num*(arr[first+1].weight + 1))/sum;

		first++;
		arr[first].num = sum;
		arr[first].weight = weight;
	}
	//output
	cout << arr[first].num*arr[first].weight<< endl;
	system("pause");
	return 0;
}

2.2哈夫曼树的带权路径和=非叶子结点的和

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
using namespace std;

#define check(x) cout<<x<<endl

priority_queue<int, vector<int>, greater<int> > q;

void get_pq(string &str,int n) {
	for (int i = 0; n!=0; ++i) {
		if (str.at(i) != ',') {
			//check(str.at(i) - '0');
			q.push(str.at(i) - '0');
			n--;
		}
	}
}


int main() {
	//data
	int n = 0;
	string str = "";

	//input
	cin >> n;
	cin >> str;
	get_pq(str,n);

	//exe
	int sum = 0,min1=0,min2=0,i=0;
	while (i<n-1) {
		 min1 = q.top(); q.pop();
		 min2 = q.top(); q.pop();
		// cout << min1 << "  " << min2 << endl;
		sum += min1 + min2;
		q.push(min1 + min2);
		i++;
	}

	//output
	cout << sum<< endl;

	system("pause");
	return 0;
}


发布了27 篇原创文章 · 获赞 1 · 访问量 1428

猜你喜欢

转载自blog.csdn.net/qq_34890856/article/details/103835162