Decision Tree - Google Code Jam 2009 Round 1B A题

是一道水题,其最重要的部分在于字符串处理建立树。


代码如下: 

#include"stdafx.h"
#include<iostream>
#include<string>
#include<stdio.h>
#include <iomanip>
#include<set>

using namespace std;
#define LEFTBRACKET '('
#define RIGHTBRACKET ')'
const int MAX = 1000;


class Node{
public:
	Node *left, *right;
	string feature;
	bool leaf;
	double weight;
	
	Node() {
		left = right = 0;
		leaf = true;
		weight = 0.0;
	}
	void set(double, bool, string);
	void set(double);
};

class Stack{
private:
	Node *a[MAX];
	int top;
public:
	Stack():top(-1){}
	void Push(Node *);
	void Pop();
	Node *Top();
	bool IsEmpty();
};


typedef Node* Tree;

Tree ConstructDecisionTree(int lines);
double ComputeValue(Tree tr, set<string> s);
void DestroyTree(Tree tr);

int main() {
	freopen("../A-large-practice.in", "r", stdin);
	//freopen("../A-small-practice.in", "r", stdin);
	//freopen("Input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	int casenum;
	int tline, anims; 
	string s;
	cin>>casenum;
	for(int p = 0; p < casenum; p++) {
		cin>>tline;
		Tree tr = ConstructDecisionTree(tline); //建树的过程应该是调试好了。
		cout<<"Case #"<<(p + 1)<<":"<<endl;
		cin>>anims;
		cin.get();
		for(int i = 0; i < anims; i++) {	
			int temp;
			set<string>sets;
			cin>>s>>temp; //Animal name and feature num
			//getline(cin, s);
			for(int i = 0; i < temp; i++) {
				cin>>s;
				sets.insert(s);
			}

			double ret = ComputeValue(tr, sets);
			//cout<<setprecision(7)<<ret<<endl;
			printf("%.7f\n", ret);
		}
		DestroyTree(tr);
	}
}

Tree ConstructDecisionTree(int lines) {
	Node *curNode, *root;
	double weight;
	char temp;
	string feature;
	Stack s;
	for(int i = 0; i < lines; i++) {
		do {
			cin>>temp;
		}while(temp != LEFTBRACKET && temp != RIGHTBRACKET); //May cause infinite loop
		if(temp == RIGHTBRACKET) {s.Pop(); continue;}
		//We encouter a leftbracket

		cin>>weight; //we get the weight
		cin>>feature; //Try to get the feature
		cin.get();
		curNode = new Node();
		if(s.IsEmpty()){ 
			root = curNode;
		}else {
			if(s.Top()->left == 0) s.Top()->left = curNode;
			else s.Top()->right = curNode;
		}

		s.Push(curNode);

		//if feature contains too many ")"
		if(feature[0] != RIGHTBRACKET) {
			curNode->set(weight, false, feature);
		}else {
			//there are feature.size() ‘)’
			for(int k = 0; k < feature.size(); k++) s.Pop();
			curNode->set(weight);
		}	
	}
	return root;
}

double ComputeValue(Tree tr, set<string> s) {
	//s中查找字符串
	double pro = 1.0f;
	Node *p = tr;
	//set<string>::iterator it;

	while(true) {
		pro *= p->weight;
		if(p->leaf) break;
		else {
			/*
			if(s.find(p->feature) != string::npos) p = p->left;
			else p = p->right;
			假设为s为 sdd, ddd, sdsdfd,
			那么当p->feature为dd时候,会显示为正确
			要考虑越界的情形,还有其他的问题。 果然是这个问题
			*/
			if(s.find(p->feature) != s.end() ) p = p->left;
			else p = p->right;
			
			
		} 
	}
	
	
	return pro;

}

void DestroyTree(Tree tr) {
	if(tr == 0) return;
	DestroyTree(tr->right);
	DestroyTree(tr->left);
	delete tr;
}


//字符串处理方面太弱了,一定得补上
void Node::set(double w, bool l, string fe){
	weight = w;
	leaf = l;
	feature = fe;
}

void Node::set(double w) {
	weight = w;
}
void Stack::Push(Node * v) {
	a[++top] = v;
}

void Stack::Pop() {
	--top;
}
Node* Stack::Top() {
	return a[top];
}

bool Stack::IsEmpty() {
	return top == -1;
}


总结: 

感觉自己还是不大懂得用C++,事实上使用Python做文本处理是更好的选择。 决定最近去掌握一下Python和Lisp。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值